具有null组件的复合id的唯一性

时间:2010-08-10 16:16:20

标签: sql grails unique gorm constraints

我遇到了使用唯一约束的问题。 允许以下组合

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)
}

2 个答案:

答案 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调用是否将检索同一类中的属性。这基于它应该的名称。

我很想知道它是否适合你。