Folks- I am trying to set up hibernate.ejb.interceptor but for some reason it never gets to 'intercept' any update or inse开发者_如何学Crt event. The application seems to work fine, updating and inserting entities but no interception.
I cannot find what is wrong with my setup, please help:
persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="myPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<non-jta-data-source>jdbc/myDS</non-jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.ejb.interceptor"
value="my.AuditLogInterceptor" />
</properties>
</persistence-unit>
</persistence>
Application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:annotation-driven />
<context:component-scan base-package="my.package" />
<tx:annotation-driven />
<context:annotation-config
transaction-manager="transactionManager" proxy-target-class="false" />
<jee:jndi-lookup id="myDS" jndi-name="jdbc/myDS"
resource-ref="true" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass">
<value>
org.springframework.web.servlet.view.tiles2.TilesView
</value>
</property>
</bean>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles/tiles.xml</value>
</list>
</property>
</bean>
<bean id="myEMF"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="myDS" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="myEMF" />
<property name="dataSource" ref="myDS" />
</bean>
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
</bean>
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean id="auditLog" class="my.AuditLog" />
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
</beans>
Interceptor (From manning book):
public class AuditLogInterceptor extends EmptyInterceptor {
/**
*
*/
private static final long serialVersionUID = -634733855120326803L;
/**
*
*/
private XLogger logger = XLoggerFactory
.getXLogger(AuditLogInterceptor.class.getName());
private Session session;
private Long userId;
private Set<Auditable> inserts = new HashSet<Auditable>();
private Set<Auditable> updates = new HashSet<Auditable>();
public AuditLogInterceptor() {}
public void setSession(Session session) {
this.session = session;
}
public void setUserId(Long userId) {
this.userId = userId;
}
@Override
public boolean onSave(Object entity, Serializable id, Object[] state,
String[] propertyNames, Type[] types) throws CallbackException {
logger.entry(entity, id, state, propertyNames);
if (entity instanceof Auditable)
inserts.add((Auditable) entity);
logger.exit();
return false;
}
@Override
public boolean onFlushDirty(Object entity, Serializable id,
Object[] currentState, Object[] previousState,
String[] propertyNames, Type[] types) throws CallbackException {
logger.entry(entity, id, currentState, previousState);
if (entity instanceof Auditable)
updates.add((Auditable) entity);
logger.exit();
return false;
}
@Override
public void postFlush(Iterator iterator) throws CallbackException {
logger.entry(iterator);
try {
for (Auditable entity : inserts) {
AuditLog.logEvent("create", entity, "userId");
}
for (Auditable entity : inserts) {
new AuditLog().logEvent("update", entity, "userId");
}
} finally {
inserts.clear();
updates.clear();
}
logger.exit();
}
}
The Spring bean (found it on the web):
public class AuditLog {
static protected AuditLog theAuditLog = null;
@PersistenceContext(unitName = "myPU")
protected EntityManager itsEntityManager;
public AuditLog() {
theAuditLog = this;
}
/**
*
* @return the entity manager
*/
protected EntityManager getEntityManager() {
return this.itsEntityManager;
}
/**
*
* @return Hibernate Session
*/
protected Session getHibernateSession() {
return (Session) getEntityManager().getDelegate();
}
public static void logEvent(String action, Auditable entity, String userId) {
/*
* TODO get rid of this .connection() - deprecated - call !
*/
Session tempSession = theAuditLog.getHibernateSession()
.getSessionFactory()
.openSession(theAuditLog.getHibernateSession().connection());
try {
AuditLogRecord alr = new AuditLogRecord();
alr.entityId = entity.getId();
alr.entityClass = entity.getClass();
alr.message = "Something changed";
alr.created = new Date();
tempSession.save(alr);
tempSession.flush();
} catch (Exception ex) {
throw new CallbackException(ex);
} finally {
try {
tempSession.close();
} catch (HibernateException ex) {
throw new CallbackException(ex);
}
}
}
}
精彩评论