我的问题很简单。当应用程序在 Tomcat 上加载时,我想从数据库中访问一些数据。要在那个时间点做某事,我使用@PostConstruct(它可以正常工作)。
但是,在该方法中,我与数据库建立了 2 个单独的连接:一个用于带来实体列表,另一个用于将它们添加到公共库中。第二步意味着一些用于解决一些延迟加载关联的幕后查询。这是代码片段:
@Override
@PostConstruct
public void populateLibrary() {
// query for the Book Descriptors - 1st query works!!!
List<BookDescriptor> bookDescriptors= bookDescriptorService.list();
Session session = sessionFactory.openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
// resolving some lazy-loading associations - 2nd query fails!!!
for (BookDescriptor book: bookDescriptors) {
library.addEntry(book);
}
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
正如我在评论中所写,第一个查询有效,而第二个查询失败。失败给出:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:86)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:140)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
at com.freightgate.domain.SecurityFiling_$$_javassist_7.getSfSubmissionType(SecurityFiling_$$_javassist_7.java)
at com.freightgate.dao.SecurityFilingTest.test(SecurityFilingTest.java:73)
这很奇怪,因为我明确地打开和关闭了一个事务。但是,如果我检查第一个查询如何工作的一些细节,似乎在幕后会话绑定到 AbstractLazyInitializer 类。
我通过将 for 循环中的功能抽象为一个单独的服务类来解决我的问题,该服务类使用 @Transactional(readOnly = true) 进行注释。我仍然对为什么我在这里发布的方法失败感到困惑。
如果有人有一些提示,我会很高兴听到他们。