openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Albert Lee <allee8...@gmail.com>
Subject Re: StateManager setup with embedded entity handling in Cassandra plugin
Date Fri, 08 Apr 2011 16:39:24 GMT
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