Bug 380573 - NullPointerException in WriteLockManager and it never releases it's lock
Summary: NullPointerException in WriteLockManager and it never releases it's lock
Status: CLOSED INVALID
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: All Linux
: P2 major with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: Nobody - feel free to take it CLA
QA Contact:
URL:
Whiteboard:
Keywords: needinfo
Depends on:
Blocks:
 
Reported: 2012-05-24 13:50 EDT by Eric Neilsen CLA
Modified: 2022-06-09 10:29 EDT (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Eric Neilsen CLA 2012-05-24 13:50:09 EDT
Build Identifier: 2.3.2.v20111125-r10461

We are seeing locks in the identity manager that are never being released. This causes a big problem when a secondary thread tries to read that object. After digging into the logs I noticed that there is a NPE in the WriteLockManager. See the stack trace listed below. After further digging into the problem I noticed that the CacheKey's object is null but the key isn't. Ultimately, the thread throws an exception and the lock is never released. Subsequent threads try to acquire the lock and block waiting for the lock to release. When we see this problem we have to bounce the application.

java.lang.NullPointerException
	at org.eclipse.persistence.internal.helper.WriteLockManager.appendLock(WriteLockManager.java:407)
	at org.eclipse.persistence.internal.sessions.MergeManager.mergeChangesOfWorkingCopyIntoOriginal(MergeManager.java:700)
	at org.eclipse.persistence.internal.sessions.MergeManager.mergeChangesOfWorkingCopyIntoOriginal(MergeManager.java:617)
	at org.eclipse.persistence.internal.sessions.MergeManager.mergeChanges(MergeManager.java:267)
	at org.eclipse.persistence.internal.queries.ContainerPolicy.mergeCascadeParts(ContainerPolicy.java:1042)
	at org.eclipse.persistence.internal.queries.ContainerPolicy.mergeChanges(ContainerPolicy.java:1080)
	at org.eclipse.persistence.mappings.CollectionMapping.mergeChangesIntoObject(CollectionMapping.java:1334)
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder.mergeChangesIntoObject(ObjectBuilder.java:3409)
	at org.eclipse.persistence.internal.sessions.MergeManager.mergeChangesOfWorkingCopyIntoOriginal(MergeManager.java:744)
	at org.eclipse.persistence.internal.sessions.MergeManager.mergeChangesOfWorkingCopyIntoOriginal(MergeManager.java:617)
	at org.eclipse.persistence.internal.sessions.MergeManager.mergeChanges(MergeManager.java:267)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.mergeChangesIntoParent(UnitOfWorkImpl.java:3254)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitRootUnitOfWork(UnitOfWorkImpl.java:1327)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commit(UnitOfWorkImpl.java:1087)


Other Threads just block forever:
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:485)
org.eclipse.persistence.internal.helper.ConcurrencyManager.acquire(ConcurrencyManager.java:94)
org.eclipse.persistence.internal.identitymaps.CacheKey.acquire(CacheKey.java:126)
org.eclipse.persistence.internal.identitymaps.AbstractIdentityMap.acquireLock(AbstractIdentityMap.java:122)
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:4688)
org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:772)
org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:603)
org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectsInto(ObjectBuilder.java:1081)
org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:436)
org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1081)
org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:844)
org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1040)
org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:392)
org.eclipse.persistence.internal.sessions.AbstractSession.internalExecuteQuery(AbstractSession.java:2831)
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1516)
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1498)
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)
	

Reproducible: Didn't try

Steps to Reproduce:
1. We see these errors in our production server. 
2. We haven't tried to manually reproduce the problem. But we do this this happening several times each week.
Comment 1 Tom Ware CLA 2012-07-04 08:11:26 EDT
Setting target and priority.  See the following page for the meanings of these fields:

http://wiki.eclipse.org/EclipseLink/Development/Bugs/Guidelines

Community: Please vote for this bug if it is important to you.  Votes are one of the main criteria we use to determine which bugs to fix next.
Comment 2 Gordon Yorke CLA 2012-09-06 09:30:51 EDT
Can you verify that the UnitOfWork is not being accessed by multiple threads.  The UnitOfWork or EntityManager is not threadsafe and should not be accessed by multiple threads.  Are you storing EMs or UOWs in an attribute of a Stateless Session Bean or a Servlet?  Doing either can lead to a single EntityManager or UnitOfWork being shared by multiple requests.
Comment 3 Michael Nielson CLA 2012-09-06 17:59:14 EDT
Hmm, interesting, that might just be the problem. It looks like I have one location where a uow is passed into another thread. I'll see if I can resolve the problem by fixing that issue.
Comment 4 Gordon Yorke CLA 2012-09-11 09:50:58 EDT
I have marked this as invalid.  If you find that changing the thread access to the EntityManager does not solve the issue then please reopen the bug.
Comment 5 Eric Neilsen CLA 2012-10-11 13:13:29 EDT
We are still having the problem. I have Michael post more information about this.
Comment 6 Michael Nielson CLA 2012-10-11 13:26:17 EDT
I modified the one location in our code base where a UnitOfWork moved threads (it wasn't used concurrently, just created in one thread and used in another). I'd hoped that cutting out this additional thread would solve the problem but that was not the case. 

I was also able to find an instance where this bug was triggered by a web request (zero chance of any threading involved at all), this web request is interesting because the source was an ajax call in the browser. The ajax call had a bug that caused the request to fire twice. Fixing the javascript bug "solved" that issue, but of course, the race condition is still present.
Comment 7 Michael Nielson CLA 2012-10-11 15:42:06 EDT
I can replicate this with a call to IdentityMapAccessor.initializeIdentityMaps()
Comment 8 Tom Ware CLA 2013-04-03 11:19:01 EDT
We should investigate for 2.4.3
Comment 9 Gordon Yorke CLA 2013-04-11 16:05:24 EDT
If you can replicate the problem please upload an example testcase that reproduces the issue or at least some pseudo code to provide the steps involved in reproducing the issue.
Comment 10 Michael Nielson CLA 2013-04-11 16:34:51 EDT
(In reply to comment #9)
> If you can replicate the problem please upload an example testcase that
> reproduces the issue or at least some pseudo code to provide the steps
> involved in reproducing the issue.

We were calling IdentityMapAccessor.initializeIdentityMaps() to clear the cache if we'd run raw SQL updates. This problem went away after we started invalidating the identity maps instead.
Comment 11 Gordon Yorke CLA 2013-04-17 14:20:37 EDT
IdentityMapAccessor.initializeIdentityMaps() must not be called in a running concurrent system and should only be used for testing.
Comment 12 Eclipse Webmaster CLA 2022-06-09 10:29:43 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink