openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Dick <michael.d.d...@gmail.com>
Subject Re: SingleFieldManager.preFlushPC
Date Fri, 28 Aug 2009 19:37:45 GMT


Daryl Stultz wrote:
> 
> On Fri, Aug 28, 2009 at 1:46 PM, Michael Dick
> <michael.d.dick@gmail.com>wrote:
> 
>>
>> The scenario you've described doesn't sound right (maybe I need a
>> refresher). The new ShippingInstructions object should be unmanaged
>> unless
>> you've managed to inject a StateManager into it (which would be a good
>> trick).
>>
> 
> No, I've never injected anything in my life. I'm working in Tomcat. I'm
> still confused, if an object has a state manager it's managed? Doesn't a
> detached object have a state manager? Here's my unit test (as clean as
> possible):
> 
My fault, I shouldn't have mentioned injecting a StateManager - there's
almost no way you could have done that. 

Detachted Entities do have a StateManager some of the time. You can
configure the detached SM to be transient in which case it'll be lost at
serialization time (you can also remove the detached SM entirely though).
Obligatory link to 
http://openjpa.apache.org/builds/latest/docs/manual/manual.html#ref_guide_detach_graph
docs 

Lets just look at your example for now though and I'll try not to muddy the
waters any more. 


Daryl Stultz wrote:
> 
> User editingUser = em.find(User.class, userOneId);
> ScheduledAssignment saOne = setup.insertScheduledAssignment(...);
> 

saOne is persisted and committed in a separate transaction? 


Daryl Stultz wrote:
> 
> TimeTrackingEntry entry = new TimeTrackingEntry();
> entry.setScheduledAssignment(saOne);
> entry.setStartTime(startTime);
> entry.setStartTime(endTime);
> em = setup.getEntityManager(); // different em than above, simulating
> different thread/web transaction
> User editingUserClone = new User();
> editingUserClone.setId(editingUser.getId());
> editingUserClone.setArchived(editingUser.isArchived());
> ... more property copying
> entry.setAddedBy(editingUserClone);
> entry.setAddedOn(Calendar.getInstance().getTime());
> em.getTransaction().begin();
> em.merge(entry);
> em.getTransaction().commit(); // expected this to fail, but it works
> 

Aha, you're calling em.merge which is slightly different than em.persist.
Merge handles detached, or unmanaged entities differently. If a row in the
database matches the entity you're merging we'll issue an update (there's
some version checking here to help prevent the app from shooting itself in
the foot too). 

The error message we gave you is a bit misleading in this case. We should be
using Cascade.MERGE instead of Cascade.PERSIST. This may be a case where we
find the row in the database and issue an update, if the row isn't found we
go back and do a 'normal' persist - resulting in the error message you see.

>From what you've said the row always exists in the database though - so
maybe this isn't a perfect match.. 

-mike


Daryl Stultz wrote:
> 
>>
>> Out of idle curiosity do you have any properties set in persistence.xml?
>> Or
>> should I be able to reproduce this with OpenJPA's default configuration?
>>
> 
> <property name="openjpa.LockManager" value="none" />
> <property name="openjpa.DetachState" value="loaded(AccessUnloaded=false)"
> />
> 
> -- 
> Daryl Stultz
> _____________________________________
> 6 Degrees Software and Consulting, Inc.
> http://www.6degrees.com
> mailto:daryl@6degrees.com
> 
> 

-- 
View this message in context: http://n2.nabble.com/SingleFieldManager-preFlushPC-tp3534271p3536988.html
Sent from the OpenJPA Developers mailing list archive at Nabble.com.

Mime
View raw message