我有两个对象具有一对一和一对多的关系。

class GroupMember {
   /**
    * InvitationCode used to join this Group
    */
   InvitationCode invitationCode

   static constraints = {
      // group creator member object won't have used an invitation code
      invitationCode(nullable: true)
   }
}

class InvitationCode {
   /**
    * GroupMember who created the code, not used the code
    */
   GroupMember creator

   // I tried removing this, it has no effect.
   static hasMany = [members: GroupMember]
}

基本上,我有一个GroupMember,他拥有一个InvitationCode,并且可以使用另一个InvitationCode。或者,一个InvitationCode只能属于/由一个GroupMember创建,但可以被许多GroupMember使用/引用。

这些表看起来好像已正确设置-两个表都有另一个字段:INVITATION_CODE.CREATOR_IDGROUP_MEMBER.INVITATION_CODE_ID

但是,当我创建一个新的InvitationCode时,似乎GroupMember对象正在更新,并且invitationCodeId被设置为新创建的InvitationCodeid
GroupMember creator = new GroupMember(
   invitationCode: null // group creator - didn't use an invitation code
)
creator.save(flush: true)

InvitationCode invitationCode = new InvitationCode(
   creator: creator
)
invitationCode.save(flush: true)

GroupMember _creatorMember = GroupMember.findById(creator.id)
assert _creatorMember.invitationCode == invitationCode // true??

我从来没有设置creator.invitationCode,所以我不确定GORM如何/为什么设置它。我也不确定我在定义域时的错误。当我删除flush: true时,我对GroupMember.invitationCode违反了外键约束。

最佳答案

当前设置的问题是InvitationCode域对GroupMember域有2个引用,而grails错误地(在您的情况下)推断出:

  • invitationCodecreator彼此双向关联
  • members是与GroupMember
  • 的单向关联

    但实际上,您想要:
  • creator是与GroupMember
  • 的单向关联
  • members与反向引用invitationCode成多对一关系,使其成为双向关联

  • 可以理解,grails在“猜测”如何形成这种复杂的关系方面存在问题。

    关键将是 mappedBy 属性的使用。我已经成功地将其用于在相同的2个类上映射2个多对多关系,但没有一个像您需要的那样。我认为您需要的是在InvitationCode类中包含以下内容:
    static mappedBy = [
        members: 'invitationCode',
        creator: 'none' // because the relationship is unidirectional
    ]
    

    希望这对您有用!

    08-28 13:36