Hibernate兑现双向一对一关系,很黄很暴力的方法

Hibernate实现双向一对一关系,很黄很暴力的方法
3张表
A表 AID(主键)  bID   cID其他属性略。。。
B表 BID(主键)  aID   cID其他属性略。。。
C表 CID(主键)  aID   bID其他属性略。。。  有点类似关联的表,但又不是

数据库里未设外键
暂且不讨论这张表设计的好坏(数据库表已经设计好了,改动表结构按目前项目来说有点复杂)
hibernate是工具,是拿来用的,所以在项目中是它适应项目,不是项目去适应他。
如果一个项目被工具所累,那是非常糟糕的事情。

主键是通过hibernate自动生成UUID
在A表中,如果它和B表没有关系,则bID设置为-1
因此要求:
能通过任意一张表对其他表一起来查询
但不能相互修改

通常PO中是这样的
public class A {    
  private String aID;    
  private B b;
  private C c;    
  ...
  public void setAID(String aID); {   
    this.aID = aID;   
  }     
  public void setB(B b); {   
    this.b = b;   
  }
  public void setC(C c); {   
    this.c = c;   
  }      
  public String getAID(); {   
    return aID;   
  }     
  public B getB(); {    
    return b;   
  }  
  public C getC(); {    
    return c;   
  }
  ...    
}    


public class B {    
  private String bID;    
  private A a;
  private C c;    
  ...
  public void setBID(String bID); {   
    this.bID = bID;   
  }     
  public void setA(A a); {   
    this.a = a;   
  }
  public void setC(C c); {   
    this.c = c;   
  }      
  public String getBID(); {   
    return aID;   
  }     
  public A getA(); {    
    return b;   
  }  
  public C getC(); {    
    return c;   
  }
  ...    
}  


配置文件里如下
<hibernate-mapping>
    <class name="com.pojo.A" table="A">
        <id name="aID" type="java.lang.String">
            <column name="AID" length="32" />
            <generator class="assigned" />
        </id>
        ...
        <one-to-one name="b" class="com.pojo.B" 
        	property-ref="a" />
     </class>
</hibernate-mapping>


<hibernate-mapping>
    <class name="com.pojo.B" table="B">
        <id name="bID" type="java.lang.String">
            <column name="BID" length="32" />
            <generator class="assigned" />
        </id>
        ...
        <many-to-one name="a" class="com.A" fetch="select"
        	column="aID" cascade="none" unique="true" />
     </class>
</hibernate-mapping>

但是这样设计的话,如果要对表A解除和表B的关联,同时把表A中的bID设置为-1,必定要通过B对象的实体进行操作,但问题是实体B中的BID由UUID自动生成了,这样会产生类型错误

所以我对B.hbm.xml进行了修改
<hibernate-mapping>
    <class name="com.pojo.B" table="B">
        <id name="bID" type="java.lang.String">
            <column name="BID" length="32" />
            <generator class="assigned" />
        </id>
        ...
        <many-to-one name="a" class="com.A" fetch="select"
        	column="aID" cascade="none" unique="true" update="false" insert="false" />
     </class>
</hibernate-mapping>


update,insert:指定对应的字段是否在用于UPDATE 和/或 INSERT的SQL语句中包含。如果二者都是false,则这是一个纯粹的“外源性(derived)”关联,它的值是通过映射到同一个(或多个)字段的某些其他属性得到的,或者通过trigger(除法器),或者是其他程序(可选 - 默认为 true)

这里加入update="false" insert="false"。打个比方,对表A进行修改和插入,不会对A表中的bID字段进行影响,具体你可以查看HQL语句。
但是这里我们要对A表的bID进行修改,而这样设置的话,bID是无法修改的

===============================
想了N种解决方案,也尝试了N种,都不是很满意,最后的方法可能会让您很吃惊,这也是我说很黄很暴力的原因Hibernate兑现双向一对一关系,很黄很暴力的方法
PO修改如下
public class A {    
  private String aID;    
  private B b;
  private C c; 
  private String bID; 
  private String cID;  
  ...
  public void setAID(String aID); {   
    this.aID = aID;   
  }     
  public void setB(B b); {   
    this.b = b;   
  }
  public void setC(C c); {   
    this.c = c;   
  }      
  public String getAID(); {   
    return aID;   
  }     
  public B getB(); {    
    return b;   
  }  
  public C getC(); {    
    return c;   
  }

  public void setBID(String bID); {   
    this.bID = bID;   
  }      
  public String getBID(); {   
    return bID;   
  }    
  public void setCID(String cID); {   
    this.cID = cID;   
  }      
  public String getCID(); {   
    return cID;   
  }  
  ...    
}   

B.java省略

配置文件修改如下
<hibernate-mapping>
    <class name="com.pojo.A" table="A">
        <id name="aID" type="java.lang.String">
            <column name="AID" length="32" />
            <generator class="assigned" />
        </id>
        ...
        <property name="bID" type="java.lang.String">
            <column name="bID" length="32" />
        </property>
        <property name="cID" type="java.lang.String">
            <column name="cID" length="32" />
        </property>
        <one-to-one name="b" class="com.pojo.B" 
        	property-ref="a" />
     </class>
</hibernate-mapping>

这样的话,要对A表中的bID进行操作的话,就不用通过B实体对象进行操作了。
而且也符合预先的所有要求,查可以通过可自对象互相关联,各自删改,不会对其他表产生影响
1 楼 ariestiger 2009-11-25  
老实说,没怎么看懂,搞这么复杂?你就是添加了几个冗余字段吧?晕
2 楼 卡拉阿风 2009-11-26  
ariestiger 写道
老实说,没怎么看懂,搞这么复杂?你就是添加了几个冗余字段吧?晕

数据库未变。所以没有冗余字段一说。只是PO和配置上稍微改变了下。可以级联操作也可以不级联。