I've seen this error before, in the case where my Id generation strategy was IDENTITY, and I had a new persisted but unflushed object on the One-side of a One-Many relation, and I tried to persist a new object on the Many side, and then called commit. OpenJPA would try to set the FK value on the Many side with the PK value from the One side, but the value was not available until flush time, and OpenJPA would think that the One-side entity was unmanaged.
My problem was not random, though. The solution for me was to: new up an entity, immediately call em.persist(), immediately call em.flush(), and only then set up the relationships from this entity to other entities, especially for all entities that had IDENTITY (or SEQUENCE) strategy. hth, Dinkar On Fri, Mar 5, 2010 at 11:55 AM, Daryl Stultz <[email protected]> wrote: > Hello, some of you have read about this issue I am having and some have > offered various suggestions. I'm still getting this > > <openjpa-1.2.1-r752877:753278 nonfatal user error> > org.apache.openjpa.persistence.InvalidStateException: Encountered > unmanaged object > in persistent field "...model.Case.addedBy" 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.User-23 > > It seems to be completely random. The failed object is not new as "23" is > the primary key of the object. I've collected the status of a number of > flags: > > failedObject: JpaEntity-User:23-23-EM:dxnPrt BK:cdxnPrt SM:null > JpaEntity-User:23.isDetached() = false > JpaEntity-User:23.getDetachedState() = null > > The flags are capital if true, lowercase false: > isDetachedNew c > isDetached d > isDirty x > isNew n > isPersistent p > isDeleted r > isTransactional t > > The flags are read from: > EM - entity manager > BK - broker > SM - state manager > > The last 2 are from this: > PersistenceCapable pc = ImplHelper.toPersistenceCapable(object, null); > sb.append(pc + ".isDetached() = " + pc.pcIsDetached() + "\n"); > sb.append(pc + ".getDetachedState() = " + > (Arrays.toString((Object[])pc.pcGetDetachedState())) + "\n") > > So the failed object is persistent but the state manager is null. The only > way I've been able to "imitate" the stack trace is to try to save a root > object with an association (many-to-one) where the associated object is > currently managed by a *different* em. So contrary to the error message, > it's managed but not by the current em. I don't know if that's the same > condition that's causing my app to crash. It seems like the only way this > could happen is if one user loads up a web page while another user saves an > object with an association to an object currently being managed by the first > user's action. This would make the whole operation one big race condition. > > If the "object managed by a different em" is not what is happening in my > application, then OpenJPA seems to be mysteriously dropping the state of the > object (or failing to get it) and thus thinks the object is new and > unmanaged. > > Anybody have any new ideas for me? > > I'm using OpenJPA 1.2.1. > > Thanks. > > -- > Daryl Stultz > _____________________________________ > 6 Degrees Software and Consulting, Inc. > http://www.6degrees.com > mailto:[email protected] >
