在将现有应用程序从Grails 2.5迁移到3.1时,我遇到了一个双向一对一关系的奇怪问题。
想象一下带有User和Employee
对象的简单模型。 User
表示通用用户帐户。并非所有用户都是员工,但所有员工都是用户。此外,员工还可以参考经理,主管等(也是用户实例)。用户是这段关系的拥有者。
class User {
Employee employee
static mappedBy = [employee: "user"]
static hasOne = [employee: Employee]
static constraints = {
employee(nullable:true)
}
}
class Employee {
User user // represents employee's own account, a bi-directional one-to-one
User supervisor // represents a supervisor
static belongsTo = [user: User]
static constraints = {
user(unique:true)
supervisor(nullable:true)
}
}
升级到Grails 3之后的问题是,在创建模式下,这会导致员工表的supervisor_id
列生成为NOT NULL
,而在Grails 2中,它可以按预期为空(仅限于user_id为NOT NULL)。
我用Grails 3.1.12和3.2.0对此进行了测试,两者都有相同的行为。我在域类声明中做了什么愚蠢的事吗?我已经尝试了多次映射来实现与Grails 2.5相同的行为而没有运气。在某些情况下,我甚至会在关系的两边获得一把外键......
答案 0 :(得分:0)
我不知道为什么你的代码与以前版本的Grails一起使用,但这是错误的。
当您使用hasMany和belongsTo时,没有必要在子对象中定义其他属性,并且您也不需要在父对象上使用mappedBy属性,并且与父对象(属性员工)相同在用户)
Grails并不需要任何其他知道两个clases上的双向属性,以及user(unique : true)
的约束{/ p>}。
所以你的课程应该是这样的:
class User {
static hasOne = [employee: Employee]
static constraints = {
employee(nullable: true)
}
}
class Employee {
User supervisor // represents a supervisor
static belongsTo = [user: User]
static constraints = {
supervisor(nullable:true)
}
}
知道你的数据库结构如何可能会很好。但是这样所有foreigns键都存储在employee表中。但是当然你可以从两个实体导航。如果您具有不同的结构,则可以使用此模型映射当前数据库。见this
employee.user
user.employee