Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
3.0
-
None
-
3.0 M1
Description
I've been using a shared DataContext in a read-only multi-threaded app. Looks like I've stumbled upon a race condition in resolving to-one relationship. I've noticed applications occasionally spinning out of control with load averages on the box shooting to 50 and higher. A "kill -QUIT" on the Jetty server shows a bunch of threads executing the code shown in the stack below. Googling for "java.util.HashMap.get(HashMap.java:346)" shows that this is a common race condition (looks like HashMap.get() is stuck in an endless loop). The easiest solution is to use the common objectstore lock spanning most of the DataContext.localObject(..).
at java.util.HashMap.get(HashMap.java:346)
at org.apache.cayenne.CayenneDataObject.readPropertyDirectly(CayenneDataObject.java:212)
at org.apache.cayenne.reflect.generic.DataObjectBaseProperty.readPropertyDirectly(DataObjectBaseProperty.java:69)
at org.apache.cayenne.reflect.generic.DataObjectToManyProperty.injectValueHolder(DataObjectToManyProperty.java:98)
at org.apache.cayenne.reflect.PersistentDescriptor.injectValueHolders(PersistentDescriptor.java:247)
at org.apache.cayenne.reflect.LazyClassDescriptorDecorator.injectValueHolders(LazyClassDescriptorDecorator.java:113)
at org.apache.cayenne.access.DataContext.localObject(DataContext.java:1679)
at org.apache.cayenne.access.DataDomainQueryAction.interceptRelationshipQuery(DataDomainQueryAction.java:228)
at org.apache.cayenne.access.DataDomainQueryAction.execute(DataDomainQueryAction.java:113)
at org.apache.cayenne.access.DataDomain.onQuery(DataDomain.java:722)
at org.apache.cayenne.util.ObjectContextQueryAction.runQuery(ObjectContextQueryAction.java:282)
at org.apache.cayenne.access.DataContextQueryAction.execute(DataContextQueryAction.java:59)
at org.apache.cayenne.access.DataContext.onQuery(DataContext.java:1321)
at org.apache.cayenne.access.DataContext.performQuery(DataContext.java:1310)
at org.apache.cayenne.access.DataContextFaults$ToOneFault.doResolveFault(DataContextFaults.java:113)
at org.apache.cayenne.access.DataContextFaults$ToOneFault.resolveFault(DataContextFaults.java:86)
at org.apache.cayenne.CayenneDataObject.readProperty(CayenneDataObject.java:204)