如果没有@Transactional 注释,Hibernate Envers AuditReader 将无法工作

问题描述

我在我的项目中使用 Hibernate Envers,配置简单。

pom.xml

False

EnversConfiguration

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.1</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-envers</artifactId>
    </dependency>
</dependencies>

AuditorAwareImplementation 只是 AuditorAware

的简单实现

我还使用 @Configuration @EnableJpaAuditing public class EnversConfiguration { @Bean AuditorAware<Auditor> auditorProvider() { return new AuditorAwareImplementation(); } } 读取某些实体的更改。 我的方法总是抛出 AuditReader

java.lang.IllegalStateException: Session/EntityManager is closed

如果我使用 java.lang.IllegalStateException: Session/EntityManager is closed at org.hibernate.internal.AbstractSharedSessionContract.checkOpen(AbstractSharedSessionContract.java:375) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.engine.spi.SharedSessionContractImplementor.checkOpen(SharedSessionContractImplementor.java:148) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.internal.AbstractSharedSessionContract.createquery(AbstractSharedSessionContract.java:709) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.internal.AbstractSharedSessionContract.createquery(AbstractSharedSessionContract.java:113) ~[hibernate-core-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.envers.internal.tools.query.QueryBuilder.toQuery(QueryBuilder.java:323) ~[hibernate-envers-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.envers.query.internal.impl.AbstractAuditQuery.buildQuery(AbstractAuditQuery.java:98) ~[hibernate-envers-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.envers.query.internal.impl.AbstractAuditQuery.buildAndExecuteQuery(AbstractAuditQuery.java:104) ~[hibernate-envers-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.envers.query.internal.impl.RevisionsOfEntityQuery.getQueryResults(RevisionsOfEntityQuery.java:173) ~[hibernate-envers-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.envers.query.internal.impl.RevisionsOfEntityQuery.list(RevisionsOfEntityQuery.java:136) ~[hibernate-envers-5.4.25.Final.jar:5.4.25.Final] at org.hibernate.envers.query.internal.impl.AbstractAuditQuery.getResultList(AbstractAuditQuery.java:112) ~[hibernate-envers-5.4.25.Final.jar:5.4.25.Final] 注释运行方法,一切都很好。 在另一个具有非常相似配置和较旧 Spring Boot 版本的项目(没有 @Transactional)中,没有 @Transactional 一切正常。

其实我不知道发生了什么。

有效的代码

@Transactional

不起作用的代码

@Service
@AllArgsConstructor
public class CarHistoryService {
  private final EntityManager entityManager;

  @Transactional
  @SuppressWarnings("unchecked")
  public List<Object[]> getHistory() {
    final AuditReader reader = AuditReaderFactory.get(entityManager);
    return (List<Object[]>) reader.createquery()
      .forRevisionsOfEntityWithChanges(Car.class,true)
      .add(AuditEntity.property("id").eq("5ee7c9dd-a986-4030-8294-3f5dfa2fd6ab"))
      .getResultList();
  }
}

通过简单使用 @Service @AllArgsConstructor public class CarHistoryService { private final EntityManager entityManager; // @Transactional @SuppressWarnings("unchecked") public List<Object[]> getHistory() { final AuditReader reader = AuditReaderFactory.get(entityManager); return (List<Object[]>) reader.createquery() .forRevisionsOfEntityWithChanges(Car.class,true) .add(AuditEntity.property("id").eq("5ee7c9dd-a986-4030-8294-3f5dfa2fd6ab")) .getResultList(); } } 来查找实体的代码

EntityManager

如果我执行和调试上面的代码,它会正确检索带有 @Service @AllArgsConstructor public class CarHistoryService { private final EntityManager entityManager; @SuppressWarnings("unchecked") public List<Object[]> getHistory() { final Object object = entityManager.find(Car.class,UUID.fromString("5ee7c9dd-a986-4030-8294- 3f5dfa2fd6ab")); final AuditReader reader = AuditReaderFactory.get(entityManager); return (List<Object[]>) reader.createquery() .forRevisionsOfEntityWithChanges(Car.class,true) .add(AuditEntity.property("id").eq("5ee7c9dd-a986-4030-8294-3f5dfa2fd6ab")) .getResultList(); } } 的实体,并且我看到 entityManager 有一些属性。但是继续执行该方法 - 它会为下一行抛出相同的异常,我想在其中使用 Envers 检索对象历史记录。

谁能告诉我一些解决方案并解释为什么它会这样工作? 我认为读取数据应该不需要事务,但我可能错了。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...