【问题标题】:Map hibernate many-to-one with the foreign key in subclass joined table与子类连接表中的外键映射休眠多对一
【发布时间】:2013-07-31 11:28:24
【问题描述】:

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

  • Student 实体(学生表)
  • UniversityStudent 实体(tuniversitystudent 表)
  • University 实体(大学表)

UniversityStudent 扩展自 Student 并具有自己的属性,例如大学本身,它是 tuniversitystudent 表的外键。它也像子类一样映射到 Student 类,使用 discriminator 字段:

<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 集合,其中每个 University 都有 UniversityStudent 实体。所以我这样映射它:

<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 加载它。

“字段列表”中的未知列“student0_.id_university”

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

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

<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>

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

【问题讨论】:

  • 你为什么一直使用 hbm.xml 文件?他们太乱了
  • 由于时间原因,并非每个遗留项目都可以移植到 JPA 注释。而且我在这里没有看到任何混乱。
  • 可能是个愚蠢的问题 - DB 中大学生记录的类型列是否具有“UNIVERSITY”?

标签: java hibernate


【解决方案1】:

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

如果您有时间并且愿意,您可以尝试使用另一个 JPA 提供程序并检查您是否仍然遇到相同的问题。 JPA 2.0 specifications 是一回事,提供者实现是另一回事!我最近遇到了另一个错误(与@IdClass 相关),它迫使我尝试EclipseLink,并且不适用于 Hibernate 的配置与 Eclipse Link 是正确的

【讨论】:

  • 您提供的链接实际上与我的问题非常相关。 @yair 为我提供了一种解决方法,但您的回复似乎确实解释了问题的根源。然而,一些海报谈论的是limitation,而不是bug。在阅读了 Hibernate 指南后,我真的不认为这应该被视为 limitation
  • 我在发布我的研究之前阅读了@yair 的答案,主要是因为我对Custom SQL for loading 感兴趣。我不知道这是一个错误还是一个限制,但不幸的是,正如您所读到的,它已在几年前发出信号,显然尚未在版本 4 中修复。使用 yair 的解决方案,它很干净!
【解决方案2】:

看来你可以使用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>

【讨论】:

  • @XtremeBiker 不知道。但如果my other answer 解决了问题,那么问题就解决了:)。
  • @XtremeBiker 太棒了!感谢您的编辑。我会试着再看看这个问题。
  • @XtremeBiker 似乎您的编辑被一些评论者拒绝了。我会添加你的变化。据我了解,您在父项和子项中的列出现了一些随之而来的问题,即它们的名称发生冲突。
  • @XtremeBiker OK 添加。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-02
  • 2018-05-29
  • 2014-07-21
  • 2013-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多