Return-Path: Delivered-To: apmail-openjpa-dev-archive@www.apache.org Received: (qmail 86027 invoked from network); 9 Apr 2011 00:19:50 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 9 Apr 2011 00:19:50 -0000 Received: (qmail 82820 invoked by uid 500); 9 Apr 2011 00:19:50 -0000 Delivered-To: apmail-openjpa-dev-archive@openjpa.apache.org Received: (qmail 82779 invoked by uid 500); 9 Apr 2011 00:19:50 -0000 Mailing-List: contact dev-help@openjpa.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@openjpa.apache.org Delivered-To: mailing list dev@openjpa.apache.org Received: (qmail 82771 invoked by uid 99); 9 Apr 2011 00:19:50 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 09 Apr 2011 00:19:50 +0000 X-ASF-Spam-Status: No, hits=2.2 required=5.0 tests=HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_NEUTRAL X-Spam-Check-By: apache.org Received-SPF: neutral (athena.apache.org: local policy) Received: from [209.85.216.174] (HELO mail-qy0-f174.google.com) (209.85.216.174) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 09 Apr 2011 00:19:44 +0000 Received: by qyk7 with SMTP id 7so201311qyk.12 for ; Fri, 08 Apr 2011 17:19:22 -0700 (PDT) MIME-Version: 1.0 Received: by 10.229.106.214 with SMTP id y22mr2282982qco.105.1302308362490; Fri, 08 Apr 2011 17:19:22 -0700 (PDT) Sender: todd@spidertracks.co.nz Received: by 10.229.11.75 with HTTP; Fri, 8 Apr 2011 17:19:22 -0700 (PDT) In-Reply-To: References: <1302136925.2531.90.camel@greenlantern> <1302228171.2531.117.camel@greenlantern> <1302232607.2531.119.camel@greenlantern> Date: Sat, 9 Apr 2011 12:19:22 +1200 X-Google-Sender-Auth: x5tqrv6IMhcY6wVUO3J_mvJojpQ Message-ID: Subject: Re: StateManager setup with embedded entity handling in Cassandra plugin From: Todd Nine To: dev@openjpa.apache.org Cc: Albert Lee , Rick Curtis Content-Type: multipart/alternative; boundary=0023544705585592fa04a0714b9c --0023544705585592fa04a0714b9c Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable Hi guys, Another update. After doing some additional debugging, I believe I've found the source of the issue. On line 260 of the AttachManager class cascading the attach, the embedded objects are not cascaded. As a result, the fields that were set on the detached embedded entity are not properly deep copied from detached embedded instance into the new instance loaded as part of the merge operation. It doesn't seem possible to set cascade merge on @Embedded using the javax annotations. Shouldn't this be the default behavior? Todd On 9 April 2011 08:22, Todd Nine wrote: > 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 t= o > line 113. I read the spec last night on Embedded entities. I couldn't f= ind > 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 @Embed= ded > and @ElementCollection(fetch=3DFetchType.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 w= ay > Open JPA behaves? I honestly don't care either way, but I need to know s= o > that I can document how to use @Embedded and @ElementCollection with the > Cassandra Plugin. > > Thanks, > Todd > > > On 9 April 2011 04:39, Albert Lee wrote: > >> Todd, >> >> em2.getTransaction().begin(); >> Customer returned =3D 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: >> =95 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=3DPERSIST or cascade=3DALL annot= ation >> element >> value or specified with the equivalent XML descriptor element. >> =95 If X is a detached object, the EntityExistsException may be thrown w= hen >> 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-scope= d >> container-managed entity >> manager is used (see section 3.3); from transaction rollback (see sectio= n >> 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=97e.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 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) shou= ld >> > 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 >> 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 a= ny >> > > luck. It's something specific in our app. >> > > >> > > >> > > >> > >> https://github.com/riptano/hector-jpa/blob/master/src/test/java/com/data= stax/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 tha= t >> 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 S= M >> > 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: todd@spidertracks.co.nz 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'r= e >> > having >> > > problems with? >> > > >> > > Thanks, >> > > Rick >> > > >> > > On Wed, Apr 6, 2011 at 7:42 PM, Todd Nine >> 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 =3D 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 requiri= ng >> > > all @Embeddable entities to also implement Serializable. The embedd= ed >> > > 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/data= stax/hectorjpa/meta/EmbeddedColumnField.java >> > > >> > > >> > > Any guidance would be greatly appreciated. I know I'm not wiring th= e >> > > entity manager correctly during load, I'm just unsure what else I ne= ed >> > > to do. I've looked at both ElementEmbedValueHandler and >> > > EmbedFieldStrategy, however I'm not getting anywhere. Any help woul= d >> be >> > > greatly appreciated. >> > > >> > > Thanks in advance! >> > > >> > > Todd >> > > >> > > >> > > >> > >> >> >> >> -- >> Albert Lee. >> > > --0023544705585592fa04a0714b9c--