Hibernate 无需生成外键即可使用单个映射表建立多个关系
我有两个基本抽象类,并且有多个从这两个抽象类派生的附加类,添加附加属性等。
这些特定的派生类型之间存在关系。
一个简单的说明示例:
Role
和 Group
类是 abstract
,但它们没有标记为 @映射的超类
。
正在使用 InheritanceType.JOINED
策略,因此表 Role
(对于抽象类)和 AdminRole
(对于派生类)都应该存在(它们都将具有相同的RoleID
)。
DiscussionGroup
有一个AdminRole
属性,一个Set
,Set
WorkingGroup
有Set
,Set<经理角色>
<前><代码>角色 |-- 管理员角色 |-- 讨论者角色 |-- 经理角色 |-- 工人角色 团体 |-- 讨论组 |-- 工作组
因为派生类的数量可能会增长,并且因为从 Role 派生的类可以与从 Group 派生的不同类有关系(反之亦然),这将导致大量不同的映射表(Worker_DiscussionGroup、Worker_WorkingGroup)或多个外键列(在 M:1 关系中 - 例如 ManagerRole 必须具有 DiscussionGroupID 和workingGroupId)。 我想通过一个通用映射表来映射所有这些关系。
Role_Group (RoleID, GroupId)
在当前开发过程中,我们使用Hibernate 生成 DDL 架构 (hbm2ddl.auto=create)(我们将使用静态模式定义供以后生产使用)。 Hibernate 会自动为关系创建外键,这对我们来说非常好。
如果我指示它使用相同的映射表进行连接(对于多对多、多对多以及一对一),它将尝试创建外键也是如此。当然,不可能在从 Role_Group
到 AdminRole
和 DiscussantRole
的 RoleID
上创建外键同时,所以我收到错误。
有什么方法,如何指示 Hibernate
在没有外键的情况下生成选定的关系
或
定义关系应基于抽象 祖先(即 DiscussionGroup 及其 Set 应该 映射为 1:N - 组和集合)?
I have two base abstract classes and there are multiple additional classes derived from these two, adding additional attributes etc.
There exist relations between those specific derived types.
A simple illustrating example:
Role
and Group
classes are abstract
, but they are not marked as @MappedSuperclass
.
InheritanceType.JOINED
strategy is being used, so both tables Role
(for abstract class) and AdminRole
(for derived class) should exist (they both will have the same RoleID
).
DiscussionGroup
has oneAdminRole
property, aSet<DiscussantRole>
, aSet<ManagerRole>
WorkingGroup
hasSet<WorkerRole>
,Set<ManagerRole>
Role |-- AdminRole |-- DiscussantRole |-- ManagerRole |-- WorkerRole Group |-- DiscussionGroup |-- WorkingGroup
Because the number of derived classes can grow, and because classes derived from Role can have relations to different classes derived from Group (and vice versa) this would lead to a large amount of different mapping tables (Worker_DiscussionGroup, Worker_WorkingGroup) or multiple foreign key columns (in M:1 relationships - e.g. a ManagerRole would have to have DiscussionGroupID and WorkingGroupId). I want to map all these relations through one common mapping table.
Role_Group (RoleID, GroupId)
We use Hibernate to generate the DDL schema (hbm2ddl.auto=create) during current development (we will use a static schema definition for later production use). Hibernate automatically creates Foreign keys for the relations, and thats quite good for us.
If I instruct it to use the same mapping a table for joins (for the many-to-many, many-to-many and for one-to-one as well), it will try to create foreign keys as well. And it is of course not possible to create a foreign key on RoleID
from Role_Group
to AdminRole
and DiscussantRole
at the same time, so I get an error.
Is there any way, how to instruct Hibernate
to generate selected relationships without foreign keys
or
to define that the relation should be based on the abstract
ancestors (i.e. DiscussionGroup and its Set should
be mapped as 1:N - Group and Set)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
以下对我来说是问题 2 的答案:
没有为该关系生成外键。
来源:
根据来源,这是一个未记录的功能,可以在发行说明中看到:
在 xml 配置中 - 您可以像
让 Hibernate 连接您的世界!(请参阅页面源 - 页面上未显示 xml 配置)
注意:
但这并不能解决整个问题。 Hibernate 也无法通过此映射表为
getAdmin
和getManagers
获取正确的数据,因为它会查找Role_Group
,找到RoleIDs< /code> for
DiscussionGroup
GroupID
并且不知道它是用于AdminRole
还是ManagerRole
并给出“ 没有给定的行标识符存在“错误”,但是当我在 Group 或 DiscussionGroup 中使用此类表作为
public SetgetRoles()
时,Hibernate 将成功加载派生类 (AdminRole
、ManagerRole
)到集合。Following works for me as an answer for question number 2:
No foreign key is being generated for the relationship.
Sources:
Based on the sources, it is an undocumented feature which was seen in release notes:
In xml config - you would use it like this
as mentioned in Let Hibernate Connect Your World! (see the page sources - xml configuration is not shown on the page)
Note:
This does not solve the whole problem however. Hibernate cannot get the right data through this mapping table for
getAdmin
andgetManagers
as well, because it looks toRole_Group
, findsRoleIDs
forDiscussionGroup
GroupID
and has no idea if it is forAdminRole
orManagerRole
and gives "No row with the given identifier exists" error".Simimilar mapping works however when I use such table in Group or DiscussionGroup as
public Set<Role> getRoles()
, Hibernate will successfully load derived classes (AdminRole
,ManagerRole
) to the Set.我认为你应该保留多张桌子。它只是映射类中存在的关系。
如果您不希望这样,那么您可以在抽象
Group
中定义一个Set
并在抽象Group
中定义一个Set
>角色。子类中不会有任何“子集”;您只需使用正确类型的适当元素填充抽象类中的集合即可。然后,自动映射将为您提供您想要的单个连接表。I think that you should keep multiple tables. It just maps the relationship that exists in your classes.
If you don't want that then you could define a
Set<Role>
inside abstractGroup
and aSet<Group>
in abstractRole
. You would not have any "subsets" in the subclasses; you just fill the set from the abstract class with the appropriate elements of the right type. The automatic mapping would then give you a single join table like you want.