Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject EntityManager in EntityListeners

I need to inject EntityManager in EntityListener class so that I can perform CRUD operation on it.

POJO:

@Entity
@EntityListner(AuditLogging.class)
class User
{
      //Getter / setter of properties
}

AuditLogging (Listner class)

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 is not managed by any of the container.EntityListeners are instanciated by JPA, so Spring does not have an opportunity to inject EntityManager. My question is, how we can inject inject EntityManager in EntityListener class so that I can perform CRUD operation on it ???

like image 374
user3029929 Avatar asked Mar 04 '14 11:03

user3029929


1 Answers

I have faced a similar problem where I was trying to create history records for an entity using EntityListeners.

In order to resolve this problem, I have created utility class BeanUtil with a static method to get the bean and used this util class to get bean inside my Entitylistener class

@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);
    }

}

Now we can call BeanUtil.getBean() to get the bean of any type

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));
    }

}

We can use this BeanUtil class to get any spring managed bean from anywhere, To know more you can read my article JPA Auditing: Persisting Audit Logs Automatically using EntityListeners.

like image 57
Naresh Joshi Avatar answered Sep 30 '22 17:09

Naresh Joshi