使用子类连接表中的外键映射hibernate多对一

时间:2013-07-31 11:28:25

标签: java hibernate

我使用 Hibernate 3 为我的项目映射了一些实体,并简单地解释了我有这样的事情:

  • Student实体( tstudent 表)
  • UniversityStudent实体( tuniversitystudent 表)
  • University实体( tuniversity 表)

UniversityStudentStudent延伸并具有自己的属性,就像大学本身一样,它是 tuniversitystudent 表中的外键。使用鉴别器字段,它也像子类一样映射到Student类:

<class name="mycompany.Student" table="tstudent" discriminator-value="BASIC">
    <id name="id" column="id" type="integer">
        <generator class="native" />
    </id>
    <discriminator column="type" />
    <property name="name" column="name" />
    <property name="surname" column="surname" />
    <property name="phoneNumber" column="phone_number" />
    <subclass discriminator-value="UNIVERSITY"
            name="mycompany.UniversityStudent">
        <join table="tuniversitystudent">
            <key column="id_student" />
            <many-to-one name="university" class="mycompany.University">
                <column name="id_university" />
            </many-to-one>
        </join>
    </subclass>
</class>

好吧,现在我希望每个Set都有一个UniversityStudent个实体和University个实体。所以我把它映射成:

<class name="mycompany.University" table="tuniversity">
    <id name="id" column="id" type="integer">
        <generator class="native" />
    </id>
    <property name="name" column="name" />
    <set name="universityStudents" table="tuniversitystudent">
        <key>
            <column name="id_university" />
        </key>
        <one-to-many class="mycompany.UniversityStudent" />
    </set>
</class>

当我想加载University对象时出现问题,Hibernate抱怨 tstudent 表中id_university不存在。我检查了生成的SQL查询,它确实尝试从 tstudent 加载它。

  

未知专栏&#39; student0_.id_university&#39;在&#39;字段列表&#39;

它似乎认识到它是基本Student的子类并尝试使用父表中的字段加入集合,但是该字段实际上在子表中,因为只有大学生可以分配大学。

我尝试了另一种似乎有效的解决方法,但它对我无效,将UniversityStudent映射为joined-subclass而不是subclass内部加入

<joined-subclass name="mycompany.UniversityStudent" table="tuniversitystudent">
    <key column="id_student" />
    <many-to-one name="university" class="mycompany.University">
        <column name="id_university" />
    </many-to-one>
</joined-subclass>

但是,我有兴趣将其保留为具有鉴别值的子类。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

我检查了一些资源,最后遇到了这个错误:https://hibernate.atlassian.net/browse/HHH-1015,看起来与你的情况完全兼容。结帐this old question as well,与您的情况非常相似。
我首先阅读了Hibernate给出的table per sublass的定义(我知道,它适用于版本3.3但我找不到Hibernate 4的相同来源):joined-subclass似乎(对我来说)是一个Hibernate提供的subclass using a discriminator的自定义实现,这是远离其使用的一个很好的理由。但是,据我所知,映射table per sublasstable per subclass using a discriminator应该是等价的,这就是为什么我相信我指出的错误仍然是开放的。

如果您有时间和意愿,您可以尝试使用其他JPA提供程序并检查您是否仍在同一问题中运行。 JPA 2.0 specifications是一个东西,提供者实现是另一个!我最近遇到了另一个错误(与@IdClass相关),这迫使我尝试使用EclipseLink并且使用Hibernate的配置是正确的Eclipse链接

答案 1 :(得分:1)

似乎你可以使用Custom SQL (or HQL) for loading。没有尝试过,但看起来,嗯,至少作为最后的手段,它提供了一个不错的解决方案。

在HBM中定义查询:

<sql-query name="universityStudents">
    <load-collection alias="unistu" role="University.universityStudents"/>
    SELECT unistu.*, student.*
    FROM tuniversitystudent unistu 
    JOIN tstudent student 
    ON unistu.id_student = student.id
    WHERE unistu.id_university = :id
</sql-query>

然后在University内使用它:

<set name="universityStudents" inverse="true">
    <key/>
    <one-to-many class="mycompany.UniversityStudent"/>
    <loader query-ref="universityStudents"/>
</set>