How to inject EntityManager in EntityListeners

后端 未结 4 1256
死守一世寂寞
死守一世寂寞 2020-12-06 13:32

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

POJO:

@Entity
@EntityListner(AuditLogging.class)
c         


        
相关标签:
4条回答
  • 2020-12-06 14:09

    Well, the first solution which came into my mind is a little "hack", but should work.

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

    Inside of your code use EntityManager entityManager = emf.getEntityManager()

    Declare your AuditInterceptor as a spring bean (@Component with component-scan or define AuditorInterceptor as a bean)

    0 讨论(0)
  • 2020-12-06 14:16

    Anyways, I got this done by getting entityManager reference from EntityManagerFactory bean which is configured in my jdbc-config.xml. But again this is not what I wanted. I wanted to work around with @PersistenceContext.

      @Autowired
      EntityManagerFactory entityManagerFactory;
    
      private static EntityManager entityManager;
    
      public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
        entityManager=entityManagerFactory.createEntityManager();
        this.entityManagerFactory = entityManagerFactory;
      }
    

    Here are few notes that we need to keep in mind:

    1. We can't inject an EntityManager into an EntityListener (through @PersistenceContext). EntityListener is not managed by any of the containers
    2. @PersistenceContext 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
    0 讨论(0)
  • 2020-12-06 14:19

    I used a ThreadLocal to pass the Spring Application Context which contains EntityManager around. Though I am not sure if it is safe Is it safe to pass in the Spring Application Context into a ThreadLocal associated with a request? but so far it is working for me.

    0 讨论(0)
  • 2020-12-06 14:29

    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.

    0 讨论(0)
提交回复
热议问题