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

发布于 2024-09-13 17:20:31 字数 510 浏览 8 评论 0 原文

我在使用独特的约束时遇到了问题。 允许以下组合

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

I am running into problems using unique constraints.
The following combinations are allowed

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

It should not be possible to create a new A with same name, only if it has a different B.
With the constraints below it is possible to create

A.name B.name
foo    NULL
foo    NULL

Because NULL seems not to have effect on unique.

Any hints how to fix this?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

还如梦归 2024-09-20 17:20:31

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

In the database structure, could you set the columns to NOT NULL DEFAULT 0 or similar, and then treat the zeros the same as you otherwise would the NULLs? Since the column is for names, there's likely to be no digits in the values anyway right?

紫罗兰の梦幻 2024-09-20 17:20:31

我不完全确定,但我认为这会起作用:

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 调用是否将检索同一类中的属性。从名字来看,它似乎应该是这样。

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

I'm not entirely sure, but I think this will work:

name(unique:['b', 'name'])

Looking at the code for the unique constraint, it seems feasible. The constraint definitely lets you pass in a list of things to compare the uniqueness to. It calls this the uniquenessGroup. Then, when validating, it iterates over this list. Take a look starting at line 137 here: http://www.docjar.com/html/api/org/codehaus/groovy/grails/orm/hibernate/validation/UniqueConstraint.java.html

The code looks like this:

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

So it depends on whether the GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue call will retrieve a property in the same class. Which based on the name it seems like it should.

I'm curious to know if it works for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文