Hello, I occasionally get this exception (meaning it's not repeatable):
<openjpa-1.2.1-r752877:753278 fatal user error>
org.apache.openjpa.persistence.InvalidStateException:
Encountered unmanaged object in persistent field
"model.EntityA.b" during flush.
However, this field does not allow cascade persist.
Set the cascade attribute for this field to CascadeType.PERSIST or
CascadeType.ALL (JPA annotations)
or "persist" or "all" (JPA orm.xml), or enable cascade-persist globally,
or manually persist the related field value prior to flushing.
You cannot flush unmanaged objects or graphs that have persistent
associations to unmanaged objects.
FailedObject: model.EntityB-5
at
org.apache.openjpa.kernel.SingleFieldManager.preFlushPC(SingleFieldManager.java:754)
at
org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:594)
at
org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:562)
at
org.apache.openjpa.kernel.SingleFieldManager.preFlush(SingleFieldManager.java:478)
at
org.apache.openjpa.kernel.StateManagerImpl.preFlush(StateManagerImpl.java:2829)
at
org.apache.openjpa.kernel.PNewState.beforeFlush(PNewState.java:39)
at
org.apache.openjpa.kernel.StateManagerImpl.beforeFlush(StateManagerImpl.java:960)
at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1948)
at
org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1908)
at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1679)
at
org.apache.openjpa.kernel.StateManagerImpl.assignObjectId(StateManagerImpl.java:524)
at
org.apache.openjpa.kernel.StateManagerImpl.assignField(StateManagerImpl.java:609)
at
org.apache.openjpa.kernel.StateManagerImpl.beforeAccessField(StateManagerImpl.java:1495)
at
org.apache.openjpa.kernel.StateManagerImpl.accessingField(StateManagerImpl.java:1478)
at model.EntityA.pcGetid(...)
at model.EntityA.getId(...)
at model.EntityA.getId(...)
at model.EntityA.hashCode(...)
at java.util.HashMap.get(HashMap.java:300)
The code pattern may be different for the few times the exception has
occurred but in this case it's something like this:
em.getTrasaction().begin();
EntityA a = new EntityA(); // Instantiate new EntityA
a.setB(b); // assign relations to other (detached) objects (including
reference to EntityB-5 above)
em.persist(a);
// continue working with a
em.getTrasaction().commit();
The traceback above refers to "continue working with a". "a" was placed in a
HashMap and the hashCode of "a" was being used to retrieve it. The hashcode
method of "a" refers to the id. The process of getting the id triggers a
flush, which seems to make sense since "a" has not actually been inserted
into the database and we need the primary key. So it seems I should at least
not be referencing the id of "a" until after the commit. The thing is, the
exception is not reproducible. It has failed just once and I keep doing the
same action and it won't fail again. I've encountered this exception before
and discovered that the FailedObject is in fact managed but not by the
current em (by a different one). A plausible explanation for this is a
ThreadLocal bug in the JDK. I store the current em on a ThreadLocal variable
(I've upgraded the JDK which appears to have taken care of it). In this case
I don't understand what is going on that causes apparently inconsistent
behavior. Any ideas appreciated.
Thanks.
--
Daryl Stultz
_____________________________________
6 Degrees Software and Consulting, Inc.
http://www.6degrees.com
mailto:[email protected]