Hibernate Lazy Loaded对象因会话分离而引发错误

时间:2014-09-24 23:57:22

标签: java hibernate exception lazy-loading

我正在使用一些设置为使用延迟加载的传统hibernate代码。

我试图通过缓存经常使用的值来提高性能,这些值很少变化以避免数据库调用。所以我已经实现了一个HashMap来存储3个值。

我想要发生的事情是在会话关闭后缓存一个延迟加载的实体,并利用该实体中保存的数据。

在我遇到问题的方法中,我查找父对象,然后还检索关联的延迟加载的子对象。这两个都存储在HashMap中。

hashMap = PARENT = ParentType.class
          CHILD = ChildType.class

除了断断续续地我看到CHILD字段突然包含以下错误代码而不是填充的对象时,这大部分工作正常。

hashMap = PARENT = ParentType.class
          CHILD = Exception occurred in target VM: could not initialize     proxy - no Session
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
            at     org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:149)
            at     org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:195)
            at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
            at webpay.cryptolib.bean.KeyTypes_$$_javassist_9.toString(KeyTypes_$$_javassist_9.java)
            at webpay.ksl.DekManager.putCryptoKey(DekManager.java:378)
            at webpay.ksl.DekManager.getDekValue(DekManager.java:225)
            at webpay.ksl.KeyService.encrypt(KeyService.java:116)
            at webpay.ksl.KeyService.encrypt(KeyService.java:146)
            at webpay.crypto.CardCrypt.encryptAndStoreOrNone(CardCrypt.java:116)
            at webpay.engine.transaction.creditcard.CreditcardTransaction.insertTransaction(CreditcardTransaction.java:1066)
            at webpay.engine.transaction.creditcard.CreditcardTransaction.init(CreditcardTransaction.java:261)
            at webpay.engine.TransactionFactory.makeTransaction(TransactionFactory.java:166)
            at webpay.engine.TransactionFactory.makeTransaction(TransactionFactory.java:98)
            at webpay.engine.TransactionFactory.makeTransaction(TransactionFactory.java:85)
            at webpay.engine.TransactionHandler.serviceSocket(TransactionHandler.java:164)
            at matrix.net.SocketDispatcher$SocketThread.run(SocketDispatcher.java:296)
            at java.lang.Thread.run(Thread.java:745)

现在我明白这表明没有会话,这是正确的,因为一旦检索到CHILD,会话就会关闭。然而,这个CHILD现在被缓存,应该分离但仍然可以使用。

用于填充此方法的方法是:

 public ParentType getCurrentContainer() throws InvalidSystemException, NoParentTypeFoundException{
Session session = null;
 if (!isCacheValid()) {
   try {
      session = HibernateUtil.getSessionFactory(getSystemName()).openSession();
      Criteria dekQuery = session.createCriteria(ParentType.class, "pt");
      dekQuery.add(Restrictions.and(Restrictions.eq("pt.status", DekStatus.CURRENT.toString())));
        if (!dekQuery.list().isEmpty()) {
          ParentType pt = (ParentType) dekQuery.list().get(0);
          putCryptoKey(PARENT_CRYPTO_KEY, pt);

          //Extract lazy load keytype
          KeyTypes keyType = pt.getKeyType();
          putCryptoKey(KEY_TYPE_CRYPTO_KEY, keyType);
          logger.debug("Current ParentType found - ParentType Id : {}", pt.getDekId());
          logger.debug("Current KeyType found - KeyType Id : {}", keyType.getKeyTypeId());

       } else {
          logger.info("No Current pt found");
          throw new NoDekFoundException("No pt found with status CURRENT");
       }
} finally {
if (session != null && session.isOpen()) {
session.close();
}
}
}
return (ParentType) cryptoKeys.get(PARENT_CRYPTO_KEY);
}

我的猜测是,当我加载惰性对象时,它不会加载,当我下次引用它时,它会尝试从父级加载(也是缓存)。此时没有会话,因此抛出错误。

有没有办法强制惰性对象存在而不是允许hibernate来决定?

0 个答案:

没有答案