在Hibernate的EmptyInterceptor中注入JPA的实体管理器 [英] Injecting JPA's Entity Manager in Hibernate's EmptyInterceptor

查看:253
本文介绍了在Hibernate的EmptyInterceptor中注入JPA的实体管理器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



对于审计日志记录的目的,我通过在persistence.xml中配置下面的属性来使用Hibernate的EmptyInterceptor :

 < property name =hibernate.ejb.interceptor
value =com.mycom.audit。 AuditLogInterceptor/>

其中 AuditLogInterceptor 扩展了hibernate的 org.hibernate.EmptyInterceptor '。

  public class AuditLogInterceptor extends EmptyInterceptor {
$ b $ private long userId;
$ b $ public AuditLogInterceptor(){}
$ b $ @Override
public boolean onSave(Object entity,Serializable id,Object [] state,
String [] propertyNames,Type []类型)抛出CallbackException {
//需要使用JPA实体管理器执行数据库操作
return false;

$ b @Override
public boolean onFlushDirty(Object entity,Serializable id,
Object [] currentState,Object [] previousState,
String [] propertyNames,Type []类型){
//其他代码
return false;

$ b @Override
public void postFlush(Iterator iterator)throws CallbackException {
System.out.println(我在postFlush);
//此处的其他代码
}
}

我是在数据访问层使用JPA实体管理器来执行数据库操作。 JPA配置如下:

 < bean id =entityManagerFactory
class =org.springframework.orm .jpa.LocalContainerEntityManagerFactoryBean
p:persistenceUnitName =PersistenceUnit
p:persistenceXmlLocation =classpath *:persistence.xml
p:dataSource-ref =dataSourcep:jpaVendorAdapter-ref =jpaAdapter >
< property name =loadTimeWeaver>
< bean
class =org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver/>
< / property>
< / bean>

我的AbstractDAO是:

  public class AbstractDao< T,ID extends Serializable> {

private final transient Class< T>对PersistentClass;

保护瞬态EntityManager entityManager;

@SuppressWarnings(unchecked)
public AbstractDao(){

this.persistentClass =(Class< T>)((ParameterizedType)getClass()。 getGenericSuperclass())getActualTypeArguments()[0];


@PersistenceContext
public final void setEntityManager(final EntityManager entityMgrToSet){

this.entityManager = entityMgrToSet;
}

public final Class< T> getPersistentClass(){

返回persistentClass;


public final void persist(final T entity){

entityManager.persist(entity);
}

}

我想在'AuditLogInterceptor'中注入JPA实体管理器,以便我可以像'抽象DAO'那样在'AuditLogInterceptor'中执行数据库操作。

任何想法?什么应该是正确的解决方案?

解决方案

我有一个简单的方法来执行数据库操作使用JPA实体管理器'AuditLogInterceptor'



我在下面的类中创建了一个应用程序上下文引用:

  @Component(applicationContextProvider)
public class ApplicationContextProvider实现ApplicationContextAware {
private static ApplicationContext context;

public static ApplicationContext getApplicationContext(){
return context;
}

@Override
public void setApplicationContext(ApplicationContext ctx){
context = ctx;


$ / code $ / pre

创建数据访问类:

  @Repository(myAuditDAO)
public class myAuditDAO< T,ID extends Serializable> {

private final transient Class< T>对PersistentClass;

保护瞬态EntityManager entityManager;

@SuppressWarnings(unchecked)
public MyDAO(){

this.persistentClass =(Class< T>)((ParameterizedType)getClass()。 getGenericSuperclass())getActualTypeArguments()[0];


@PersistenceContext
public final void setEntityManager(final EntityManager entityMgrToSet){

this.entityManager = entityMgrToSet;
}

public final Class< T> getPersistentClass(){

返回persistentClass;


public final T findById(final ID theId){

return entityManager.find(persistentClass,theId);


public final void persist(final T entity){

entityManager.persist(entity);
}

public final void merge(final T entity){

entityManager.merge(entity);


$ / code $ / pre

并使用'AuditLogInterceptor'中的'ApplicationContextProvider'作为在DAO初始化期间被注入的属性的具有JPA实体管理器的'MyAuditDAO'的引用。现在在'MyAuditDAO'的帮助下,我可以执行数据库操作。

  public class AuditLogInterceptor extends EmptyInterceptor {

@Override
public void postFlush(Iterator iterator)throws CallbackException {

//这里我们可以得到MyAuditDao引用并且可以执行持久化/合并选项
MyAuditDao myAuditDao =( MyAuditDao)ApplicationContextProvider.getApplicationContext()。getBean(myAuditDao);

// myAuditDao.persist(myEntity);

}
}


I am using JPA-2.0 with Hibernate in my data access layer.

For audit logging purposes, I am using Hibernate's EmptyInterceptor by configuring below property in persistence.xml:

<property name="hibernate.ejb.interceptor"  
                value="com.mycom.audit.AuditLogInterceptor" /> 

Where AuditLogInterceptor extends hibernate's 'org.hibernate.EmptyInterceptor'.

public class AuditLogInterceptor extends EmptyInterceptor {  

    private Long userId;  

    public AuditLogInterceptor() {}  

    @Override  
    public boolean onSave(Object entity, Serializable id, Object[] state,  
            String[] propertyNames, Type[] types) throws CallbackException {  
        // Need to perform database operations using JPA entity manager
        return false;  
    }  

   @Override
    public boolean onFlushDirty(Object entity, Serializable id,
            Object[] currentState, Object[] previousState,
            String[] propertyNames, Type[] types) {
        // other code here        
        return false;
    }

    @Override  
    public void postFlush(Iterator iterator) throws CallbackException {  
        System.out.println("I am on postFlush");
        // other code here 
    }  
}  

I am using JPA entity manager in data access layer to perform database operations. JPA configuration is like below:

<bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        p:persistenceUnitName="PersistenceUnit"
        p:persistenceXmlLocation="classpath*:persistence.xml"
        p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter">
        <property name="loadTimeWeaver">
            <bean
                class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property>
    </bean>

My AbstractDAO is :

public class AbstractDao<T, ID extends Serializable> {

    private final transient Class<T> persistentClass;

    protected transient EntityManager entityManager;

    @SuppressWarnings("unchecked")
    public AbstractDao() {

        this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    @PersistenceContext
    public final void setEntityManager(final EntityManager entityMgrToSet) {

        this.entityManager = entityMgrToSet;
    }

    public final Class<T> getPersistentClass() {

        return persistentClass;
    }

    public final void persist(final T entity) {

         entityManager.persist(entity);       
    }

}

I would like to inject JPA entity manager in 'AuditLogInterceptor' so that I can perform database operations in 'AuditLogInterceptor' like my abstract DAO.

Any Idea? What should be the proper solution?

解决方案

I have got a simple way to perform database operation using JPA Entity Manager in 'AuditLogInterceptor'

I have created below class that will give the application context reference:

@Component("applicationContextProvider")
    public class ApplicationContextProvider implements ApplicationContextAware {
        private static ApplicationContext context;

        public static ApplicationContext getApplicationContext() {
            return context;
        }

        @Override
        public void setApplicationContext(ApplicationContext ctx) {
            context = ctx;
        }
    }

Created Data access class:

@Repository("myAuditDAO")
public class myAuditDAO<T, ID extends Serializable> {

    private final transient Class<T> persistentClass;

    protected transient EntityManager entityManager;

    @SuppressWarnings("unchecked")
    public MyDAO() {

        this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    @PersistenceContext
    public final void setEntityManager(final EntityManager entityMgrToSet) {

        this.entityManager = entityMgrToSet;
    }

    public final Class<T> getPersistentClass() {

        return persistentClass;
    }

    public final T findById(final ID theId) {

        return entityManager.find(persistentClass, theId);
    }

    public final void persist(final T entity) {

        entityManager.persist(entity);
    }

    public final void merge(final T entity) {

        entityManager.merge(entity);
    }
}

And used 'ApplicationContextProvider' in 'AuditLogInterceptor' to get the reference of 'MyAuditDAO' that is having JPA entity manager as a property which is injected during DAO initialization. Now with the help of 'MyAuditDAO' I can perform database operations.

public class AuditLogInterceptor extends EmptyInterceptor {  

    @Override  
    public void postFlush(Iterator iterator) throws CallbackException {  

      // Here we can get the MyAuditDao reference and can perform persiste/merge options
       MyAuditDao myAuditDao = (MyAuditDao ) ApplicationContextProvider.getApplicationContext().getBean("myAuditDao");

      //  myAuditDao.persist(myEntity);

    }  
} 

这篇关于在Hibernate的EmptyInterceptor中注入JPA的实体管理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆