2

我有两个基本抽象类,并且有多个从这两个派生的附加类,添加附加属性等。

这些特定的派生类型之间存在关系。

一个简单的说明示例:

RoleGroup类是abstract,但它们没有标记为@MappedSuperclass

InheritanceType.JOINED正在使用策略,因此表Role(对于抽象类)和AdminRole(对于派生类)都应该存在(它们都将具有相同的RoleID)。

  • DiscussionGroup有一个AdminRole属性, a Set<DiscussantRole>, aSet<ManagerRole>
  • WorkingGroupSet<WorkerRole>Set<ManagerRole>
Role 
|-- AdminRole
|-- DiscussantRole
|-- ManagerRole
|-- WorkerRole

Group
|-- DiscussionGroup
|-- WorkingGroup

因为派生类的数量可以增长,并且因为派生自 Role 的类可以与派生自 Group 的不同类有关系(反之亦然),这将导致大量不同的映射表(Worker_DiscussionGroup、Worker_WorkingGroup)或多个外键列(在 M:1 关系中 - 例如,ManagerRole 必须具有 DiscussionGroupID 和 WorkingGroupId)。我想通过一个通用映射表来映射所有这些关系。

Role_Group (RoleID, GroupId)

在当前开发过程中,我们使用Hibernate 生成 DDL 模式 (hbm2ddl.auto=create)(我们将使用静态模式定义供以后的生产使用)。Hibernate 自动为关系创建外键,这对我们来说非常好。

如果我指示它使用相同的映射表进行连接(对于多对多、多对多和一对一),它也会尝试创建外键。当然不可能同时在 from to 上创建外键,RoleID所以Role_Group我得到一个错误。AdminRoleDiscussantRole

有什么办法,如何指示Hibernate

  1. 生成没有外键的选定关系

    或者

  2. 定义关系应该基于抽象祖先(即 DiscussionGroup 及其 Set 应该映射为 1:N - Group and Set)?

4

2 回答 2

4

以下对我来说是问题 2 的答案:

@ForeignKey( name = "none" )

没有为关系生成外键。

@Cascade( value = { CascadeType.ALL } )
@OneToOne( fetch = FetchType.EAGER, orphanRemoval = true )
@JoinTable( name = "Role_Group",
            inverseJoinColumns = { @JoinColumn( referencedColumnName = "rolleId", name = "RolleID" ) },
            joinColumns = { @JoinColumn( referencedColumnName = "groupId", name = "GroupID" ) } )

@ForeignKey( name = "none" )
public AdminRole getAdmin()

资料来源:

根据消息来源,这是一个未记录的功能,在发行说明中可以看到:

Changes in version 2.1.9 (xx.x.xxxx)
------------------------------------
* TimesTenDialect now supported (look at TimesTenDialect for certain limitations)
* foreign-key="none" can be used to disable generation of a foreign key.

在 xml 配置中 - 你会像这样使用它

<many-to-one name="Hospital" column="hospitalId" property-ref="hospitalId" update="false" insert="false" foreign-key="none">

让 Hibernate 连接您的世界中所述!(请参阅页面来源 - 页面上未显示 xml 配置)

笔记:

然而,这并不能解决整个问题。Hibernate 也无法通过此映射表获取正确的数据 for and getAdmingetManagers因为它查找Role_Group、查找并且不知道它是否为or并给出“ No row with the given identifier exists”错误“。RoleIDsDiscussionGroup GroupIDAdminRoleManagerRole

但是,当我在 Group 或 DiscussionGroup as 中使用此类表时,类似的映射有效public Set<Role> getRoles(),Hibernate 将成功地将派生类 ( AdminRole, ManagerRole) 加载到 Set 中。

于 2011-09-06T12:32:32.107 回答
1

我认为你应该保留多张桌子。它只是映射您的类中存在的关系。

如果你不想这样,那么你可以定义一个Set<Role>inside abstractGroup和一个Set<Group>in abstract Role。子类中不会有任何“子集”;您只需使用正确类型的适当元素填充抽象类中的集合。然后,自动映射将为您提供您想要的单个连接表。

于 2011-09-06T01:36:22.353 回答