From: Lew on
Tom Anderson wrote:
> On Tue, 29 Dec 2009, Lew wrote:
>
>> On Dec 29, 4:33 pm, kamiseq <kami...(a)gmail.com> wrote:
>>
>>> @OrderBy
>>> @OneToMany(cascade = CascadeType.ALL, mappedBy = "objects", fetch =
>>> FetchType.LAZY)
>>> private List<GenObjectCfg> objectsCfgSet = new ArrayList<GenObjectCfg>
>>> ();
>>
>> Puzzle 1: Why are you explicitly allocating an ArrayList to
>> 'objectsCfgSet'?
>
> Because otherwise, it would be null, and so any attempt to use the
> object before it was persisted would fail. No?

No.

--
Lew
From: Lew on
Please confine your answers to the newsgroup. Content follows:

From: kamiseq <kamiseq(a)gmail.com>
To: Lew <lew(a)lewscanon.com>

> Puzzle 1: Why are you explicitly allocating an ArrayList to
> 'objectsCfgSet'?
why not? and plus you dont need to check every time if collection is
null or not.
this is not a problem here

> Puzzle 2: What is 'objects' in the 'GenObjectCfg' type? That the name is plural but it's
> mapping what presumably is a many-to-one from 'GenObjectCfg' is
> suspicious.

f man! yes it can be but is not. the plural form is only because I
auto generated it from DB where tables names are plural.
ech your puzzles are not helping at all as mapping is perfectly fine.
if it wasn't, it wouldnt work with em.find call

> Also, you didn't need to post your question twice. Someone eventually
> will get around to answering, or they won't.
oh it was probably some connection error. are you always answering to
threads you have no idea about?
From: Lew on
Lew wrote:
>> Puzzle 1: Why are you explicitly allocating an ArrayList to
>> 'objectsCfgSet'?

kamiseq wrote:
> why not? and plus you dont need to check every time if collection is
> null or not.
> this is not a problem here

Why not? Because it's atypical of JPA code and I haven't seen that done.
Usually you either let the JPA engine fill it or you fill it explicitly with
the setter. For example,
<http://java.sun.com/developer/technicalArticles/J2EE/jpa/Customer.java>

Lew wrote:
>> Puzzle 2: What is 'objects' in the 'GenObjectCfg' type? That the name
>> is plural but it's
>> mapping what presumably is a many-to-one from 'GenObjectCfg' is
>> suspicious.

kamiseq wrote:
> f man! yes it can be but is not. the plural form is only because I
> auto generated it from DB where tables names are plural.
> ech your puzzles are not helping at all as mapping is perfectly fine.
> if it wasn't, it wouldnt work with em.find call

Perhaps if you had provided enough code or the code you did was idiomatic, I
wouldn't have had to wonder. I wasn't able to clairvoyantly tell about that
variable, though, so I asked you for clarification, a reasonable strategy.

Lew wrote:
>> Also, you didn't need to post your question twice. Someone eventually
>> will get around to answering, or they won't.

kamiseq wrote:
> oh it was probably some connection error. are you always answering to
> threads you have no idea about?

There's certainly no reason to be so snarky. I actually have a bit of
experience with JPA, but you provided so little information in your post that
I had to ask questions to get enough out of you to hope to answer.

--
Lew
From: kamiseq on

> 1) The mappedBy name "objects" is jarring. If I understand you
> correctly, you're saying that for one GenObject we have many GenObjCnf
> objects. In the database the GenObjCnf table will have a foreign key for
> GenObject, and GenObjCnf is considered to be the owning side; GenObject
> is the inverse side, and has the mappedBy attribute, which you have
> correctly. "objects" is the field in each GenObjCnf that refers to the
> single GenObject, so would be something like
>
> GenObject genObject;
>
> and you'd more likely declare it as
>
> mappedBy="genObject"
>
sure but it was all auto generated by netbeans.

> 4) do you know for a fact that after persisting that the DB is updated?
> Are you looking at console SQL or keeping an eye o the tables? What are
> your transactions like? Are you using application-managed or
> container-managed entity managers?
>
this all fine

> 3) EntityManager.merge() doesn't update state - calling refresh() or
> explicitly changing state on the POJO instance does.
>
> 6) Lazy initialization is not pinned down by the JPA spec, leastways not
> JPA 1.0. Use at your own risk; persistence implementations have a lot of
> leeway. If you are newish to JPA, consider setting the OneToMany to
> EAGER (note that the default _is_ LAZY for that type of relationship, so
> you didn't need to put that in) and get stuff working.
(ok but then it is a problem again with List collection - so I prefer
to stay with Lazy fetch)

my question was more about why

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

works fine (so all mappings between entities are correct and data in
DB is correct) where

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

is not working at all. (ok refreshing object this.em.refresh(object);
solves the problem and data is fetched).

all I dont understand is - if my entity(GenObject) has lazily fetched
collection and it is detached from session then to start working with
that entity I need to first attach it to the session (em.merge()) then
I can normally fetch the collection from the db, cannot I?for me it
doesn't matter how I obtain/create the entity(GenObject). I can
em.find that entity and return it to the client (entity's collection
is empty), the client wants to fetch more information about related
objects(GenObjectCfg) so the GenObject entity is sent back, merged and
I should be able to retrieve GenObjectCfg objects list without
refreshing GenObject.
From: Tom Anderson on
On Tue, 29 Dec 2009, Lew wrote:

> Lew wrote:
>>> Puzzle 1: Why are you explicitly allocating an ArrayList to
>>> 'objectsCfgSet'?
>
> kamiseq wrote:
>> why not? and plus you dont need to check every time if collection is
>> null or not. this is not a problem here
>
> Why not? Because it's atypical of JPA code and I haven't seen that
> done. Usually you either let the JPA engine fill it

Which won't happen before the JPA provider has got its hands on it, so:

new GenObject().objectsCfgSet.add(something);

Will fail, right?

There's a general principle (more honoured in the breach than in the
observance) that JPA entities should be fully functional POJOs, ie should
work correctly even without JPA. Or, perhaps, that they *can* be, and
since this simplifies unit testing, some pundits elevate that to *should*.

> or you fill it explicitly with the setter. For example,
> <http://java.sun.com/developer/technicalArticles/J2EE/jpa/Customer.java>

They're using setters because they're using property access - note the @Id
annotation on the getCustomerID() method rather than the id field. That
means they have to use setters to set fields. Kamiseq is using field
access, which means he can access the fields directly. There's no
JPA-specific reason for him to use a setter rather than direct access.

tom

--
Remember Sammy Jankis.