开发者

NewbieQuestion: Can I somehow pass arguments to Spring+Hibernate from a DAO?

In the code I am currently working on I came across a piece code where the fields of MyClass are supposed to be set according to the language in use. But in reality the language code has been hardcoded into the Hibernate UserType class. I somehow need to tell Hibernate what language in use, but how can I accomplish this?

Below are versions of the code modified to be as problem specific as possible.

class I18nStringUserType

/**
 * Gets a localized string based on the key and current language
 * TODO: Remove hardcoded language value
 * 
 * @see org.hibernate.usertype.
 *   UserType#nullSafeGet(ResultSet, String[], Object)
**/
public Object nullSafeGet(ResultSet rs, String[] names, 
       Object owner) throws Exception 
{
    String key = (String) Hibernate.STRING.nullSafeGet(rs, names);
    String language = "US"; // design-smell. FIX!
    return I18nStringFactory.getI18nString(key, language);
}

The DAO that supplies MyClass uses Spring's HibernateDaoSupport class. Can I somehow modify this to pass arguments to Hibernate that tells it to use some specific language?

public class HibernateMyClassDAO extends HibernateDaoSupport{
    public MyClass get(Long id) {
        MyClass fund =  (MyClass) getHibernateTemplate().get(MyClass.class, id);
    }
}

This is an edited version of the Hibernate mapping. Do not know if it is needed.

<hibernate-mapping>
    <class name="MyClass" table="MYCLASS" >

        <id name="id" type="java.lang.Long" column="ID" />
        <property  name="description" column="I18DESCRIPTION" 
            insert="false" update="false"
            type="18nStringUserType"/>
    </class>
    ...
</hibernate-mapping>

I have just been exposed to Spring & Hibernate, so fare gentle on me ;) I am unsure if the question adequately reflects the problem at 开发者_运维知识库hand, so feel free to suggest a more telling title.


Personally I don't think it's a good idea to apply i18n inside UserType (how would you implement nullSafeSet?), it would be better to resolve i18n code at higher levels.

But if it's actually required to do so, you need to introduce some kind of "context" accessible via static fields. For example, using thread-local static field, something like this:

public class ThreadI18nContext {
    private static final ThreadLocal<String> language = new ThreadLocal<String>() {
        protected String initialValue() { return "US"; }
    }

    public static String getLanguage() {
        return language.get();
    }

    public static void setLanguage(String l) {
        language.set(l);
    }
}

This solution is ugly, but it's a natural result of implementing i18n at this level.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜