我有一个 Spring(启动)应用程序,我正在尝试在其上使用 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()
返回 falseAuditReaderFactory.get(EntityManager entityManager)
函数使用第二个,这就是为什么它抱怨会话已关闭,而实际上会话并未关闭。我不太明白为什么 delegate
关闭,所以:
entityManager
的委托来代替?我想我也遇到了同样的问题,当运行
@SpringBootTest
时,我需要抓住 EntityManager
,就像 Envers 用户指南中所示的那样。
如果你去Hibernate Envers github-project测试,你可以看到他们使用工厂来获取
EntityManager
。
我尝试在测试中用
EntityManager
或 @Autowire
注释我的 @PersistenceContext
,在这两种情况下 EntityManager
对象都已打开,但委托已关闭,就像您的情况一样。
它仅在我自动连接工厂时才起作用:
@Autowired
private EntityManagerFactory entityManagerFactory;
然后为我的测试创建一个实体管理器,如下所示:
var entityManager = entityManagerFactory.createEntityManager();