Monday, February 21, 2011

How to map these classes with Hibernate?

Suppose I've these 2 classes:

class A{

    B ref1 = null; //Can both be null
    B ref2 = null;

}

class B{

    ..
}

I'm omitted the getters and setters for ref1 and ref2. Of course I want to add ids... Anyway what I want is to have hibernate handle automatic persistence of these two references... and to have automatic deletion of B objects. I thought of using one-to-one between each property ref* of A and B. But I got lost :) Can you give suggestions? I want to use SchemaExport.

Thank you.

From stackoverflow
  • you can achieve this behaviour by using the Cascade property of the OneToOne-Annotation. so with Hibernate Annotations / JPA Annotations youd have something like:

    @Entity
    public class AClass{
        @Id
        @GeneratedValue
        private long id;
        @OneToOne(cascade={Cascade.ALL, Cascade.DELETE_ORPHANS})
        private BClass b_1;
        @OneToOne(cascade={Cascade.ALL, Cascade.DELETE_ORPHANS})
        private BClass b_2;
    }
    
    @Entity
    public class BClass{
        private String someField;
    }
    

    in an XML-mapping the association should look something like this:

    <hibernate-mapping>
        <class name="AClass">
            <one-to-one cascade="all,delete-orphans" name="b_1" class="BClass" />
            <one-to-one cascade="all,delete-orphans" name="b_2" class="BClass" />
        </class>
    </hibernate-mapping>
    

    This should give you the wanted behaviour in cascading persistence operations onto the BClasses and delete any nonreferenced BClass Objects from the persistence layer.

    Have Fun!

    Frank

    gotch4 : thanks but I was looking for xml based mapping...
    gotch4 : moreover are you sure that it is safe to use one-to-one isn't it one to many for A?
    smeg4brains : well that depends on the data model, if you have one and only one reference from one AClass to one BClass it works, even if there are 2 fields holding BClasses in AClass. they just shouldnt be referencing the same instance
  • Hi,

    You have a @OneToMany relationship. But you have to adapt ORM to your model because of There is no @OneToTwo relationship available.

     <hibernate-mapping>
         <class name="ClassAa">
             <list name="classBbList">
                 <key column="CLASS_AA_ID" not-null="true"/>
                 <list-index column="CLASS_BB_INDEX"/>
                 <one-to-many class="ClassBb"/>
             </list>
         </class>
     <hibernate-mapping>
    

    Now your ClassAa looks like

    public class ClassAa {
    
        private ClassBb classBb1;
        private ClassBb classBb2;
    
        private List<ClassBb> classBbList = new ArrayList<ClassBb>();
    
        public void setClassBb1(ClassBb classBb1) {
            // You can use index 0 to store your classBb1
            if(getClassBbList().size == 0)
                getClassBbList().add(classBb1);
            else
                getClassBbList().set(0, classBb1);
        }
    
        public ClassBb getClassBb1() {
            if(getClassBbList().size() == 0)
                return null;
    
            return getClassBbList().get(0);
        }
    
        public void setClassBb2(ClassBb classBb2) {
            // You can use index 1 to store your classBb2
            switch(getClassBbList().size()) {
                case 0:
                    getClassBbList().add(null);
    
                    getClassBbList().add(classBb2);
                break;
                case 1:
                    getClassBbList().add(classBb2);
                break;
                case 2:
                    getClassBbList().set(1, classBb2);
                break;
            }
        }
    
        public ClassBb getClassBb2() {
            if(getClassBbList().size() < 2)
                return null;
    
            return getClassBbList().get(1);
        }
    
        public List<ClassBb> getClassBbList() {
            return this.classBbList;
        }
    
        public void setClasBbList(List<ClassBb> classBbList) {
            this.classBbList = classBbList;
        }
    
    }
    

    regards,

0 comments:

Post a Comment