]
Gail Badner commented on HHH-961:
---------------------------------
Please attach a runnable test case (Java + mapping) to reproduce this issue.
ConcurrentModificationException in Session.getEntityName()
----------------------------------------------------------
Key: HHH-961
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-961
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.0.5
Environment: Hibernate 3.0.5 running on JBoss 4.0.2 with JBoss' Hibernate
integration, Database is Oracle 10g R1
Reporter: Mathias Meyer
I already posted this issue in the Hibernate forums and then tried, on Gavin's
advice, to come up with a test case to reproduce the problem. I tried to reproduce this
issue in a normal testcase, but didn't succeed with that until now. To not forget
about posting this issue, I'm gonna post it anyway.
Under certain circumstances I get a java.util.ConcurrentModificationException from
SessionImpl.getEntityName(). It occures only, when I call getEntityName() on an entity
that has just been loaded via Session.load(), and has lazy associations. As you can see in
the stacktrace the exception occurs in PersistenceContext.containsProxy(), where the proxy
checking and lazy-initializer-fetching happens. The problem seems to be that if the lazy
association is being loaded during that call, which definitely seems to happen in my case,
it modifies the PersistenceContext's proxiesByKey map. During the iteration the
modification is being discovered and accordingly the exception is being thrown.
The code involved is a lot, so I it's hard for me to separate the problem code from
the rest, since there's a whole meta model around the code involved. What I can offer
is a patch for the SessionImpl which definitely solved the problem for me. I ran the
Hibernate test suites and all seemed to be well with it except the query- and
ANTLR-involving ones which somehow don't want to work for me. The patch is inspired by
the code in SessionImpl.getIdentifier() which does a similar thing. The following version
of SessionImpl.getEntityName() seems to solve the problem:
public String getEntityName(Object object) {
if (object instanceof HibernateProxy) {
LazyInitializer li = ((HibernateProxy) object).getHibernateLazyInitializer();
if ( li.getSession() != this ) {
throw new TransientObjectException( "The proxy was not associated with this
session" );
}
object = li.getImplementation();
}
EntityEntry entry = persistenceContext.getEntry(object);
if (entry==null) throwTransientObjectException(object);
return entry.getPersister().getEntityName();
}
The stacktrace I get is as follows. FYI:
java.util.ConcurrentModificationException
at org.apache.commons.collections.ReferenceMap$EntryIterator.checkMod(Unknown
Source)
at org.apache.commons.collections.ReferenceMap$EntryIterator.hasNext(Unknown
Source)
at java.util.AbstractCollection.contains(AbstractCollection.java:99)
at
org.hibernate.engine.PersistenceContext.containsProxy(PersistenceContext.java:468)
at org.hibernate.impl.SessionImpl.getEntityName(SessionImpl.java:1449)
at
de.asdis.acm.persistence.support.hibernate.HibernatePersistenceManager.getOid(HibernatePersistenceManager.java:116)
at
de.asdis.acm.persistence.support.hibernate.HibernatePersistenceManager.getObjectById(HibernatePersistenceManager.java:207)
at de.asdis.acm.api.tools.SoftwareTools.findSoftwareBO(SoftwareTools.java:113)
at
de.asdis.acm.api.tools.SoftwareTools.createSoftwarePackage(SoftwareTools.java:499)
at
de.asdis.acm.api.ejb.ObjectManagerServiceBean.createSoftwarePackage(ObjectManagerServiceBean.java:497)
at sun.reflect.GeneratedMethodAccessor382.invoke(Unknown Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.jboss.invocation.Invocation.performCall(Invocation.java:345)
at
org.jboss.ejb.StatelessSessionContainer$ContainerInterceptor.invoke(StatelessSessionContainer.java:214)
at
org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:185)
at
org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:130)
at
org.jboss.webservice.server.ServiceEndpointInterceptor.invoke(ServiceEndpointInterceptor.java:51)
at
org.jboss.ejb.plugins.CallValidationInterceptor.invoke(CallValidationInterceptor.java:48)
at
org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:105)
at
org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:335)
at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:166)
at
de.asdis.acm.interceptor.jboss.ApiExceptionInterceptor.invoke(ApiExceptionInterceptor.java:33)
at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:139)
at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:192)
at
org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
at org.jboss.ejb.SessionContainer.internalInvoke(SessionContainer.java:624)
at org.jboss.ejb.Container.invoke(Container.java:873)
at sun.reflect.GeneratedMethodAccessor212.invoke(Unknown Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at
org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:141)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:80)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:72)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:249)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:644)
at
org.jboss.invocation.jrmp.server.JRMPInvoker$MBeanServerAction.invoke(JRMPInvoker.java:805)
at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:406)
at sun.reflect.GeneratedMethodAccessor211.invoke(Unknown Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
at sun.rmi.transport.Transport$1.run(Transport.java:148)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
at
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
at java.lang.Thread.run(Thread.java:534)
I tried to reproduce this bug without the container, but haven't been able to do so
yet. The fix works fine in our environment, where several thousand objects use this code
during testing.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: