Implement Entity JPA Manager in Hibernate EmptyInterceptor

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

For audit logging, I use the Hibernate EmptyInterceptor by creating the following property in the persistence.xml file:

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

Where AuditLogInterceptor extends org.hibernate.EmptyInterceptor hibernation.

 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 the JPA entity manager at the data access level to perform database operations. JPA configuration is as follows:

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

 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 add a JPA entity manager to the "AuditLogInterceptor" so that I can perform database operations in the "AuditLogInterceptor", like my abstract DAO.

Any idea? What should be the right decision?

+6
source share
2 answers

I have an easy way to perform a database operation using JPA Entity Manager in "AuditLogInterceptor"

I created the class below that will provide a link to the application context:

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

Data access class created:

 @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 the "ApplicationContextProvider" in the "AuditLogInterceptor" to get the "MyAuditDAO" link, which has a JPA object manager as a property that is entered during DAO initialization. Now with the help of "MyAuditDAO" I can perform operations with the database.

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

I am considering a persistenceManager successfully initiated in your abstract class. You can have an AuditLogDAO class that extends your AbstractDao . Add the AuditLogDAO class to your interceptor and call auditLogDAO.save(entity); and other methods.

Or write a Util class that performs database operations and introduces the util class to your hook.

0
source

Source: https://habr.com/ru/post/955385/


All Articles