与单个映射表的多个关系,而不会由Hibernate生成外键 [英] Multiple relationships with single mapping table without generating foreign keys by Hibernate

查看:181
本文介绍了与单个映射表的多个关系,而不会由Hibernate生成外键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

存在关系在这些具体的派生类型之间。

一个简单的示例:

Role Group 类是 abstract ,但它们未被标记为 @MappedSuperclass

InheritanceType.JOINED 策略正在使用,所以两个表角色(对于抽象类)和 AdminRole (对于派生类)应该存在(它们都具有相同的 RoleID
$ b


  • DiscussionGroup 有一个 AdminRole code> property,a
    Set< DiscussantRole> ,a Set< ManagerRole> li>
  • WorkingGroup has Set< WorkerRole> Set< ManagerRole>




  b $ b |  -  AdminRole 
| - DiscussantRole
| - ManagerRole
| - WorkerRole

Group
| - DiscussionGroup
| - WorkingGroup


因为派生类的数量可以增长,并且因为派生自角色的类可以与派生自组的不同类相关(反之亦然),这会导致大量的a不同映射表(Worker_DiscussionGroup,Worker_WorkingGroup)或多个外键列(以M:1关系 - 例如, ManagerRole必须拥有DiscussionGroupID和WorkingGroupId)。 我想通过一个公共映射表映射所有这些关系。

  Role_Group(RoleID,GroupId) 

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

如果我指示它使用相同的映射表来连接(对于多对多,多对多和一对一) ),它也会尝试创建外键。从 Role_Group AdminRole RoleID 上创建外键当然是不可能的 DiscussantRole ,所以我得到一个错误信息。

有什么办法,如何指示Hibernate


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




  2. 定义关系应该基于抽象
    祖先(即DiscussionGroup和它的Set应该
    被映射为1:N - Group和Set)?
    $ / $>

    解决方案

    以下作品为我提供了第二个问题的答案:

      @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()



    来源:



    根据资料来源,这是一个未公开的功能,可以在发行说明中看到:

     版本2.1.9(xx.x.xxxx)中的更改
    ---------------------------- --------
    *现在支持TimesTenDialect(查看TimesTenDialect的某些限制)
    * foreign-key =none可用于禁止生成外键。

    在xml config中 - 您可以像这样使用它$ /

     <多对一名称=医院列=hospitalIdproperty-ref =hospitalIdupdate =falseinsert =false外键= 无 > 

    让Hibernate连接你的世界!(请参阅页面源代码 - 页面上未显示xml配置)

    注意:

    然而,这并不能解决整个问题。对于 getAdmin getManagers ,Hibernate无法通过此映射表获取正确的数据,因为它看起来像 Role_Group ,找到 RoleIDs 用于 DiscussionGroup GroupID ,并且不知道它是否适用于 AdminRole ManagerRole 并给出 No但是当我在Group或DiscussionGroup中使用这样的表格作为 public时,类似映射就可以工作了设置< Role> getRoles(),Hibernate将成功加载派生类( AdminRole ManagerRole )到设置。


    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 one AdminRole property, a Set<DiscussantRole>, a Set<ManagerRole>
    • WorkingGroup has Set<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

    1. to generate selected relationships without foreign keys

      or

    2. 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)?

    解决方案

    Following works for me as an answer for question number 2:

    @ForeignKey( name = "none" )
    

    No foreign key is being generated for the relationship.

    @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()
    

    Sources:

    Based on the sources, it is an undocumented feature which was seen in release notes:

    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.
    

    In xml config - you would use it like this

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

    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 and getManagers as well, because it looks to Role_Group, finds RoleIDs for DiscussionGroup GroupID and has no idea if it is for AdminRole or ManagerRole 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.

    这篇关于与单个映射表的多个关系,而不会由Hibernate生成外键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆