我正在使用一些设置为使用延迟加载的传统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来决定?