-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Newbie mapping question, multiple one-to-many mappings
PostPosted: Thu Oct 26, 2006 8:11 pm 
Newbie

Joined: Thu Oct 26, 2006 7:53 pm
Posts: 1
Hi all,

I'm currently trying to crack Hibernate. Here's what I conceptually want to achieve:

A "Parent" class has a set of "Children". Each "Child" has a Mother (a Parent) and a Father (Parent).

My proposed hbm's are:

Code:
<hibernate-mapping>
    <class name="events.Adult" table="ADULT">
        <id name="id" column="ADULT_ID">
            <generator class="native"/>
        </id>
    </class>
</hibernate-mapping>

<hibernate-mapping>
    <class name="events.Child" table="CHILD">
        <id name="id" column="CHILD_ID">
            <generator class="native"/>
        </id>
       
      <many-to-one name="mother" class="events.Adult" column="ADULT_ID"/>
      <many-to-one name="father" class="events.Adult" column="ADULT_ID"/>
    </class>
</hibernate-mapping>


Now obviously this does not work, as there are two things mapping on to ADULT_ID.

But I'm unsure how to achieve this using Hibernate's mapping model. In legacy database design, I'd have two foreign keys on the child table, mother and father, then to produce a children set for the Parent, i'd do a UNION or simple OR clause in my SQL SELECT.

I'm hopeful I might be able to add something like this to the Adult class:

Code:
<set name="children" inverse="true">
    <key column="CHILD_ID"/>
    <one-to-many class="Child"/>
</set>


... and magically produce the children set (all who have the Adult as their Father or Mother), but I'm not sure if this is possible with mappings or whether it might needlessly complicate things.

A related problem (and here the biological Parent/Child analogy falls down!), is what happens if I want to have a separate method for getFatheredChildren (Child who has Adult as father) or getMotheredChildren (Child who has Adult as mother). I could add the following to my mapping:

Code:
<set name="motheredChildren" inverse="true">
    <key column="CHILD_ID"/>
    <one-to-many class="Child"/>
</set>

<set name="fatheredChildren" inverse="true">
    <key column="CHILD_ID"/>
    <one-to-many class="Child"/>
</set>


Again this doesn't work. If I could persuade it to work, how would Hibernate properly work out which set should contain which items? This doesn't seem to be specified anywhere in the mapping.

Am I approaching this entirely from the wrong direction?

Thoughts appreciated...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 27, 2006 10:45 am 
Newbie

Joined: Fri Oct 27, 2006 5:10 am
Posts: 2
Hello,

I do not have that much experience in the field but I think that you can make sub-classes in each class. Use the gender field to define a father and a mother class for this. Then you can make the many-to-one to that sub-class. Check the documentation on that.

Regards,

Marco


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 27, 2006 12:06 pm 
Senior
Senior

Joined: Sun Jun 11, 2006 10:41 am
Posts: 164
Which of the following parenting options do you need to support:
1. mother AND father
2. mother only
3. father only
4. No mother nor father

If #1 is needed, you simply need to have two separent columns: FATHER_ID and MOTHER_ID:
<many-to-one name="father" class="events.Father" column="FATHER_ID"/>
<many-to-one name="mother" class="events.Mother" column="MOTHER_ID"/>

If #2, #3 or #4 is needed, make a single "many-to-one" declaration to a "parent", instead of two declarations:
<many-to-one name="parent" class="events.Adult" column="PARENT_ID"/>

In either case, you need to create mother and father Adult subclasses (in a table-per-hierarchy model):

<hibernate-mapping>
<class name="events.Adult" table="ADULT"
discriminator-value="A"
>
<id name="id" column="ADULT_ID">
<generator class="native"/>
</id>
<discriminator column="type" type="string"/>
</class>
</hibernate-mapping>

<hibernate-mapping>
<subclass name="events.Father"
extends="events.Adult"
discriminator-value="F">
</subclass>
</hibernate-mapping>

<hibernate-mapping>
<subclass name="events.Mother"
extends="events.Adult"
discriminator-value="M">
</subclass>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 27, 2006 1:31 pm 
Newbie

Joined: Thu Aug 24, 2006 5:14 pm
Posts: 4
An alternative to subclassing would be for the Adult class to hold a "gender" field, two private sets of children (for hibernate), and one computed public set of children (for the app):

Code:
    private Set<Child> fatheredChildren = new HashSet<Child>();
    private Set<Child> motheredChildren = new HashSet<Child>();

    public Set<Child> getChildren()
    {
        if ("m".equals(getGender()))
        {
            return fatheredChildren;
        }
        else
        {
            return motheredChildren;
        }
    }

    public void addChild(Child child)
    {
        if ("m".equals(getGender()))
        {
            child.setFather(this);
            fatheredChildren.add(child);
        }
        else
        {
            child.setMother(this);
            motheredChildren.add(child);
        }
    }
}


Only the two private children sets are mapped, of course:
Code:
    <set name="fatheredChildren" access="field" table="child" cascade="all">
        <key column="father_id"/>
        <one-to-many class="Child"/>
    </set>
    <set name="motheredChildren" access="field" table="child" cascade="all">
        <key column="mother_id"/>
        <one-to-many class="Child"/>
    </set>


The child would have two references, one for the father and one for the mother:
Code:
    <many-to-one name="father" column="father_id"/>
    <many-to-one name="mother" column="mother_id"/>


This isn't particularly pretty, but it works. On the other hand, subclassing just for this doesn't strike me as being a lot prettier, unless of course you have other reasons to subclass in addition to this.

Mathieu


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.