我有一个Spring(Boot(应用程序,我正在尝试使用Hibernate Envers。
以下bar
函数抛出一个IllegalStateException: EntityManager is closed
,而foo
函数则完美地工作:
@Service
public class FoobarService {
private final EntityManager entityManager;
@Autowired
public FoobarService(EntityManager entityManager) {
this.entityManager = entityManager;
}
public Iterable<Foobar> foo() {
return entityManager.createQuery("select f from Foobar f", Foobar.class).getResultList();
}
public Iterable<Foobar> bar() {
System.out.println(entityManager.isOpen()); // <--- Returns true!
AuditReader auditReader = AuditReaderFactory.get(entityManager);
AuditQueryCreator queryCreator = auditReader.createQuery();
AuditQuery query = queryCreator.forRevisionsOfEntity(Foobar.class, true);
return query.getResultList();
}
}
有人知道当foo
函数清楚地工作(如上所述(时,它为什么声称它是关闭的吗?
PS:为了简洁起见,我省略了maven依赖项和实体映射,因为它们都在工作。
编辑:
有件事真的很奇怪,我想不通。在bar
函数中,我们可以看到:
entityManager.isOpen()
返回true((Session) entityManager.getDelegate()).isOpen()
返回false
AuditReaderFactory.get(EntityManager entityManager)
函数使用第二个,这就是为什么它会在会话未关闭时抱怨会话已关闭。我不太明白为什么delegate
关闭了,所以:
- 为什么工厂使用
entityManager
的委托 - 为什么代理甚至是关闭的
我想我也遇到了同样的问题,当运行@SpringBootTest
时,我需要获得EntityManager
,就像Envers用户指南中显示的那样。
如果你去Hibernate Envers github项目测试,你可以看到他们使用工厂来获得EntityManager
。
我试图在测试中用@Autowire
或@PersistenceContext
注释我的EntityManager
,在这两种情况下,EntityManager
对象都是打开的,但委托是关闭的,就像您的情况一样。它只有在我自动连接工厂时才起作用:
@Autowired
private EntityManagerFactory entityManagerFactory;
然后为我的测试创建了一个entityManager,如下所示:
var entityManager = entityManagerFactory.createEntityManager();