Hi Marc,

The example I sent was something I hacked together to populate a database
using your model. Basically it creates 3 Fathers with 2 children for each of
them. Hopefully that didn't distract you too much.

The real issue is setting the backrefs. In JPA the application must maintain
both sides of a bi-directional relationship (on your Java objects). There's
some wording in the spec to this effect which I can drag up if you're
interested.

The other thing that might be worth noting is that when you add
mappedBy="something" JPA will consider the Many side (in your case Child, or
Player) the _owner_ of the relationship. Using the @Embedded annotations may
reverse the owners - but you need to remove the mappedBy attribute of
@OneToMany. It's the owner of the relationship which matters "most".

So for general JPA use I definitely recommend setting both sides of the
relationship to make sure they get persisted properly.

That said, OpenJPA does provide a mechanism to manage the inverse side of
relationships for you. You can read about it in the users guide here :
http://openjpa.apache.org/builds/1.2.1/apache-openjpa-1.2.1/docs/manual/manual.html#ref_guide_inverses.
It sounds like it's exactly what you're looking for.

Hope this helps.  If you have other questions keep posting.

-mike

On Fri, Nov 13, 2009 at 11:39 AM, Marc Logemann <[email protected]> wrote:

> Hi,
>
> for the records, i am using 1.2.0.
>
> To your question: i am only doing that (sorry, i changed my example to be
> Team->Player, instead of Father->Child) :
>
>        Player p = new Player();
>        p.setName("Huiboo");
>        List<Player> list = new ArrayList<Player>();
>        list.add(p);
>
>        Team t = new Team();
>        t.setName("VfL");
>        t.setPlayers(list);
>        em.persist(t);
>
> So yes, i am only setting the child references in the list and i dont
> manually set the backreference. To be honest,  i dont understand your
> example too well. I wouldnt expect that i need to do the backreferences
> manually.
>
> At this point i know something that works without setting backrefs
> manually, but this looks also quite weird to me because i must use OneToOne
> on the child. If i do the mapping on the Team (Father) like this:
>
>    @OneToMany(cascade = CascadeType.PERSIST)
>    @ElementJoinColumn(name = "team_oid", referencedColumnName = "oid")
>    public List<Player> players;
>
> and then do the mappedBy in the child (player)
>
>    @OneToOne(mappedBy = "players")
>    public Team team;
>
> Then i have my bidirectional link and i also have the FK column filled like
> if i wouldnt use the mappedBy.
>
> Would you recommend doing it like you have done it? As i said, i would
> expect the ORM layer to work out the back reference because i already
> defined the relationship via setting childs to a list, why telling the
> childs again to which object they belong?
>
> Thanks for being with me on that one. Appreciate that.
>
>
>
> ---
> regards
> Marc Logemann
> http://www.logemann.org
> http://www.logentis.de
>
>
>
>
> Am 13.11.2009 um 18:27 schrieb Michael Dick:
>
>
>  Hi Marc,
>>
>> Are you setting the relationship for both the Father and Child entities?
>>
>> I see the behavior you describe if I do this :
>>       Father f;
>>       Child c;
>>       for (int i = 0; i < nFathers; i++) {
>>           f = new Father();
>>           f.setChildren(new ArrayList<Child>());
>>           em.persist(f);
>>
>>           for(int j = 0 ; j < nChildren; j++ ) {
>>               c = new Child();
>> //                c.setFather(f);
>>               f.getChildren().add(c);
>>               em.persist(c);
>>           }
>>
>>
>> Uncommenting c.setFather(f); fixes the problem. If that doesn't help let
>> me
>> know which version of OpenJPA and which database you're using and I'll try
>> to recreate.
>>
>> -mike
>>
>> On Fri, Nov 13, 2009 at 10:33 AM, Marc Logemann <[email protected]> wrote:
>>
>>  Hi,
>>>
>>> what you have done works of course but thats not my problem because thats
>>> what i had before i wanted to do the inverse. Your example simply
>>> demonstrates how to use ElementJoinColumn and i am pretty aware of that
>>> ;-)
>>> The problem starts when using mappedBy on the children inside Father.
>>>
>>> When i am doing it as you described it in your email before, i am at
>>> least
>>> not getting any errors back but instead he inserts a "null" in my FK
>>> field.
>>>
>>>  @ManyToOne
>>>  @ForeignKey
>>>  @JoinColumn(name="team_oid", referencedColumnName="oid")
>>>  public Team team;
>>>
>>> I am really clueless. It simply cant be so hard and uncommon to make an
>>> inverse OneToMany with a FK field in the child table.
>>>
>>> I googled for hours and all example i ve found just dont work.
>>>
>>>
>>>
>>> ---
>>> regards
>>> Marc Logemann
>>> http://www.logemann.org
>>> http://www.logentis.de
>>>
>>>
>>>
>>>
>>> Am 13.11.2009 um 17:17 schrieb Michael Dick:
>>>
>>>
>>> Hi Marc,
>>>
>>>>
>>>> Did some more reading and I was wrong about the use case for the
>>>> @Element
>>>> annotations. The @Element annotations allow you to specify the FK
>>>> constraint
>>>> on the One side of a @OneToMany, so your annotations would look like
>>>> this
>>>> :
>>>>
>>>> @Entity
>>>> public class Father extends Person {
>>>>  @OneToMany
>>>>  @ElementForeignKey
>>>>  @ElementJoinColumn(name="father_oid", referencedColumnName="oid")
>>>>  Collection<Child> children;
>>>> . . .
>>>> }
>>>>
>>>> @Entity
>>>> public class Child extends Person {
>>>>  @ManyToOne
>>>>  private Father father;
>>>> . . .
>>>> }
>>>>
>>>> It appears to be functionally identical to using @JoinColumn and
>>>> @ForeignKey
>>>> on the Child class, but the documentation is a bit sparse on this
>>>> annotation..
>>>>
>>>> There are several examples in our unit tests though. For example
>>>>
>>>>
>>>> openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/bidi/ParentWithAutoIdentity.java
>>>> looks somewhat similar to your model.
>>>>
>>>> Hope this helps,
>>>> -mike
>>>>
>>>>
>>>> ---------- Forwarded message ----------
>>>> From: Michael Dick <[email protected]>
>>>> Date: Fri, Nov 13, 2009 at 9:52 AM
>>>> Subject: Re: inverse OneToMany relation - getting weird
>>>> To: [email protected]
>>>>
>>>>
>>>> Hi Marc,
>>>>
>>>> I think the @ElementForeignKey and @ElementJoinColumn annotations are
>>>> intended to be used with non-entity types (ie PersistentCollections).
>>>>
>>>> If Child is an entity you'd want to use @ForeignKey and @JoinColumn
>>>> instead
>>>> (I gave this a quick try and it looks like it worked for me).
>>>>
>>>> Regards,
>>>> -mike
>>>>
>>>>
>>>> On Fri, Nov 13, 2009 at 7:03 AM, Marc Logemann <[email protected]> wrote:
>>>>
>>>> Hi,
>>>>
>>>>>
>>>>> after struggling for several hours, i need to ask for help.
>>>>>
>>>>> Following scenario.....
>>>>>
>>>>> DB Table: Father
>>>>> ---------------------------
>>>>> INT oid
>>>>> ....
>>>>>
>>>>>
>>>>> DB Table: Childs
>>>>> ------------------------
>>>>> INT oid
>>>>> INT father_oid
>>>>> ...
>>>>>
>>>>> Java Entity: Father
>>>>> --------------------------
>>>>> ...
>>>>> @OneToMany(cascade = CascadeType.PERSIST, mappedBy = "father")
>>>>> private List<Child> childList;
>>>>>
>>>>> Java Entity: Child
>>>>> --------------------------
>>>>> ...
>>>>> @ManyToOne(cascade = CascadeType.PERSIST)
>>>>> @ElementForeignKey
>>>>> @ElementJoinColumn(name="father_oid", referencedColumnName="oid")
>>>>> protected Father father;
>>>>>
>>>>>
>>>>> When i try to persist a Father, i am getting:
>>>>>
>>>>> <openjpa-1.2.0-r422266:683325 fatal user error>
>>>>> org.apache.openjpa.persistence.ArgumentException: Field
>>>>> "Father.childList"
>>>>> declares "Child.father" as its mapped-by field, but this field is not a
>>>>> direct relation. at......
>>>>>
>>>>> Ok, then i changed Child to:
>>>>>
>>>>> Java Entity: Child
>>>>> --------------------------
>>>>> ...
>>>>> @ManyToOne(cascade = CascadeType.PERSIST)
>>>>> @Column(name = "father_oid")
>>>>> protected Father father;
>>>>>
>>>>>
>>>>> When i now do persist a Father object, both DB records (Father and
>>>>> Childs)
>>>>> are filled with records but the FK column in Child (father_oid) is
>>>>> empty.
>>>>> So
>>>>> the FK relation is broken but it did persist childs, which is somehow
>>>>> weird.
>>>>>
>>>>> So whatever i do, i never get a fully persisted graph with correct FK
>>>>> values.
>>>>>
>>>>> Can anyone give me a hint what i am doing wrong here?
>>>>>
>>>>>
>>>>> Thanks a lot.
>>>>>
>>>>> ---
>>>>> regards
>>>>> Marc Logemann
>>>>> http://www.logemann.org
>>>>> http://www.logentis.de
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>
>

Reply via email to