我在数据访问层中将JPA-2.0与Hibernate一起使用。
为了进行审核日志记录,我通过在persistence.xml中配置以下属性来使用Hibernate的EmptyInterceptor:
<property name="hibernate.ejb.interceptor" value="com.mycom.audit.AuditLogInterceptor" />
凡 AuditLogInterceptor 扩展Hibernate的’ 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 } }
我在数据访问层中使用JPA实体管理器来执行数据库操作。JPA配置如下所示:
<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是:
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”中执行数据库操作。
任何的想法?什么是正确的解决方案?
我有一个简单的方法可以在“ AuditLogInterceptor”中使用JPA实体管理器执行数据库操作
我创建了下面的类,该类将提供应用程序上下文参考:
@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; } }
创建的数据访问类:
@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); } }
并在“ AuditLogInterceptor”中使用“ ApplicationContextProvider”来获取“ MyAuditDAO”的引用,该引用具有JPA实体管理器作为在DAO初始化期间注入的属性。现在,借助“ MyAuditDAO”,我可以执行数据库操作。
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); } }