一对一主键关联映射(双向)

双向和单向的区别,其实不在数据库,而在加载方向。按照我们Person和IdCard的例子,单向是Person通过拥有IdCard的实例可以加载IdCard,而双向不但Person可以加载IdCard,还使IdCard通过拥有Person实例来加载Person。数据库还是原来的数据库(两个共享主键的表),不同的是在IdCard实体类中增加Person类型的变量和在IdCard.hbm.xml中增加了对该变量的配置。
 
1.实体模型:


 
 
2.关系模型:


 
 
3.实体类:
IdCard.java
public   class  IdCard {  
   private  Integer id;  
   private  String cardNo;  
   private  Person person;  
//一系列的setter.getter方法 
  @Override  
   public  String toString() {  
     return   "Idcard:"+cardNo;  
  }  
}
 
Person.java
public   class  Person {  
   private  Integer id;  
   private  String name;  
   private  IdCard idCard;  
//一系列的setter.getter方法 
  @Override  
   public  String toString() {  
     // TODO Auto-generated method stub 
     return   "Person:"+name;  
  }  
}
 
4.映射文件:
IdCard.hbm.xml
   < class   name ="com.sxt.hibernate.one2one.entity.IdCard"   table ="sxt_hibernate_idCard" >  
     < id   name ="id"   length ="4" >  
       < generator   class ="native" > </ generator >  
     </ id >  
     < property   name ="cardNo"   length ="10" > </ property >  
    <!--  one-to-one标签是为了加载 -->  
     < one-to-one   name ="person" > </ one-to-one >  
   </ class >
Person.hbm.xml
   < class   name ="com.sxt.hibernate.one2one.entity.Person"   table ="sxt_hibernate_person" >  
     < id   name ="id"   length ="4" >  
      <!--  person的主键来源于idCard,也就是共享idCard的主键 -->  
       < generator   class ="foreign" >  
         < param   name ="property" >idCard </ param >  
       </ generator >  
     </ id >  
     < property   name ="name"   length ="10" > </ property >  
    <!-- one-to-one标签的含义,指示Hibernate如何加载它的关联对象,默认根据主键加载。 
      constrained="true"的含义,表明当前主键上存在一个约束,person的主键作为外键参照了idCard, 
      并且要求关联属性不能为空 
        
-->  
     < one-to-one   name ="idCard"   constrained ="true" > </ one-to-one >  
   </ class >
 
5.hibernate配置文件
hibernate.cfg.xml
限于篇幅,可以参照上一篇的该文件,此处就不再赘述。
 
6.测试方法:
   public   static   void  main(String[] args) {  
    Session session = HibernateUtils.getSession();  
    Transaction t = session.beginTransaction();  

     try  {  
       /** 
        * 测试插入操作 
        */
 
/*      IdCard idCard = new IdCard(); 
      idCard.setCardNo("1234567890"); 

      Person person = new Person(); 
      person.setName("张三"); 
      idCard.setPerson(person); 
      session.save(idCard);//这样的话,如果不在IdCard.hbm.xml的<one-to-one>中设置cascade="save-update"的话,会只保存上idCard,而保存不上关联属性person记录 
     //如果设置上cascade="save-update",则会先保存person记录,而由于person主键要引用idCard的id,此时idCard又没有保存呢,所以会报错org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: idCard 
      */
 
        
/*      IdCard idCard = new IdCard(); 
      idCard.setCardNo("1234567890"); 
      Person person = new Person(); 
      person.setName("张三"); 
      idCard.setPerson(person); 
      session.save(person);//这样貌似关系已经建立好了,但是在存person时,它的主键关联属性idCard的id,而此时idCard为null,所以还是会报错org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: idCard 
*/
 
        
/*      IdCard idCard = new IdCard(); 
      idCard.setCardNo("1234567890"); 
      Person person = new Person(); 
      person.setName("张三"); 
      person.setIdCard(idCard); 
      session.save(person);//这样,既建立好了关系,而且保存时还由person来维护关联关系,保存才是成功的 
      */

       /** 
        * 小结:插入时先插主表,后插副表.必须保证主表记录已经插入了,才能为副表提供引用需要的id. 
        */
 

        
       /** 
        * 测试加载操作 
        */
 
/*      Person p=(Person)session.load(Person.class, 1); 
      System.out.println(p); 
      System.out.println(p.getIdCard());*/
 
        
      IdCard idCard=(IdCard)session.get(IdCard. class, 1);  
      System.out.println(idCard);  
      System.out.println(idCard.getPerson());  
      t.commit();  
    }   catch  (HibernateException e) {  
      e.printStackTrace();  
      t.rollback();  
    }   finally  {  
      HibernateUtils.closeSession(session);  
    }  

  }  

}  

本文出自 “夜狼” 博客,请务必保留此出处http://yangfei520.blog.51cto.com/1041581/273249

 

你可能感兴趣的:(关联映射)