使用相同的数据透视表对具有子类的多对多进行休眠

时间:2013-07-09 07:44:50

标签: java hibernate

拥有此模型架构:

Person
    |__ Student
            |__ SchoolBoy
            |__ CollegeStudent

我正在使用Hibernate 3.6,并且使用 tperson 表为所有类使用了一个鉴别器列。我的映射是这样完成的:

<class name="Person" table="tperson" discriminator-value="PERSON">
    <id name="Id" column="id" type="integer">
        <generator class="increment" />
    </id>
    <discriminator column="person_type" />
    <subclass name="Student" discriminator-value="STUDENT">
        <key column="id_person" />
        <subclass name="SchoolBoy" discriminator-value="SCHOOL_BOY">
            <join table="tstudent">
                <key column="id_person" />
            </join>
        </subclass>
        <subclass name="CollegeStudent" discriminator-value="COLLEGE_STUDENT">
            <join table="tstudent">
                <key column="id_person" />
            </join>
        </subclass>
    </subclass>
</class>

现在我想介绍课程实体,实现课程与学生之间的关系。当然,这是一种多对多的关系。假设我使用名为tstudent_course的数据透视表,其中包含 SchoolBoy CollegeStudent 两种类型的学生。该表包含对该人本身及其正在学习的课程的参考。

现在,我希望在加载课程实体时,大学生和学生之间会有所不同。我这样做:

<set name="CollegeStudents" table="tstudent_course"
            inverse="true">
    <key>
        <column name="id_course" not-null="true" />
    </key>
    <many-to-many entity-name="CollegeStudent">
        <column name="id_person" not-null="true" />
    </many-to-many>
</set>

<set name="SchoolStudents" table="tstudent_course"
            inverse="true">
    <key>
        <column name="id_course" not-null="true" />
    </key>
    <many-to-many entity-name="SchoolBoy">
        <column name="id_person" not-null="true" />
    </many-to-many>
</set>

但是,作为数据透视表的一个表,其中包含对每种类型学生的引用,它会尝试加载我的集合中的每个学生,然后我收到下一个异常:

Object with id: 2 was not of the specified subclass: 
   CollegeStudent (loaded object was of wrong class class SchoolBoy)

似乎Hibernate正在进行连接而没有评估我的学生的具体类型,并试图在我的大学生系列中注入一个SchoolBoy。

我可以做些什么来避免这种情况?是否有可能在数据透视表中建立一种歧视?或者我是否必须为每种子类创建特定的数据透视表?

1 个答案:

答案 0 :(得分:2)

在您的设置中,您可以添加过滤器:

<set name="CollegeStudents" table="tstudent_course"
            inverse="true">
    <key>
        <column name="id_course" not-null="true" />
    </key>
    <many-to-many entity-name="CollegeStudent" where="person_type='COLLEGE_STUDENT'">
        <column name="id_person" not-null="true" />
    </many-to-many>
</set>

恕我直言,没有那个过滤器(只是一组所有学生),映射会更好。