openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Todd Nine <t...@spidertracks.com>
Subject Re: StateManager setup with embedded entity handling in Cassandra plugin
Date Sat, 09 Apr 2011 00:19:22 GMT
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 <todd@spidertracks.com> 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 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 <allee8285@gmail.com> 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 <curtisr7@gmail.com> 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 <todd@spidertracks.com>
>> 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: 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're
>> > having
>> > > problems with?
>> > >
>> > > Thanks,
>> > > Rick
>> > >
>> > > On Wed, Apr 6, 2011 at 7:42 PM, Todd Nine <todd@spidertracks.com>
>> 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.
>>
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message