Hi,
I recently created an Interceptor to replace the Lifecycle implementation.
My application has been running very well so far, for more than 2years now.
When I monitor the Interceptor class behavior on a local level everthing seems to fine. But functional testers are reporting very odd errors, all producing NPE, so far. Seems to be side effects caused by the Interceptor.
A pretty obvious one I identified is:
A object has a Map of B objects: when Hibernate has to retrieve a Map of B objects from a A, it is empty.
This occurs only when adding the Interceptor to the config. When removing it, everything is back to normal.
Another one occurs in the list() method of the SessionImpl.
the errors occurs in the AbstractFlushingEventListener's flushEntities(FlushEvent) method.
I have more than 150 entities to flush so can't identifies where it fails exactly.
But once again this doesn't happen when the Interceptor is not enabled.
And weirdly enough, the stacktrace doesn't mention anything below my code:
Code:
19:35:47,468 ERROR ActionExceptionHandler:64 - 127.0.0.1: org.xx.operationcomptable.service.OperationComptableException: java.lang.NullPointerException: java.lang.NullPointerException
at org.xx.operationcomptable.service.OperationComptableEngagement.genererOCEngagementDfModification(OperationComptableEngagement.java:594)
at org.xx.operationcomptable.service.OperationComptableServiceImpl.genererOCEngagementDfModification(OperationComptableServiceImpl.java:405)
at org.xx.common.service.ServiceMediator.genererOCEngagementDfModification(ServiceMediator.java:195)
at org.xx.dossierformation.service.DossierFormationServiceImpl.updateDossierFormation(DossierFormationServiceImpl.java:176)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:292)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:155)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:122)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:174)
at $Proxy4.updateDossierFormation(Unknown Source)
at org.xx.dossierformation.action.ModificationDossierFormationIndividuelAction.engage(ModificationDossierFormationIndividuelAction.java:1405)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:274)
at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:194)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:174)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.xx.security.SecurityFilter.doFilter(SecurityFilter.java:125)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:534)
I'm facing these very weird behavior with no real hope to understand what is going on. So help is more than welcome!
I've read some people had strange behavior as well with Interceptor.
Is it better to use the Event framework?
Interceptor's code:
Code:
package org.xx.common.persistence;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.*;
import org.hibernate.type.StringType;
import org.hibernate.type.Type;
import org.xx.common.model.collecte.DateComptable;
import java.io.Serializable;
import java.util.Date;
import java.util.Iterator;
/**
* @version Aug 29, 2005 - 7:22:53 PM
*/
public final class BoInterceptor implements Interceptor, Serializable {
private Date dateMutualisation;
private int updates;
private int creates;
private int deletes;
/**
* The <code>Log</code> instance for this package.
*/
private Log log = LogFactory.getLog(this.getClass());
/**
* @param sessionFactory The sessionFactory to set.
*/
public void setSessionFactory(SessionFactory sessionFactory) {
this.dateMutualisation = new Date(2006,10,10);
}
/**
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#onDelete(java.lang.Object,
* java.io.Serializable, java.lang.Object[], java.lang.String[],
* org.hibernate.type.Type[])
*/
public void onDelete(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
this.deletes++;
}
/**
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#onFlushDirty(java.lang.Object,
* java.io.Serializable, java.lang.Object[], java.lang.Object[],
* java.lang.String[], org.hibernate.type.Type[])
*/
public boolean onFlushDirty(Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types) {
this.updates++;
boolean isModified = false;
for (int i = 0; i < types.length; i++)
if ((types[i] instanceof StringType) && "".equals(currentState[i])) {
currentState[i] = null;
isModified = true;
log.debug("Empty attribute '" + propertyNames[i] + "', replaced by 'null'");
} else if (propertyNames[i].endsWith("DateMaj") && (new Date()).after(this.dateMutualisation)) {
currentState[i] = this.dateMutualisation;
isModified = true;
log.debug("Updated Objet with Mutualisation Date :" + entity.getClass().getName() + " Date Mutualisation : " + this.dateMutualisation);
}
return isModified;
}
/**
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#onLoad(java.lang.Object,
* java.io.Serializable, java.lang.Object[], java.lang.String[],
* org.hibernate.type.Type[])
*/
public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
log.trace("CALLED load(" + entity + "," + id + ")");
return false;
}
/**
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#onSave(java.lang.Object,
* java.io.Serializable, java.lang.Object[], java.lang.String[],
* org.hibernate.type.Type[])
*/
public boolean onSave(Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
boolean isModified = false;
this.creates++;
for (int i = 0; i < types.length; i++)
if ((types[i] instanceof StringType) && "".equals(state[i])) {
state[i] = null;
isModified = true;
log.debug("Empty attribute '" + propertyNames[i] + "', replaced by 'null'");
} else if ((propertyNames[i].endsWith("DateCreation") || propertyNames[i].endsWith("DateMaj")) && (new Date()).after(this.dateMutualisation)) {
state[i] = this.dateMutualisation;
isModified = true;
log.debug("Created Objet with Mutualisation Date :" + entity.getClass().getName() + " Date Mutualisation : " + this.dateMutualisation);
}
return isModified;
}
/*
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#postFlush(java.util.Iterator)
*/
public void postFlush(Iterator entities) {
log.debug("Creations: " + this.creates + ", Updates: " + this.updates + ", Deletes: " + this.deletes);
this.creates = 0;
this.updates = 0;
this.deletes = 0;
}
/**
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#preFlush(java.util.Iterator)
*/
public void preFlush(Iterator entities) {
log.trace("CALLED preFlush()");
}
/**
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#isTransient(java.lang.Object)
*/
public Boolean isTransient(Object entity) {
log.trace("CALLED isTransient(" + entity + ")");
return null;
}
/**
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#instantiate(java.lang.String,
* org.hibernate.EntityMode, java.io.Serializable)
*/
public Object instantiate(String entityName, EntityMode entityMode, Serializable id) {
log.trace("CALLED instantiate(" + entityName + "," + entityMode + "," + id + ")");
return null;
}
/**
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#findDirty(java.lang.Object,
* java.io.Serializable, java.lang.Object[], java.lang.Object[],
* java.lang.String[], org.hibernate.type.Type[])
*/
public int[] findDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
log.trace("CALLED findDirty(" + entity + "," + id + "," + currentState + "," + previousState + "," + propertyNames + ")");
return null;
}
/**
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#getEntityName(java.lang.Object)
*/
public String getEntityName(Object object) {
log.trace("CALLED getEntityName(" + object + ")");
return null;
}
/**
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#getEntity(java.lang.String,
* java.io.Serializable)
*/
public Object getEntity(String entityName, Serializable id) {
log.trace("CALLED getEntity(" + entityName + "," + id + ")");
return null;
}
/**
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#afterTransactionBegin(org.hibernate.Transaction)
*/
public void afterTransactionBegin(Transaction tx) {
}
/**
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#afterTransactionCompletion(org.hibernate.Transaction)
*/
public void afterTransactionCompletion(Transaction tx) {
}
/**
* (non-Javadoc)
*
* @see org.hibernate.Interceptor#beforeTransactionCompletion(org.hibernate.Transaction)
*/
public void beforeTransactionCompletion(Transaction tx) {
}
}
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp
Hibernate version:3.0.5
cheers,