我遇到了使用唯一约束的问题。 允许以下组合
A.name B.name
foo NULL
foo bar
foo bar1
foo1 bar
不应该创建具有相同名称的新A,只有它具有不同的B. 通过以下约束,可以创建
A.name B.name
foo NULL
foo NULL
因为NULL似乎对unique不起作用。
任何提示如何解决这个问题?
class A {
String name
static belongsTo = [b:B]
static constraints = {
name(unique:'b')
b(nullable:true)
}
}
class B {
String name
static hasMany = [as:A]
name(unique:true)
}
答案 0 :(得分:1)
在数据库结构中,您是否可以将列设置为NOT NULL DEFAULT 0
或类似,然后将零处理为与NULL相同的值?由于列是用于名称,因此值中可能没有数字吗?
答案 1 :(得分:1)
我不完全确定,但我认为这会奏效:
name(unique:['b', 'name'])
查看唯一约束的代码,似乎是可行的。约束肯定会让你传递一个事物列表来比较唯一性。它将此称为uniquenessGroup。然后,在验证时,它会遍历此列表。从第137行开始:http://www.docjar.com/html/api/org/codehaus/groovy/grails/orm/hibernate/validation/UniqueConstraint.java.html
代码如下所示:
if(shouldValidate) {
Criteria criteria = session.createCriteria( constraintOwningClass )
.add( Restrictions.eq( constraintPropertyName, propertyValue ) );
if( uniquenessGroup != null ) {
for( Iterator it = uniquenessGroup.iterator(); it.hasNext(); ) {
String propertyName = (String) it.next();
criteria.add(Restrictions.eq( propertyName,
GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue(target, propertyName)));
}
}
return criteria.list();
}
因此,它取决于GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue调用是否将检索同一类中的属性。这基于它应该的名称。
我很想知道它是否适合你。