【问题标题】:uniqueness of composite id with null component具有空组件的复合 id 的唯一性
【发布时间】:2010-08-10 16:16:19
【问题描述】:

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

A.name  B.name
foo     NULL
foo     bar
foo     bar1
foo1    bar

应该不可能创建具有相同名称的新 A,只有当它具有不同的 B 时。 使用下面的约束可以创建

A.name B.name
foo    NULL
foo    NULL

因为 NULL 似乎对唯一性没有影响。

任何提示如何解决这个问题?

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

【问题讨论】:

  • 您使用的是哪些 RDBMS?
  • mysql,但这个问题的目的是在 grails 及其对域的约束中解决
  • null values int key component 会给您带来严重的麻烦:请考虑不允许在 key 组件中使用 null 值。认真:考虑不允许在关键组件中使用空值

标签: sql grails unique grails-orm constraints


【解决方案1】:

在数据库结构中,您能否将列设置为NOT NULL DEFAULT 0 或类似的值,然后像对待NULL 一样对待零?由于该列是用于名称的,因此值中可能没有数字,对吧?

【讨论】:

  • 一些(或至少一个,Oracle)RDBMS 将'' 视为null
  • 以上类定义在 SQL 中翻译成什么?我们可以看看表定义吗?
【解决方案2】:

我不完全确定,但我认为这会奏效:

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 调用是否会检索同一类中的属性。根据名称,它似乎应该这样做。

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

【讨论】:

  • 不,那行不通。仍然可以创建两个与 B 同名且为 NULL 的 As
猜你喜欢
  • 1970-01-01
  • 2021-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-19
  • 2015-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多