I am using spring boot and spring data jpa. I am also using hibernate envers and I need access to AuditReaderFactory so that I can write Audit Queries.
Since, its a spring boot and spring data jpa, everything is auto configured. So when I do this,
@Autowired
AuditReaderFactory auditReaderFactory;
It doesn't work. I get the following error.
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
How do I get a proper reference to AuditReaderFactory in my repository classes?
Following up on above answer, and linked question, I found this to work. (Would be nice if this can be turned into an autowire of the reader directly somehow)
@Autowired
private EntityManagerFactory factory;
public void stuff() {
AuditReader audit = AuditReaderFactory.get(factory.createEntityManager());
}
AuditReaderFactory only has two static methods. Can you autowire a SessionFactory object or your EntityMananger? Looks like either would give you what you want, which is access to an AuditReader.
AuditReaderFactory.get(sessionFactory.getCurrentSession())
EDIT this post has some detail or wiring SessionFactory if needed
Create configuration class such as 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());
}
}
After that you can you autowire AuditReader
in your component classes.
In my opinion, @deniss-s answer (top-voted one) is not correct because EntityManager must not be reused outside of the context of a transaction (see https://stackoverflow.com/a/9375891/554117 ), while the solution makes use of it as a singleton.
A correct retrieval of AuditReader looks like this:
public class AuditRepository {
@PersistenceContext
private EntityManager entityManager;
private AuditReader getAuditReader() {
return AuditReaderFactory.get(entityManager);
}
public Optional<T> getRevision() {
final AuditReader auditReader = getAuditReader();
...
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.