首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Hibernate的EmptyInterceptor中注入JPA的实体管理器

在Hibernate的EmptyInterceptor中注入JPA的实体管理器
EN

Stack Overflow用户
提问于 2013-10-07 05:50:11
回答 2查看 9K关注 0票数 9

我在数据访问层中使用了带有Hibernate的JPA-2.0。

为了进行审计日志记录,我使用Hibernate的EmptyInterceptor,方法是在persistence.xml中配置以下属性:

代码语言:javascript
复制
<property name="hibernate.ejb.interceptor"  
                value="com.mycom.audit.AuditLogInterceptor" /> 

AuditLogInterceptor扩展hibernate的'org.hibernate.EmptyInterceptor'.

代码语言:javascript
复制
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 
    }  
}  

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

代码语言:javascript
复制
<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>

我的AbstractDAO是:

代码语言:javascript
复制
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);       
    }

}

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

知道吗?正确的解决办法应该是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-10 06:04:51

我有一种在“AuditLogInterceptor”中使用JPA实体管理器执行数据库操作的简单方法

我在下面的类中创建了将提供应用程序上下文引用的类:

代码语言:javascript
复制
@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;
        }
    }

创建的数据访问类:

代码语言:javascript
复制
@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);
    }
}

并在'ApplicationContextProvider‘中使用'AuditLogInterceptor’来获得'MyAuditDAO‘的引用,即将JPA实体管理器作为属性在DAO初始化期间注入。现在,在“MyAuditDAO”的帮助下,我可以执行数据库操作。

代码语言:javascript
复制
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);

    }  
} 
票数 9
EN

Stack Overflow用户

发布于 2013-10-07 06:59:57

我认为persistenceManager是在您的抽象类中成功启动的。您可能有一个类AuditLogDAO,它扩展您的AbstractDao。将AuditLogDAO类注入您的拦截器,并调用auditLogDAO.save(entity);和其他方法。

或者编写一个执行DB操作并将util类注入您的拦截器的Util类。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19217872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档