Java 如何在EntityListeners中注入EntityManager
我需要在EntityListener类中注入EntityManager,以便对其执行CRUD操作 POJO: AuditLogging(Listner类) } JDBC-CONFIg.xmlJava 如何在EntityListeners中注入EntityManager,java,spring,hibernate,spring-mvc,spring-data-jpa,Java,Spring,Hibernate,Spring Mvc,Spring Data Jpa,我需要在EntityListener类中注入EntityManager,以便对其执行CRUD操作 POJO: AuditLogging(Listner类) } JDBC-CONFIg.xml <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataS
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
<property name="packagesToScan" value="com.XXXXX.entity" />
<property name="jpaProperties">
</bean>
<!-- Datasource -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driver.classname}" />
<property name="jdbcUrl" value="${jdbc.url}" />
</bean>
<!-- transaction Manager -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
EntityListener不由任何容器管理。EntityListener由JPA实例化,因此Spring没有机会注入EntityManager。
我的问题是,我们如何在EntityListener类中注入EntityManager,以便我可以对其执行CRUD操作?好吧,我想到的第一个解决方案是有点“黑客”,但应该可以工作
public class AuditInterceptor {
static setEntityManager emf;
@Autowired
public void setEntityManagerFactory(EntityManager emf) {
AuditInterceptor.emf = emf;
}
@PrePersist
public void prePersist(Object obj) {
EntityManager entityManager = emf.getEntityManager();
// Here I want to use ENTITY manager object so that I can perform CRUD operation
// with prePersist coming object.
entityManager.unwrap(Session.class).save(obj);
// But I am getting NULL POINTER EXCEPTION for entity manager object
}
}
在代码内部使用EntityManager EntityManager=emf.getEntityManager()
将您的
auditioninterceptor
声明为Springbean(@Component
使用组件扫描或将auditioninterceptor
定义为bean)无论如何,我是通过从EntityManagerFactory
bean获取entityManager引用来实现的,该bean是在我的jdbc config.xml
中配置的。但这又不是我想要的。我想处理@PersistenceContext
@Autowired
EntityManagerFactory entityManagerFactory;
private static EntityManager entityManager;
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
entityManager=entityManagerFactory.createEntityManager();
this.entityManagerFactory = entityManagerFactory;
}
以下是我们需要记住的几个注意事项:
EntityManager
注入EntityListener
(通过
@PersistenceContext
)<代码>EntityListener不由任何
容器@PersistenceContext
类不能是静态的。所以我们不能
在类加载时获取实例李>
EntityManager
我曾经遇到过一个类似的问题,我试图使用EntityListeners为实体创建历史记录 为了解决这个问题,我使用一个静态方法创建了实用类
BeanUtil
,以获取bean,并使用这个util类在我的Entitylistener类中获取bean
@Service
public class BeanUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
}
我们可以使用这个
BeanUtil
类从任何地方获取任何spring管理的bean,您可以阅读我的文章了解更多信息。我使用ThreadLocal来传递包含EntityManager的spring应用程序上下文。虽然我不确定它是否安全,但到目前为止它对我有效。@PersistenceContext不能成为静态的。我的示例不再使用@PersistenceContext。谷歌也让我想到了这一点
@Autowired
EntityManagerFactory entityManagerFactory;
private static EntityManager entityManager;
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
entityManager=entityManagerFactory.createEntityManager();
this.entityManagerFactory = entityManagerFactory;
}
@Service
public class BeanUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
}
public class FileEntityListener {
@PrePersist
public void prePersist(File target) {
perform(target, INSERTED);
}
@Transactional(MANDATORY)
private void perform(File target, Action action) {
EntityManager entityManager = BeanUtil.getBean(EntityManager.class);
entityManager.persist(new FileHistory(target, action));
}
}