[SPRING] EntityListeners에 EntityManager를 삽입하는 방법
SPRINGEntityListeners에 EntityManager를 삽입하는 방법
EntityListener 클래스에 EntityManager를 삽입하여 CRUD 작업을 수행 할 수 있도록해야합니다.
POJO :
@Entity
@EntityListner(AuditLogging.class)
class User
{
//Getter / setter of properties
}
감사 로깅 (Listener 클래스)
public class AuditInterceptor
{
@PersistenceContext
EntityManager entityManager;
public void setEntityManager(EntityManager entityManager)
{
this.entityManager = entityManager;
}
@PrePersist
public void prePersist(Object obj)
{
// 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
}
}
JDBC-CONFIg.xml
<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 작업을 수행 할 수 있습니까?
해결법
-
==============================
1.EntityListeners를 사용하여 엔티티에 대한 히스토리 레코드를 작성하려고하는 것과 비슷한 문제점에 직면했습니다.
EntityListeners를 사용하여 엔티티에 대한 히스토리 레코드를 작성하려고하는 것과 비슷한 문제점에 직면했습니다.
이 문제를 해결하기 위해 Bean을 가져 오기위한 정적 메소드 BeanUtil을 생성하고이 util 클래스를 사용하여 Bean을 EntityListener 클래스 내부에서 가져 왔습니다.
@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.getBean ()을 호출하여 모든 유형의 Bean을 가져올 수 있습니다.
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)); } }
우리는이 BeanUtil 클래스를 사용하여 어디서나 스프링 관리 빈을 얻을 수 있습니다. 더 많은 정보를 얻으려면 JPA 감사 : EntityListeners를 사용하여 자동으로 감사 로그 유지하기.
-
==============================
2.어쨌든이 작업은 jdbc-config.xml에 구성된 EntityManagerFactory bean에서 entityManager 참조를 가져와 수행합니다. 그러나 이것은 내가 원한 것이 아닙니다. @PersistenceContext로 해결하고 싶었습니다.
어쨌든이 작업은 jdbc-config.xml에 구성된 EntityManagerFactory bean에서 entityManager 참조를 가져와 수행합니다. 그러나 이것은 내가 원한 것이 아닙니다. @PersistenceContext로 해결하고 싶었습니다.
@Autowired EntityManagerFactory entityManagerFactory; private static EntityManager entityManager; public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) { entityManager=entityManagerFactory.createEntityManager(); this.entityManagerFactory = entityManagerFactory; }
다음은 유의해야 할 몇 가지 메모입니다.
1. We can't inject an EntityManager into an EntityListener(through @presistenceContext). EntityListener is not managed by any of the containers 2. @presistenceContext class cannot be static. So we cant attain the instance while class loading. 3. EntityListeners are instantiated by JPA, so Spring does not have an opportunity to inject EntityManager
-
==============================
3.글쎄, 내 마음에 들어온 첫 번째 해결책은 약간 "해킹"이지만 작동해야한다.
글쎄, 내 마음에 들어온 첫 번째 해결책은 약간 "해킹"이지만 작동해야한다.
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 ()
감사 인터셉터를 스프링 빈으로 선언하십시오. (@Component with component-scan 또는 감사 자 인터셉터를 bean으로 정의하십시오.)
from https://stackoverflow.com/questions/22171221/how-to-inject-entitymanager-in-entitylisteners by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring에서 index.html에 대한 모든 경로 캐치 (0) | 2019.01.31 |
---|---|
[SPRING] anglejs 앱에서 보낸 iOS에 PDF (Blob)를 표시하는 방법 (0) | 2019.01.31 |
[SPRING] JsonDeserializer에서의 Autowiring : SpringBeanAutowiringSupport 대 HandlerInstantiator (0) | 2019.01.31 |
[SPRING] Spring-Boot : tomcat 커넥터를 추가하여 컨트롤러에 바인딩하는 방법 (0) | 2019.01.31 |
[SPRING] Hibernate JPA를 사용한 작업 단위 처리 문제 (0) | 2019.01.31 |