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.
精彩评论