JPA+hibernate merge vs find fetching lazy collection

K

kamiseq

hi,
I have very strange behaviour with my JPA entities.

I have to entities GenObject and GenObjectCnf that are linked with one-
to-many type, where in GenObject
@OrderBy
@OneToMany(cascade = CascadeType.ALL, mappedBy = "objects", fetch =
FetchType.LAZY)
private List<GenObjectCfg> objectsCfgSet = new ArrayList<GenObjectCfg>
();

now I create GenObject and persist it. then I instantiate new
GenObjectCnf object assign GenObject with it and persist. so in the db
everything is fine data is saved and I can move on. transaction is
over and my objects are detached from session.

the problem is now that my GenObject doesn't know about GenObjectCnf
as it was created before it and I didn't assigned GenObjectCnf back
after I created it. so I thought I can simply merge GenObject object
to update its state and data I need. so in other transaction Im
calling

this.em.merge(object);
GenObjectCfg parentCfg = object.getObjectsCfgSet().get(0);

as it should fetch all GenObjectCnf related to this GenObject object.
but is not and list remain empty.

BUT when I call
GenObject go = this.em.find(GenObject.class, object.getIdObject());
GenObjectCfg parentCfg = go.getObjectsCfgSet().get(0);

data is fetched and I get what I want, so essentially what am I
missing??
why is it so??

Im really out of ideas and it is something about how JPA works and I
didnt learn that yet, doesnt it?!
 
T

Tom Anderson

I have to entities GenObject and GenObjectCnf that are linked with one-
to-many type, where in GenObject
@OrderBy
@OneToMany(cascade = CascadeType.ALL, mappedBy = "objects", fetch =
FetchType.LAZY)
private List<GenObjectCfg> objectsCfgSet = new ArrayList<GenObjectCfg>
();

now I create GenObject and persist it. then I instantiate new
GenObjectCnf object assign GenObject with it and persist.
^^^^^^^^^^^^^^^^^^^^^^^^

What does this mean? It's not correct English, i'm afraid. Posting the
code that does this would be very helpful.

I assume that you mean that you assign the owning GenObject to the
GenObjectCnf's object field, like this:

GenObject someObject;
GenObjectCnf someCnf = new GenObjectCnf();
someCnf.object = someObject;

If my understanding is wrong, the rest of my advice will probably be
wrong.
the problem is now that my GenObject doesn't know about GenObjectCnf as
it was created before it and I didn't assigned GenObjectCnf back after I
created it. so I thought I can simply merge GenObject object to update
its state and data I need.

The solution is much simpler than this - you store the GenObjectCnf into
the GenObject's objectsCfgSet list:

someObject.objectsCfgSet.add(someCnf);

This is a very important point, which you may not have appreciated - JPA
does *not* manage bidirectional relationships at the object level, only at
the database level. So, if you create a bidirectional relationship, you
have to create both ends. See:

http://blog.xebia.com/2009/03/16/jpa-implementation-patterns-bidirectional-assocations/

It's possible i've misunderstood your problem completely - apologies if
so.

tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,981
Messages
2,570,188
Members
46,733
Latest member
LonaMonzon

Latest Threads

Top