服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

精通hibernate之映射继承关系七(图)


  company与employee类之间为一对多多态关联关系,如果继承关系树的根类对应一个表,或者每个类对应一个表,那么就能映射company类的employees集合。本节介绍如何映射多对一多态关联。如图14-11所示,classd与classa为多对一多态关联关系。
  
 精通hibernate之映射继承关系七(图)(图一)

  
图14-11 classd与classa为多对一多态关联关系

  
  classa、classb和classc构成了一棵继承关系树,如果继承关系树的根类对应一个表,或者每个类对应一个表,那么可以按以下方式映射classd的a属性:
  
  <many-to-one name="a"
  class="classa"
  column="a_id"
  cascade="save-update" />
  
  假定与classd对应的表为table_d,与classa对应的表为table_a,在table_d中定义了外键a_id,它参照table_a表的主键。
  
  classd对象的a属性既可以引用classb对象,也可以引用classc对象,例如:
  
  tx = session.begintransaction();
  classd d=(classd)session.get("classd",id);
  classa a=d.geta();
  if(a instanceof classb)
  system.out.println(((classb)a).getb1());
  if(a instanceof classc)
  system.out.println(((classc)a).getc1());
  tx.commit();
  
  以下代码在映射classd类的a属性时使用了延迟检索策略:
  
  <many-to-one name="a"
  class="classa"
  column="a_id"
  lazy="true"
  cascade="save-update" />
  
  当hibernate加载classd对象时,它的属性a引用classa的代理类实例,在这种情况下,如果对classa的代理类实例进行类型转换,会抛出classcastexception:
  
  classa a=d.geta();
  classb b=(classb)a; //抛出classcastexception
  
  解决以上问题的一种办法是使用session.load()方法:
  
  classa a=d.geta();
  classb b=(classb)session.load(classb.class,a.getid());
  system.out.println(b.getb1());
  
  当执行session的load()方法时,hibernate并不会访问数据库,而是仅仅返回classb的代理类实例。这种解决办法的前提条件是必须事先知道classd对象实际上和classa的哪个子类的对象关联。
  
  解决以上问题的另一种办法是显式使用迫切左外连接检索策略,避免hibernate创建classa的代理类实例,而是直接创建classa的子类的实例:
  
  tx = session.begintransaction();
  classd d=(classd)session.createcriteria(classd.class)
  .add(expression.eq("id",id))
  .setfetchmode("a",fetchmode.eager)
  .uniqueresult();
  classa a=d.geta();
  if(a instanceof classb)
  system.out.println(((classb)a).getb1());
  if(a instanceof classc)
  system.out.println(((classc)a).getc1());
  tx.commit();
  
  如果继承关系树的具体类对应一个表,为了表达classd与classa的多态关联,需要在table_d中定义两个字段:a_id和a_type,a_type字段表示子类的类型,a_id参照在子类对应的表中的主键。图14-12显示了表table_d、table_b和table_c的结构。
  
精通hibernate之映射继承关系七(图)(图二)

  
图14-12 表table_d、table_b和table_c的结构

扫描关注微信公众号