Hey guys, In response to Ricks question,if I begin a transaction before the read this issue seems to go away. In terms of my test, I move line 130 up to line 113. I read the spec last night on Embedded entities. I couldn't find anything specific to the case I'm seeing in section 2.5 or 2.6 of the 2.0 spec.
Using merge does resolve the issue, however I seem to have encountered an inconsistency in the behavior when using detached entities between @Embedded and @ElementCollection(fetch=FetchType.EAGER). Both load the associated elements on load. However an ElementCollection correctly persists the collection without a merge operation before the persist call. The user set values are returned correctly when sm.fetch(field id) is called, but an @Embedded object returns a new Embeddable with all fields set to null. Is this by design, or just the way Open JPA behaves? I honestly don't care either way, but I need to know so that I can document how to use @Embedded and @ElementCollection with the Cassandra Plugin. Thanks, Todd On 9 April 2011 04:39, Albert Lee <[email protected]> wrote: > Todd, > > em2.getTransaction().begin(); > Customer returned = em2.find(Customer.class, james.getId()); > em2.getTransaction().commit(); <<< After tx committed, > "returned" is detached; see 3.2.7 below > .... > returned.getPhoneNumber().setPhoneNumber("+6411122255555"); <<< > update a detached entity, ok > .... > em2.getTransaction().begin(); > em2.persist(returned); <<< Since "returned" is detached, > should use em2.merge(returned) to get updated data back to em2 > <<< make sure you use the merge() > returned managed entity for subsequent use. > <<< See 3.2.2 below. > "EntityExistsException MAY be thrown...." for persist(detach entity) > behavior > em2.getTransaction().commit(); > > em2.close(); > > > 3.2.2 Persisting an Entity Instance > The semantics of the persist operation, applied to an entity X are as > follows: > • If X is a preexisting managed entity, it is ignored by the persist > operation. However, the persist > operation is cascaded to entities referenced by X, if the relationships > from > X to these other > entities are annotated with the cascade=PERSIST or cascade=ALL annotation > element > value or specified with the equivalent XML descriptor element. > • If X is a detached object, the EntityExistsException may be thrown when > the persist > operation is invoked, or the EntityExistsException or another > PersistenceException > may be thrown at flush or commit time. > > 3.2.7 Detached Entities > A detached entity results from transaction commit if a transaction-scoped > container-managed entity > manager is used (see section 3.3); from transaction rollback (see section > 3.3.2); from detaching the > entity from the persistence context; from clearing the persistence context; > from closing an entity manager; > or from serializing an entity or otherwise passing an entity by value—e.g., > to a separate application > tier, through a remote interface, etc. > > Hope this help. > Albert Lee. > > On Fri, Apr 8, 2011 at 10:57 AM, Rick Curtis <[email protected]> wrote: > > > Todd - > > > > Thanks for pointing at the new test... it helps me understand your > scenario > > a little better. I'm still unsure about a couple things... > > > > em2.persist(returned); // : line 132 > > > > You're calling persist on an Entity which should already be a part of the > > persistence context.? At this point calling em.contains(returned) should > > return true. I'm surprised that this isn't throwing an > > EntityExistsException > > exception(or something like that). > > > > You noted that if you reverse 1 and 2 the problem goes away. What line > > numbers in the test do 1 and 2 correspond to in your test? > > > > Thanks, > > Rick > > > > On Thu, Apr 7, 2011 at 10:16 PM, Todd Nine <[email protected]> > wrote: > > > > > Cancel that. I managed to show the exact same behavior in my test. > > Check > > > out the test now. It appears to be something with this combination. > > > > > > 1. Close transaction > > > 2. Read embedded persistent fields > > > 3. update embedded persistent field > > > 4. begin transaction > > > 5. persist > > > 6. commit > > > > > > If I reverse 1 and 2, I don't get the issue. Hopefully this test > > > demonstrates the problem. > > > > > > > > > > > > > > > > > > > > > On Fri, 2011-04-08 at 14:02 +1200, Todd Nine wrote: > > > > > > Hey Rick. > > > > > > I'm attempting to re-create it in my test here, but I'm not having any > > > luck. It's something specific in our app. > > > > > > > > > > > > https://github.com/riptano/hector-jpa/blob/master/src/test/java/com/datastax/hectorjpa/store/SimpleTest.java > > > > > > Test case is embeddedFieldOnlyDirty. > > > > > > Essentially I'm using an open session in view pattern in our webapp > which > > > binds and entity manager to the thread via spring. These are the steps > > that > > > occur, the issue seems to be on flushing during commit. > > > > > > > > > entity manager created > > > > > > transaction started > > > > > > load Customer with embedded phone Embedded phone has it's own > > > StateManager, which points to the Customer's StateManager, as it's > > parent. > > > This all seems correct > > > > > > transaction commit. Both state managers are still correct. > > > > > > > > > Web UI makes changes to Address object and calls business tier > > > > > > transaction starts > > > > > > em.persist is invoked. At this point both the Customer and Address > have > > > correct StateManagers. The state manager on customer shows the address > > > field as dirty, and the state manager on address shows the field that > was > > > changed via the web ui as dirty. > > > > > > > > > transaction is committed. > > > > > > When "flush" is invoked on my plugin during the commit operation, > address > > > is present, but all fields are null, and the statemanager is not the > same > > > instance that was present before the commit operation. It's almost as > if > > > the Customer stateManager does not properly cascade to the Address SM > > during > > > the commit. > > > > > > My explanation above is for the test which demonstrates the issue. > > > Hopefully my test makes the problem I'm having clear. > > > > > > > > > -- > > > todd > > > SENIOR SOFTWARE ENGINEER > > > > > > todd nine| spidertracks ltd | 117a the square > > > po box 5203 | palmerston north 4441 | new zealand > > > P: +64 6 353 3395 > > > E: [email protected] W: www.spidertracks.com > > > > > > > > > > > > > > > > > > > > > > > > > > > On Thu, 2011-04-07 at 20:06 -0500, Rick Curtis wrote: > > > > > > Todd - > > > > > > I'm somewhat confused as to where you are running into problems. > Perhaps > > > you can write a small unit test that will better describe what you're > > having > > > problems with? > > > > > > Thanks, > > > Rick > > > > > > On Wed, Apr 6, 2011 at 7:42 PM, Todd Nine <[email protected]> > wrote: > > > > > > Hi all, > > > I'm having a very difficult time working with embedded entities in > > > Cassandra. Specifically, this is the case where I'm getting very > > > strange behavior. Em = Entity Manager. > > > > > > em1 created > > > em1 begin transaction > > > em 1 load User entity , the embedded Address object is correct. > > > em 1 complete transaction > > > > > > User entity is now detached. > > > > > > Address is updated > > > > > > em 1 begin transaction > > > User is attached > > > em 1 flush > > > > > > em1 commit transaction > > > > > > > > > The Address now has a null entity manager, and all fields are null, > > > however it is correct when the entity was passed to the flush operation > > > before using StateManager.get(fieldId) to retrieve the embedded object. > > > > > > For the cassandra plugin in it's first implementation, we're requiring > > > all @Embeddable entities to also implement Serializable. The embedded > > > entity value is simply serialized to a column > > > > > > Here is the embedded column implementation I have created for @Embedded > > > and @ElementCollection > > > > > > > > > > > > https://github.com/riptano/hector-jpa/blob/master/src/main/java/com/datastax/hectorjpa/meta/EmbeddedColumnField.java > > > > > > > > > Any guidance would be greatly appreciated. I know I'm not wiring the > > > entity manager correctly during load, I'm just unsure what else I need > > > to do. I've looked at both ElementEmbedValueHandler and > > > EmbedFieldStrategy, however I'm not getting anywhere. Any help would > be > > > greatly appreciated. > > > > > > Thanks in advance! > > > > > > Todd > > > > > > > > > > > > > > > -- > Albert Lee. >
