【发布时间】:2010-05-03 01:10:38
【问题描述】:
我有一个结构,其中主表是 USER,其他表包括 CATEGORY(包含 user_id)。
在标准逆向工程程序之后我得到的是:
- User 类包含一个类别的集合,
- 类别 Category 不包含外键 (user_id),但包含 User 对象。
为什么它不包含作为类属性的外键?
如果没有胶水,我如何在 HQL 中连接这两个表? HQL - 请解释这部分。
【问题讨论】:
我有一个结构,其中主表是 USER,其他表包括 CATEGORY(包含 user_id)。
在标准逆向工程程序之后我得到的是:
为什么它不包含作为类属性的外键?
如果没有胶水,我如何在 HQL 中连接这两个表? HQL - 请解释这部分。
【问题讨论】:
为什么它不包含作为类属性的外键?
因为 Hibernate 是一个对象-关系映射工具,Hibernate 允许使用对象模型(即对象和对象之间的关系)并将它们映射到数据库表示(表的数据行)。 Hibernate 的全部意义在于弥合面向对象范式和关系范式(著名的Object-Relational Impedance Mismatch)之间的差距。在您的情况下,以下对象模型是预期的(和正确的)对象表示:
alt text http://img251.imageshack.us/img251/6335/110b578b.png
如果没有胶水,我如何在 HQL 中连接这两个表?
胶水在那里,但你必须考虑对象(和关联)。例如(见14.3. Associations and joins):
from Category as category join category.user as user
请注意,HQL 支持两种形式的关联加入:implicit 和 explicit(请参阅 14.4. Forms of join syntax)。上面的示例使用 explicit 连接。 implicit 表单不使用 join 关键字,而是使用点符号:
from Category category where category.user.id =: id
【讨论】:
在这种情况下,Hibernate 会自动为您处理外键。在 Java 方面,您不需要考虑外键,而是聚合。这就是为什么Category 包含一个(引用一个)User 对象,而不是一个 FK。类Category 的user 属性与USER 表中的FK 列之间的绑定在Hibernate 映射中指定。
如果您随后使用这些类创建 Criteria 或 Query,Hibernate 将使用适当的 FK 自动生成 SQL 查询。我没有使用 HQL 的经验,但我很确定 Hibernate 也能正确处理。
更新: HQL 示例:
from Category as category inner join fetch category.user as user
示例改编自here。
有关映射的更多详细信息,请参阅Hibernate Reference, chapters 5 至 7。
【讨论】:
User 对象 和 FK 将是重复的,需要更多同步并为错误打开更多可能性。此外,PK 和 FK 通常(应该)是数据库私有的(这是 Hibernate 中的建议)。
我同意 Péter Török 的观点:当前的休眠行为是预期的。
例如,当你更新一个你修改了用户而不是原始 FK 的 Category 时,hibernate 应该做什么?
为什么需要原始 FK ?你只需要做 category.getUser().getId();可以访问它,而不会冒在 Category 对象中出现不一致状态的风险。
【讨论】: