-->
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.  [ 3 posts ] 
Author Message
 Post subject: A real parent - child relationship
PostPosted: Wed Feb 20, 2008 3:39 pm 
Newbie

Joined: Wed Feb 20, 2008 2:56 pm
Posts: 1
Hi,

My question is about a real parent - child relationship, where a child has two parents, a mother and a father, and those parents has a collection of children. Both child and parent are of the same class - User. So it's references to the same class, one user is the parent, a father or a mother, to another User.

I am confused about how to do the mapping since I have two many-to-one mappings:

<many-to-one name="father" column="father_id"/>

<many-to-one name="mother" column="mother_id"/>

... that I want to map to the same one-to-many set:

<set name="children" inverse="true">
<key column="?"/>
<one-to-many class="User"/>
</set>

I want the set of children to include users that reference the parent trough both father_id and mother_id.

One way around this problem is as I see it to skip the one-to-many part and just manually collect all the children with HQL query, but that must not be the best way to treat this issue is it?

/Marcus


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 20, 2008 4:58 pm 
Senior
Senior

Joined: Fri Jun 01, 2007 12:41 pm
Posts: 121
Here is my solution:

Basically father, mother and child are of type Person. So Person class has all common properties. Then create Family class that has associations with Father, Mother and Children.

Code:
package com.shyam.model;

/**
* @hibernate.class
* @author mutchaS
*
*/
public class Person {
   private Long id;
   private String name;
   
   public Person() {}
   
   /**
    * @hibernate.id generator-class="native"
    * @return
    */
   public Long getId() {
      return id;
   }
   public void setId(Long id) {
      this.id = id;
   }
   
   /**
    * @hibernate.property
    */
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
}


Code:
package com.shyam.model;

import java.util.Set;

/**
* @hibernate.class
* @author mutchaS
*
*/
public class Family {
   private Long id;
   private Person father;
   private Person mother;
   private Set children;
   
   public Family() {}
   
   /**
    * @hibernate.id generator-class="native"
    * @return
    */
   public Long getId() {
      return id;
   }
   public void setId(Long id) {
      this.id = id;
   }
   
   /**
    * @hibernate.many-to-one not-null="true" cascade="save-update" lazy="false"
    * @return
    */
   public Person getFather() {
      return father;
   }
   public void setFather(Person father) {
      this.father = father;
   }

   /**
    * @hibernate.many-to-one not-null="true" cascade="save-update" lazy="false"
    * @return
    */
   public Person getMother() {
      return mother;
   }
   public void setMother(Person mother) {
      this.mother = mother;
   }

   
   /**
    * @hibernate.set cascade="save-update, delete, delete-orphan"
    * @hibernate.one-to-many class="com.shyam.model.Child"
    * @hibernate.key column="FAMILY_ID" not-null="true" foreign-key="FK_FAMILY_ID"
    * @hibernate.list-index column="CHILD_POSITION" base="1"
    * @return
    */
   public Set getChildren() {
      return children;
   }
   public void setChildren(Set children) {
      this.children = children;
   }
   
   
}


Code:
package com.shyam.model;

/**
* @hibernate.joined-subclass
* @hibernate.joined-subclass-key column="id"
* @author mutchaS
*
*/
public class Child extends Person {/*
   private Family family;
   
   *//**
    * @hibernate.many-to-one not-null="true" cascade="save-update" lazy="false"
    * @return
    *//*
   public Family getFamily() {
      return family;
   }

   public void setFamily(Family family) {
      this.family = family;
   }*/
   
   
}


Here is the Person.hbm.cfg
Code:
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping

>

    <class
            name="com.shyam.model.Person"
    >

    <id
        name="id"
            column="id"
    >

    <!-- The generator-class attribute of @hibernate.id is deprecated, use the @hibernate.generator tag instead -->
    <generator class="native">

    </generator>

    </id>

        <property
            name="name"
                    column="name"
        >

        </property>

    <joined-subclass
        name="com.shyam.model.Child"
    >

            <!-- @hibernate.joined-subclass-key tag is deprecated, use @hibernate.key instead -->
            <key
                    column="id"
            />

    </joined-subclass>

    </class>   

</hibernate-mapping>



Here is the Family.hbm.cfg
Code:
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping

>

    <class
            name="com.shyam.model.Family"
    >

    <id
        name="id"
            column="id"
    >

    <!-- The generator-class attribute of @hibernate.id is deprecated, use the @hibernate.generator tag instead -->
    <generator class="native">

    </generator>

    </id>

        <many-to-one
            name="father"
                not-null="true"
                cascade="save-update"
                lazy="false"
        >

        </many-to-one>

        <many-to-one
            name="mother"
                not-null="true"
                cascade="save-update"
                lazy="false"
        >

        </many-to-one>

        <set
            name="children"
            cascade="save-update, delete, delete-orphan"
        >

            <key
                column="FAMILY_ID"
                foreign-key="FK_FAMILY_ID"
                not-null="true"
            >

            </key>         

            <one-to-many
                class="com.shyam.model.Child"
            />

        </set>

    </class>   

</hibernate-mapping>



Here is how I save the family
/
Code:
/First unit of work
      Session session = HibernateUtil.getSessionFactory().openSession();
      Transaction tx = session.beginTransaction();
      
      Person father = new Person();
      father.setName("father1");
      
      Person mother = new Person();
      mother.setName("mother1");
      
      Family family = new Family();
      family.setFather(father);
      family.setMother(mother);
      
      Set children = new HashSet();      
      Child child = new Child();
      child.setName("child1");
      children.add(child);
      
      Child child2 = new Child();
      child2.setName("child2");
      children.add(child2);
      
      family.setChildren(children);
      //session.save(family);
      
      tx.commit();
      session.close();



read family
Code:
List list = (List)session.createCriteria(Family.class).list();
      System.out.println("family: "+list.size());
      for(Iterator it = list.iterator(); it.hasNext();){
         family = (Family)it.next();
         System.out.println("\nfather: "+family.getFather().getName());
         System.out.println("mother: "+family.getMother().getName());
         children = family.getChildren();
         for(Iterator it2 = children.iterator(); it2.hasNext();){
            Child ch = (Child)it2.next();
            System.out.println("children: "+ch.getName());
         }
      }


and find family where
Code:
list = (List)session.createCriteria(Family.class)
               .createAlias("father", "father")
               .add(Restrictions.ilike("father.name", "father1", MatchMode.START))
               .list();
      System.out.println("family: "+list.size());
      for(Iterator it = list.iterator(); it.hasNext();){
         family = (Family)it.next();
         System.out.println("\nfather: "+family.getFather().getName());
         System.out.println("mother: "+family.getMother().getName());
         children = family.getChildren();
         for(Iterator it2 = children.iterator(); it2.hasNext();){
            Child ch = (Child)it2.next();
            System.out.println("children: "+ch.getName());
         }
      }


You can insert inverse relation between Child and Family.

[/code]


Top
 Profile  
 
 Post subject: Here's the solution
PostPosted: Wed Feb 20, 2008 5:27 pm 
Beginner
Beginner

Joined: Thu Dec 13, 2007 2:32 pm
Posts: 26
Have a User class with User field in it and a Set of Users in it.

Something like :

Code:
private User user;
private Set<User> users;



now, for some SQL, just to get you an idea as to what i am talking about ...

Code:
create table  user(user_id number primary key, parent_id number, user_name varchar2(25));

alter table user add constraint fk_parent_id_1 foreign key(parent_id) references user(user_id);


Now for the user mapping ( just a hint though, you can use Reverse engg in mapping but i like to do it by hand all the time ) :

Code:

<class name="User" table="user">
   <id name="userId" column="user_id">
       <generator class="native" />
   </id>
   
   <many-to-one class="User" column="parent_id" />

   <set name="users">
      <key column="user_id" />
      <one-to-many class="User" />
  </set>

</class>



Now understand that parent_id can be null to determine the complete lineage. ( since root cannot have a parent , if you get the picture)

_________________
Regards,
Vyas, Anirudh


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 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.