如何在Spring Boot应用程序中访问AuditReaderFactory?

问题描述 投票:0回答:5

我正在使用 spring boot 和 spring data jpa。我也在使用 hibernate envers,我需要访问 AuditReaderFactory 以便我可以编写审核查询。

因为它是 spring boot 和 spring data jpa,所以一切都是自动配置的。所以当我这样做时,

@Autowired
AuditReaderFactory auditReaderFactory;

这不起作用。我收到以下错误。

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.hibernate.envers.AuditReaderFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency

如何在我的存储库类中获得对 AuditReaderFactory 的正确引用?

java spring-boot spring-data-jpa nhibernate-envers
5个回答
12
投票

创建AuditConfiguration.java等配置类:

import org.hibernate.envers.AuditReader;
import org.hibernate.envers.AuditReaderFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManagerFactory;

@Configuration
public class AuditConfiguration {

    private final EntityManagerFactory entityManagerFactory;

    AuditConfiguration(EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

    @Bean
    AuditReader auditReader() {
        return AuditReaderFactory.get(entityManagerFactory.createEntityManager());
    }
}

之后,您可以在组件类中自动装配

AuditReader


6
投票

在我看来,@deniss-s 的答案(投票最高的一个)是不正确的,因为 EntityManager 不得在事务上下文之外重用(请参阅https://stackoverflow.com/a/9375891/554117) ,而解决方案将其用作单例。

AuditReader 的正确检索如下所示:

public class AuditRepository {

    @PersistenceContext
    private EntityManager entityManager;

    private AuditReader getAuditReader() {
        return AuditReaderFactory.get(entityManager);
    }
 
     public Optional<T> getRevision() {
         final AuditReader auditReader = getAuditReader();
         ...
    }
}

编辑:我刚刚意识到@deniss-s更新了他的答案(可能是在阅读我的答案之后),但他的答案仍然不正确:AuditReader仍然作为单例创建,而每次都必须创建一个新实例。


5
投票

按照上面的答案和链接的问题,我发现这是可行的。 (如果可以以某种方式直接将其变成阅读器的自动接线,那就太好了)

@Autowired
private EntityManagerFactory factory;

public void stuff() {
    AuditReader audit = AuditReaderFactory.get(factory.createEntityManager());
}

2
投票

AuditReaderFactory 只有两个静态方法。您可以自动装配 SessionFactory 对象或 EntityMananger 吗?看起来两者都会给你你想要的,那就是访问 AuditReader。

AuditReaderFactory.get(sessionFactory.getCurrentSession())

编辑这个帖子有一些细节或如果需要的话可以连接SessionFactory


1
投票

我无法创建评论,所以我将复制 Giulio Pulina 的答案。他的回答确实比那些点赞多的人更正确。其他答案也有效,但前提是存在与数据库的连接。如果与数据库的连接丢失(重新启动带有数据库的容器),AuditReader 将无法操作。因此,在每个请求之前创建 AuditReader 时的当前响应是最可取的。

AuditReader 的正确检索如下所示:

public class AuditRepository {

    @PersistenceContext
    private EntityManager entityManager;

    private AuditReader getAuditReader() {
        return AuditReaderFactory.get(entityManager);
    }
 
     public Optional<T> getRevision() {
         final AuditReader auditReader = getAuditReader();
         ...
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.