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 Fri, 08 Apr 2011 20:22:20 GMT
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