【问题标题】:Is it possible to turn off 2nd level caching for UserType?是否可以关闭 UserType 的二级缓存?
【发布时间】:2014-02-07 20:18:21
【问题描述】:

我在 Spring/Hibernate 应用程序中设置 i18n 时遇到了困难。我现在尝试遵循这个食谱:http://www.theserverside.com/news/1377072/Internationalized-Data-in-Hibernate

只要我不使用二级缓存,它就可以工作。当我使用它时,第一个值被缓存并返回,即使我后来更改了语言。 (通过拆卸和组装方法)。我真的希望有人能帮我解决这个问题,因为我需要缓存 CarType 实体,而不是 userType 部分。 (I18nLocaleHolder 在内存映射上运行)

谢谢!

这里是实体类的一部分:

   @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;

        ...

这里是用户类型: 公共类 LocalizedLabelUserType 实现 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;
   }
}

【问题讨论】:

    标签: hibernate caching localization internationalization usertype


    【解决方案1】:

    注释@Immutable 需要被移除,否则Hibernate 将不会检测到类CarType 的更改描述。

    然后将CarType 的缓存从READ_ONLY 更改为READ_WRITE 仍然允许缓存实体,但是当实体在数据库上更新时,缓存将反映description 的新值:

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

    【讨论】:

    • 您好,感谢您回答我。我已经尝试过您的解决方案,但不幸的是它不起作用。但是我设法让它工作,但解决方案有点hacky,所以我不会将它作为答案发布。总而言之,我从 nullSafeGet 返回描述,并在反汇编中获取并返回代码。然后所有以下对 assemble 的调用都将包含代码,我可以从语言缓存中获取正确的文本。此外,我必须在使用 Cachable 注释的地方修改 Query 注释。 (需要输入语言,所以这绝对是hacky)
    猜你喜欢
    • 2012-06-20
    • 2012-02-01
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    • 1970-01-01
    • 2011-06-24
    • 2011-08-31
    相关资源
    最近更新 更多