共有四个类A,B,B1,B2,B1,B2继承B,A和B1,B2是<one-to-one>关系:代码如下(省略getter/setter): //A.java public class A{ private Integer id; private B1 b1; private B2 b2; }
//B.java public abstract class B{ private Integer id; private A a; }
//B1.java public class B1 extends B{ }
//B2.java public class B2 extends B{ }
hibernate映射文件为: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > <hibernate-mapping package="test">
<class name="A"> <id name="id"> <generator class="native"/> </id> <one-to-one name="b1" property-ref="a" cascade="all"/> <one-to-one name="b2" property-ref="a" cascade="all"/> </class>
<class name="B" discriminator-value="0"> <id name="id"> <generator class="native"></generator> </id> <discriminator type="integer" column="B_TYPE"/>
<!-- 以下的两个many-to-one居然不能在超类中声明 --> <!-- hibernate会抛出net.sf.hibernate.MappingException: --> <!-- property-ref not found: a in class: test.B1 --> <!-- 不知道算不算hibernate的一个不尽如人意的地方 --> <!-- 注意:many-to-one中并没有定义unique='true',否则insert 数据会失败,因为违反唯一索引 --> <subclass name="B1" discriminator-value="1"> <many-to-one name="a" column="a_id"/> </subclass>
<subclass name="B2" discriminator-value="2"> <many-to-one name="a" column="a_id"/> </subclass> </class>
</hibernate-mapping>
使用hibernate schemaupdate生成表,并插入以下结构的数据: 表:a id 1 表:b id B_TYPE a_id 1 1 1 2 2 1
然后select id=1的A对象,hibernate抛出一下异常: net.sf.hibernate.WrongClassException: Object with id: 1 was not of the specified subclass: test.B2 (loaded object was of wrong class) 似乎是hiberate把b表中id=1和id=2的两条记录当成一种对象(要么B1,要么B2)看待了,其实我觉得在这种情况下,hibernate完全 有能力(只需要在where语句中限制类型)区分我们的对象究竟是B1还是B2,不知道这算不算hibernate的一个bug?
解决方法: 方法1:把A对B1,B2的<one-to-one>关系拆分成对B的集合关系。 方法2:使用joined-subclass定义B1和B2,避免两种类型出现在同一表中 
|