【问题标题】:Hibernate ManyToMany and superclass mapping problemHibernate ManyToMany和超类映射问题
【发布时间】:2010-05-27 16:41:47
【问题描述】:

我需要在 Hibernate 中创建一个关系,链接三个表:Survey、User 和 Group。 调查可以对用户或组可见,并且组是由多个用户组成的。

我的想法是为用户和组创建一个超类,并在该超类和调查之间创建多对多关系。

我的问题是 Group 不是映射到表,而是映射到视图,因此我无法将 Group 的字段拆分到多个表中——如果我创建了一个公共超类就会发生这种情况。

我想过创建一个通用接口,但不允许映射到它们。 我可能最终会采用两种关系解决方案(Survey-User 和 Survey-Group),但我不太喜欢这种方法。

我也想过创建一个如下所示的表格:

  Survey Id  |  ElementId  | Type

ElementId 将是 Group 或 UserId,并且类型...它的类型。 有谁知道如何使用休眠注释来实现它?还有其他想法吗?

非常感谢

【问题讨论】:

    标签: java hibernate annotations


    【解决方案1】:

    我昨天发布了一个非常similar answer。总而言之,您不能使用映射的超类,因为映射的超类不是实体并且不能成为关联的一部分(这是您想要的),但是您可以使用带有 TABLE_PER_CLASS 继承策略的抽象实体来获得类似的结果。

    类似这样的东西(未测试):

    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class AbstractEntity {
        @Id @GeneratedValue(strategy = GenerationType.TABLE)
        private Long id;
    
        @ManyToMany(mappedBy="entities")
        private Set<Survey> surveys = new HashSet<Survey>();
        ...
    
    }
    
    @Entity
    public class User extends AbstractEntity {
        ...
    }
    
    @Entity
    public class Group extends AbstractEntity {
        ...
    }
    
    @Entity
    public class Survey {
        @Id @GeneratedValue
        private Long id;
    
        @ManyToMany
        private Set<AbstractEntity> entities = new HashSet<AbstractEntity>();
    
        ...
    }
    

    参考文献

    【讨论】:

    • 据我所见,这种方法似乎行不通,因为您无法控制视图,两行(一行在组中,另一行在用户中)可能碰巧有相同的 id,因此无法保证 id 的唯一性。使用这种方法,id 必须在多个表之间共享,这对于视图是不可能的(它可能是从您无法控制的另一个模式中的表中获取的)。您将如何将调查与元素联系起来??
    • @Juan 确实,但我希望在视图上可以加入(也许 OP 应该澄清这一点)。我会考虑的。
    • Juan Carlos 是对的,我完全无法控制视图。还有一些我忘了提:表已经填充,所以如果我更改模型,我将不得不创建并运行一些数据库脚本来更新数据,如果可能的话我想避免它。因为它,我提到了调查 ID |元素 ID |类型方法。如果将鉴别器值(类型)添加到多对多关系中,我的问题将得到解决。但是找不到方法
    【解决方案2】:

    您可以使用每个具体类继承策略的表,hibernate 将复制每个子类的所有属性,这将适用于视图。

    我还建议用户/组的复合模式(接近您的第一个选项)。

    http://en.wikipedia.org/wiki/Composite_pattern

    【讨论】:

    • 据我所见,这种方法似乎行不通,因为您无法控制视图,两行(一行在组中,另一行在用户中)可能碰巧有相同的 id,因此无法保证 id 的唯一性。使用这种方法,id 必须在多个表之间共享,这是视图无法实现的(它可能是从您无法控制的另一个模式中的表中获取的)。您将如何将调查与元素联系起来??
    • @Juan 这是 OP 必须澄清的事情。如果您确实无法控制视图,因为您也不负责编写实体,因此无法保证 id 唯一性,您仍然可以通过将 id 映射到您知道的代理逻辑键来使用每个具体类的表唯一的(例如组/用户名)。
    • 这可能是一个好方法,问题是表中存在现有数据,并且模型基于预先存在的键,如果我更改它们,一切都会中断:S
    • @Jesus 如果您无法控制视图或映射视图的 java bean 模型,除了您提到的解决方案之外,我看不到任何其他解决方案。
    • 是的,可能是我想多了,我没有太多选择,所以即使我不太喜欢它,我也必须选择那个解决方案。非常感谢!
    【解决方案3】:

    这是可能的。这种“继承属性”方法可以通过将超类定义为MappedSuperclass 来实现。

    编辑:

    section 2.2.4 in the hibernate annotations reference doc 中还列出了一些替代方案,第 2.2.4.4 节涵盖了 MappedSuperclass。

    【讨论】:

      猜你喜欢
      • 2011-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-13
      • 2018-02-24
      • 1970-01-01
      • 2011-07-31
      • 2021-10-24
      相关资源
      最近更新 更多