Community
Participate
Working Groups
>An SE application hangs indefinitely trying to acquire the lock during a toString() on a LAZY list. >The following code locks when the custom toString() is invoked during a debug session in Eclipse or is printed to the console ConcurrencyManager.java: public synchronized void acquire(boolean forMerge) throws ConcurrencyException { > while (((this.activeThread != null) || (this.numberOfReaders > 0)) && (this.activeThread != Thread.currentThread())) { >because of the client code public String toString() {... > for(Processor<P> processor : processors) { // this for:each loop may hang on an indirectList for LAZY fetchType @Entity public class HyperCube<P> extends ComputeFabric implements Serializable { ... // LAZY will hang on 3+ entries during a toString() if a resultList is instantiated from a query via debugging or iteration @OneToMany(mappedBy="hyperCube", cascade=CascadeType.ALL, fetch=FetchType.LAZY)//.EAGER) private List<Processor<P>> processors; >Forensics: Use JConsole.exe and navigate to the threads tab - select the main thread for SE ConcurrencyManager.java public synchronized void acquire(boolean forMerge) throws ConcurrencyException { while (((this.activeThread != null) || (this.numberOfReaders > 0)) && (this.activeThread != Thread.currentThread())) { // This must be in a while as multiple threads may be released, or another thread may rush the acquire after one is released. try { this.numberOfWritersWaiting++; >93: wait(); Name: main State: WAITING on org.eclipse.persistence.internal.helper.ConcurrencyManager@1072b90 Total blocked: 0 Total waited: 1 Stack trace: java.lang.Object.wait(Native Method) java.lang.Object.wait(Object.java:485) org.eclipse.persistence.internal.helper.ConcurrencyManager.acquire(ConcurrencyManager.java:93) org.eclipse.persistence.internal.identitymaps.CacheKey.acquire(CacheKey.java:126) org.eclipse.persistence.internal.identitymaps.AbstractIdentityMap.acquireLock(AbstractIdentityMap.java:120) org.eclipse.persistence.internal.identitymaps.IdentityMapManager.acquireLock(IdentityMapManager.java:144) org.eclipse.persistence.internal.sessions.IdentityMapAccessor.acquireLock(IdentityMapAccessor.java:92) org.eclipse.persistence.internal.sessions.IdentityMapAccessor.acquireLock(IdentityMapAccessor.java:83) org.eclipse.persistence.internal.sessions.AbstractSession.retrieveCacheKey(AbstractSession.java:4556) org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:665) org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:496) org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectsInto(ObjectBuilder.java:975) org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:426) org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1080) org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:808) org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1040) org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:383) org.eclipse.persistence.internal.sessions.AbstractSession.internalExecuteQuery(AbstractSession.java:2789) org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1508) org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1490) org.eclipse.persistence.internal.indirection.QueryBasedValueHolder.instantiate(QueryBasedValueHolder.java:98) org.eclipse.persistence.internal.indirection.QueryBasedValueHolder.instantiate(QueryBasedValueHolder.java:88) org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:88) - locked org.eclipse.persistence.internal.indirection.QueryBasedValueHolder@21c3b0 org.eclipse.persistence.indirection.IndirectList.buildDelegate(IndirectList.java:237) org.eclipse.persistence.indirection.IndirectList.getDelegate(IndirectList.java:397) - locked org.eclipse.persistence.indirection.IndirectList@b69467 org.eclipse.persistence.indirection.IndirectList$1.<init>(IndirectList.java:525) org.eclipse.persistence.indirection.IndirectList.listIterator(IndirectList.java:524) org.eclipse.persistence.indirection.IndirectList.iterator(IndirectList.java:488) org.eclipse.persistence.example.jpa.dataparallel.model.HyperCube.toString(HyperCube.java:269) java.text.MessageFormat.subformat(MessageFormat.java:1246) java.text.MessageFormat.format(MessageFormat.java:836) java.text.Format.format(Format.java:140) java.text.MessageFormat.format(MessageFormat.java:812) org.eclipse.persistence.internal.localization.EclipseLinkLocalization.buildMessage(EclipseLinkLocalization.java:77) org.eclipse.persistence.internal.localization.TraceLocalization.buildMessage(TraceLocalization.java:30) org.eclipse.persistence.logging.AbstractSessionLog.formatMessage(AbstractSessionLog.java:852) org.eclipse.persistence.logging.DefaultSessionLog.log(DefaultSessionLog.java:156) - locked org.eclipse.persistence.logging.DefaultSessionLog@c907ff org.eclipse.persistence.internal.sessions.AbstractSession.log(AbstractSession.java:3058) org.eclipse.persistence.internal.sessions.AbstractSession.log(AbstractSession.java:4174) org.eclipse.persistence.internal.sessions.AbstractSession.log(AbstractSession.java:4146) org.eclipse.persistence.internal.sessions.AbstractSession.log(AbstractSession.java:4122) org.eclipse.persistence.internal.sessions.AbstractSession.log(AbstractSession.java:4044) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.logDebugMessage(UnitOfWorkImpl.java:5475) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerExistingObject(UnitOfWorkImpl.java:3856) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerExistingObject(UnitOfWorkImpl.java:3826) org.eclipse.persistence.mappings.ObjectReferenceMapping.buildUnitofWorkCloneForPartObject(ObjectReferenceMapping.java:100) org.eclipse.persistence.mappings.ObjectReferenceMapping.buildCloneForPartObject(ObjectReferenceMapping.java:74) org.eclipse.persistence.internal.indirection.NoIndirectionPolicy.cloneAttribute(NoIndirectionPolicy.java:76) org.eclipse.persistence.mappings.ForeignReferenceMapping.buildClone(ForeignReferenceMapping.java:250) org.eclipse.persistence.internal.descriptors.ObjectBuilder.populateAttributesForClone(ObjectBuilder.java:3273) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.populateAndRegisterObject(UnitOfWorkImpl.java:3622) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cloneAndRegisterObject(UnitOfWorkImpl.java:987) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cloneAndRegisterObject(UnitOfWorkImpl.java:916) org.eclipse.persistence.internal.sessions.UnitOfWorkIdentityMapAccessor.getAndCloneCacheKeyFromParent(UnitOfWorkIdentityMapAccessor.java:181) org.eclipse.persistence.internal.sessions.UnitOfWorkIdentityMapAccessor.getFromIdentityMap(UnitOfWorkIdentityMapAccessor.java:120) org.eclipse.persistence.internal.sessions.IdentityMapAccessor.getFromIdentityMap(IdentityMapAccessor.java:367) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerExistingObject(UnitOfWorkImpl.java:3868) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerExistingObject(UnitOfWorkImpl.java:3826) org.eclipse.persistence.mappings.ObjectReferenceMapping.buildUnitofWorkCloneForPartObject(ObjectReferenceMapping.java:100) org.eclipse.persistence.mappings.ObjectReferenceMapping.buildCloneForPartObject(ObjectReferenceMapping.java:74) org.eclipse.persistence.internal.indirection.NoIndirectionPolicy.cloneAttribute(NoIndirectionPolicy.java:76) org.eclipse.persistence.mappings.ForeignReferenceMapping.buildClone(ForeignReferenceMapping.java:250) org.eclipse.persistence.internal.descriptors.ObjectBuilder.populateAttributesForClone(ObjectBuilder.java:3273) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.populateAndRegisterObject(UnitOfWorkImpl.java:3622) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cloneAndRegisterObject(UnitOfWorkImpl.java:987) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cloneAndRegisterObject(UnitOfWorkImpl.java:916) org.eclipse.persistence.internal.sessions.UnitOfWorkIdentityMapAccessor.getAndCloneCacheKeyFromParent(UnitOfWorkIdentityMapAccessor.java:181) org.eclipse.persistence.internal.sessions.UnitOfWorkIdentityMapAccessor.getFromIdentityMap(UnitOfWorkIdentityMapAccessor.java:120) org.eclipse.persistence.internal.sessions.IdentityMapAccessor.getFromIdentityMap(IdentityMapAccessor.java:367) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerExistingObject(UnitOfWorkImpl.java:3868) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerExistingObject(UnitOfWorkImpl.java:3826) org.eclipse.persistence.mappings.ObjectReferenceMapping.buildUnitofWorkCloneForPartObject(ObjectReferenceMapping.java:100) org.eclipse.persistence.mappings.ObjectReferenceMapping.buildCloneForPartObject(ObjectReferenceMapping.java:74) org.eclipse.persistence.internal.indirection.NoIndirectionPolicy.cloneAttribute(NoIndirectionPolicy.java:76) org.eclipse.persistence.mappings.ForeignReferenceMapping.buildClone(ForeignReferenceMapping.java:250) org.eclipse.persistence.internal.descriptors.ObjectBuilder.populateAttributesForClone(ObjectBuilder.java:3273) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.populateAndRegisterObject(UnitOfWorkImpl.java:3622) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cloneAndRegisterObject(UnitOfWorkImpl.java:987) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.cloneAndRegisterObject(UnitOfWorkImpl.java:916) org.eclipse.persistence.internal.sessions.UnitOfWorkIdentityMapAccessor.getAndCloneCacheKeyFromParent(UnitOfWorkIdentityMapAccessor.java:181) org.eclipse.persistence.internal.sessions.UnitOfWorkIdentityMapAccessor.getFromIdentityMap(UnitOfWorkIdentityMapAccessor.java:120) org.eclipse.persistence.internal.sessions.IdentityMapAccessor.getFromIdentityMap(IdentityMapAccessor.java:367) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerExistingObject(UnitOfWorkImpl.java:3868) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerExistingObject(UnitOfWorkImpl.java:3826) org.eclipse.persistence.mappings.CollectionMapping.buildElementUnitOfWorkClone(CollectionMapping.java:265) org.eclipse.persistence.mappings.CollectionMapping.buildElementClone(CollectionMapping.java:277) org.eclipse.persistence.internal.queries.ContainerPolicy.addNextValueFromIteratorInto(ContainerPolicy.java:210) org.eclipse.persistence.mappings.CollectionMapping.buildCloneForPartObject(CollectionMapping.java:203) org.eclipse.persistence.internal.indirection.UnitOfWorkQueryValueHolder.buildCloneFor(UnitOfWorkQueryValueHolder.java:51) org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiateImpl(UnitOfWorkValueHolder.java:161) org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiate(UnitOfWorkValueHolder.java:222) org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:88) - locked org.eclipse.persistence.internal.indirection.UnitOfWorkQueryValueHolder@2bf6c0 org.eclipse.persistence.indirection.IndirectList.buildDelegate(IndirectList.java:237) org.eclipse.persistence.indirection.IndirectList.getDelegate(IndirectList.java:397) - locked org.eclipse.persistence.indirection.IndirectList@54be84 org.eclipse.persistence.indirection.IndirectList$1.<init>(IndirectList.java:525) org.eclipse.persistence.indirection.IndirectList.listIterator(IndirectList.java:524) org.eclipse.persistence.indirection.IndirectList.iterator(IndirectList.java:488) org.eclipse.persistence.example.jpa.dataparallel.model.HyperCube.toString(HyperCube.java:269) java.lang.String.valueOf(String.java:2826) java.lang.StringBuilder.append(StringBuilder.java:115) org.eclipse.persistence.example.dataparallel.GridClient.queryComparisonViaNamedQuery(GridClient.java:236) org.eclipse.persistence.example.dataparallel.GridClient.demo(GridClient.java:266) org.eclipse.persistence.example.dataparallel.GridClient.main(GridClient.java:373) Name: Finalizer State: WAITING on java.lang.ref.ReferenceQueue$Lock@9b6976 Total blocked: 96 Total waited: 91 Stack trace: java.lang.Object.wait(Native Method) java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118) java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134) java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159) >Workaround: - change to FetchType.EAGER - or, remove custom toString() that does a for:each on the indirect list
Created attachment 185891 [details] SE Eclipse 3.5 JPA project reproduction and model
>Essentially, this issue occurs if we trigger indirect instantiation by printing LAZY relationships while debugging or in a println() If we toString() a simpler flat representation of the entity we are OK
>3rd option) use if(!(processors instanceof IndirectList)) { // from core for(Processor<P> processor : processors) { // this for:each loop may hang on an indirectList for LAZY fetchType
>Discussed this with team Was a previously known issues - we don't know which side of the relationship will lock first. >reproduction of this obscure use-case was A bidirectional @OneToMany mixed LAZY/EAGER relationship is debugged on the OneToMany inverse side when the collection is still lazy (uninstantiated = IndirectList) public class HyperCube<P> extends ComputeFabric implements Serializable { // Inverse side @OneToMany(mappedBy="hyperCube", cascade=CascadeType.ALL, fetch=FetchType.LAZY) private List<Processor<P>> processors; ... } public class Processor<P> implements Serializable { // owning side @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER) private HyperCube<P> hyperCube; >We will likely no fix this one.
>Similar reference bugs (we need to triage whether any of them are related) Looks like only bug # 309822 may be related (interaction with the lazy IndirectList) bug# 309822 Deadlock when returning Entities from a remote method call bug# 312110 NoWait locking code continues to wait on ReadLock (fixed) bug# 312462 ConcurrencyManager.acquire() hangs forever (fixed) dup of Bug# 312110 - discovered RT newgroup posting relating to bug# 309822 that is a usefull alternate reproduction reference.
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink