我有两个基本抽象类,还有多个来自这两个类的附加类,添加了其他属性等。
这些特定派生类型之间存在关系。
一个简单的说明示例:
Role
和Group
类为abstract
,但未标记为@MappedSuperclass
。
InheritanceType.JOINED
策略,因此两个表Role
(对于抽象类)和AdminRole
(对于派生类)应该存在(它们都将具有相同的{{1} })。
RoleID
有一个DiscussionGroup
属性,a
AdminRole
,Set<DiscussantRole>
Set<ManagerRole>
有WorkingGroup
,Set<WorkerRole>
Set<ManagerRole>
因为派生类的数量可以增长,并且因为派生自Role的类可以与派生自Group的不同类有关系(反之亦然),这将导致大量不同的映射表(Worker_DiscussionGroup,Worker_WorkingGroup)或多个外键列(在M:1关系中 - 例如,ManagerRole必须具有DiscussionGroupID和WorkingGroupId)。 我想通过一个公共映射表映射所有这些关系。
Role
|-- AdminRole
|-- DiscussantRole
|-- ManagerRole
|-- WorkerRole
Group
|-- DiscussionGroup
|-- WorkingGroup
我们使用 Hibernate在当前开发期间生成DDL架构(hbm2ddl.auto = create)(我们将使用静态架构定义供以后的生产使用)。 Hibernate会自动为关系创建外键,这对我们来说非常有用。
如果我指示它使用相同的映射表连接(对于多对多,多对多和一对一),它将尝试创建外来密钥。并且当然不可能同时在Role_Group (RoleID, GroupId)
从RoleID
到Role_Group
和AdminRole
创建外键,因此我收到错误。
有没有办法,如何指导Hibernate
生成没有外键的选定关系
或
定义关系应该基于摘要 祖先(即DiscussionGroup及其Set应该 被映射为1:N - 组和集)?
答案 0 :(得分:3)
以下作为问题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">
如Let Hibernate Connect Your World!中所述(参见页面来源 - 页面上未显示xml配置)
注意:强>
然而,这并不能解决整个问题。 Hibernate也无法通过此getAdmin
和getManagers
的映射表获取正确的数据,因为它查找Role_Group
,找到RoleIDs
DiscussionGroup
GroupID
并且不知道它是针对AdminRole
还是ManagerRole
并且给出了“没有给定标识符存在的行”错误“。
然后,当我在Group或DiscussionGroup中将此类表用作public Set<Role> getRoles()
时,相似的映射有效,Hibernate将成功地将派生类(AdminRole
,ManagerRole
)加载到Set。
答案 1 :(得分:1)
我认为你应该保留多个表格。它只是映射你的类中存在的关系。
如果您不希望这样,那么您可以在摘要Set<Role>
内定义Group
,在摘要Set<Group>
中定义Role
。你不会在子类中有任何“子集”;您只需使用正确类型的相应元素填充抽象类中的集合。然后,自动映射会为您提供一个单独的连接表。