【问题标题】:Polymorphic belongsTo in many to many mapping in grails?grails中多对多映射中的多态属于To?
【发布时间】:2026-02-11 08:50:01
【问题描述】:

所以我知道使用超类可以做到这一点,但是,这在灵活性上非常有限。所以我的问题是,我可以使用界面吗?好东西。

interface Taggable {
  /*Adds tag(s) and returns a list of currently set tags*/
  List<String> addTags(String ... tag)
  /*Removes tag(s) and returns a list of currently set tags*/
  List<String> removeTags(String ... tag)
}

class User implements Taggable {
  String username
  static hasMany = [tags:Tag]
}

class Tag {
  String name

  static hasMany = [references:Taggable]
  static belongsTo = Taggable

  static constraints = {
    name(nullable: false, blank: false, unique: true)
  }
}

我对返回具有以下标记的对象的引用感兴趣。然而,这个对象不能扩展一个具体的类。这就是为什么我想知道这是否可以通过界面来完成。

那么,能做到吗?

【问题讨论】:

    标签: mysql hibernate grails groovy


    【解决方案1】:

    Hibernate 可以映射一个接口 - see example。我怀疑 Grails 是否在约定俗成的映射中支持这一点 - 但您可以尝试使用上面示例中的映射 annotations 或 XML 配置。

    编辑:回答评论问题:

    在数据库级别,您必须有一个 Taggable 表供 Tag.References 使用外键引用。

    1. 判别器不会破坏多态性,如果它是自动添加的 - 例如,在逐层表映射中,Hibernate/Gorm 添加一个class 字段以便在从数据库读取对象时找出具体类.

    2. 1234563

    顺便说一句,class 字段很长 - 它包含完全限定的类名

    编辑 2: 无论哪种方式,它都变得相当复杂,我个人会采用我建议的方法in another question

    • 动态查询所有带有Taggable接口的类hasMany=[tags:Tag]属性;
    • 或者,不太可取 - 拥有一个手工制作的子表和一个鉴别器。

    【讨论】:

    • 是的,你可能是对的,我认为我不能使用 grails gorm 映射来做到这一点。但是,在您的示例中,我似乎需要通过对特定类的引用向注释添加鉴别器,这确实在某种程度上违背了多态性的目的。并且还降低了Tag 实现的灵活性... 所以问题变成了,是否可以有一个没有鉴别器的任何映射,需要代码中的类引用?
    • XML 始终是一个选项,这样我们就不会在源代码中引用实现类...但是现在谁喜欢 XML?
    • 很抱歉没有提供 sn-p - 这将花费太长时间。只是一个尝试的原始想法。注释仍然可以工作,而且人们确实使用 XML——因为能够为不同的 DBMS 提供不同的映射。只需选择更适合特定情况的选项即可。
    • 一个附带问题:你说class 字段很长,我认为这是负面的吗?类字段本身是否有性能损失?这就是使用三个字母鉴别器的原因吗?是否可以对类字段进行索引或以任何方式对其进行优化? (加入表?)
    • 我只是想到了另一种可能的解决方案。也许借助 groovy 的强大功能,可以以编程方式添加数据库映射?伪代码:查找所有实现 Taggable 的域类。为Tag 类上的每个类添加一个@MetaValue。 (哦,顺便说一句,很抱歉把你的大脑选到这种程度:))