I struggle with the i18n setup in my Spring/Hibernate application. I have now tried to follow this recipe: http://www.theserverside.com/news/1377072/Internationalized-Data-in-Hibernate

And it works as long as I don't use the second level cache. When I do use it the first value is cached and return even if I later change the language. (Through the disassemble and assemble methods). I really hope someone can help me with this one, cause I need to cache the CarType entity, just not the userType-part. (The I18nLocaleHolder operates on an in-memory map)

Thank you!

Here is part of the entity class:

   @Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
   @Immutable
   @Table(name = "CAR_TYPE")
   public class CarType implements Serializable {

      @Id
      private Long id;

      @Type(type = "LocalizedLabelUserType")
      private String description;

        ...

And here is the userType: public class LocalizedLabelUserType implements UserType {

   @Override
   public int[] sqlTypes() {
      return new int[] { Types.INTEGER };
   }

   @Override
   public Class<String> returnedClass() {
      return String.class;
   }

   @Override
   public boolean equals(Object x, Object y) throws HibernateException {
      return x == y;
   }

   @Override
   public int hashCode(Object x) throws HibernateException {
      return x == null ? 0 : x.hashCode();
   }

   @Override
   public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException,
         SQLException {
      Long labelId = (Long) LongType.INSTANCE.nullSafeGet(rs, names, session, owner);
      return I18nLocaleHolder.getDescription(labelId, LocaleContextHolder.getLocale().getLanguage());
   }

   @Override
   public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException,
         SQLException {
      Long code = I18nLocaleHolder.getCode((String) value, LocaleContextHolder.getLocale().getLanguage());
      LongType.INSTANCE.nullSafeSet(st, code, index, session);
   }

   @Override
   public Object deepCopy(Object value) throws HibernateException {
      return value;
   }

   @Override
   public boolean isMutable() {
      return false;
   }

   @Override
   public Serializable disassemble(Object value) throws HibernateException {
      return (Serializable) value;
   }

   @Override
   public Object assemble(Serializable cached, Object owner) throws HibernateException {
      return cached;
   }

   @Override
   public Object replace(Object original, Object target, Object owner) throws HibernateException {
      return original;
   }
}

没有正确的解决方案

其他提示

The annotation @Immutable would need to be removed, otherwise Hibernate will not detect the changed description to class CarType.

Then changing the caching of CarType from READ_ONLY to READ_WRITE would still allow the entity to be cached, but when the entity get's updated on the database, the cache will reflect the new value of description:

@Table(name = "CAR_TYPE")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
 public class CarType implements Serializable {
     ...
 }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top