Grails-独特和无效

时间:2010-04-12 13:20:07

标签: grails gorm

alt text http://i41.tinypic.com/13ykqvb.png

这里DealerID可以为空,Car,轮胎是独一无二的。

我注意到的问题是: Grails在唯一约束中忽略空值。

4 个答案:

答案 0 :(得分:3)

我不认为这个问题很清楚,但这可能是Grails中的bug

答案 1 :(得分:2)

static constraints = {
  dealerID nullable:true;
  carID    unique:'dealerID', blank:false;
  tyreID   unique:'carID';
}


这不会按预期工作。这将使carID仅在dealerID范围内唯一。 tyreID在'carID'范围内是唯一的。这意味着当输入这个完全有效的行时验证将失败:

CarID      TyreID      DealerID
 01           02          NULL        Existing row
 01           02           95         New row is rejected 

这是因为TyreID不是唯一的 - 它与现有的CarID冲突。我们希望将唯一约束应用于所有指定字段的范围

据我所知,最新版本的Grails(1.3.7)

仍然存在这个问题

这是我的解决方法

在您的域类中,使用CriteriaBuilder为查找现有记录的字段编写自定义验证器:

class MyClass {
...
static constraints = {
...
carID( validator: { Integer carID,  MyClass thisInstance ->
                def existingRecord = MyClass.withCriteria(uniqueResult:true){
                    ne('id', thisInstance.id)
                    if (thisInstance.tyreID) {
                       eq('tyreID', thisInstance.tyreID)
                    }
                    else {
                       isNull('tyreID')
                    }
                    if (thisInstance.dealerID) {
                       eq('dealerID', thisInstance.dealerID)
                    }
                    else {
                       isNull('dealerID')
                    }
                })
                if (existingRecord) {
                    return ['myClass.duplicate', existingRecord.id]
                }
                else {
                    return true
                }
            }
        )

并在您的邮件属性中,您可以提醒用户此记录与特定记录冲突:

message.properties
...
myClass.duplicate = {0} is identical to existing record {3}

这是一个hacky解决方案,需要一个可能不必要的数据库命中,看起来很难看。我不喜欢它,但它有效。

答案 2 :(得分:0)

我知道这在游戏中已经晚了,但为了使组合独特,我会提出这样的约束:

static constraints = {
  dealerID nullable:true;
  carID    unique:'dealerID', blank:false;
  tyreID   unique:'carID';
}

这应该确保即使Grails忽略了由于dealerID为null而对carID的唯一约束,你也不会得到冲突的carID和tyreID的组合。 至少我认为这是有效的。

答案 3 :(得分:0)

这是一个古老的话题,但我认为无论如何我都会分享我可靠的解决方案。它使用了一个额外的列,因此它需要一点额外的存储空间,但保持性能的速度和没有可空的空间一样快。匹配您的示例,您添加/更改(假设您的ID是简单的字符串由于空白约束和简单):

 @foreach (var item in Model)
            {

  <div class="ratestar" id="abc" >

                            <input type="radio" name="example"  class="rating" value="1" />
                            <input type="radio" name="example" class="rating" value="2" />
                            <input type="radio" name="example" class="rating" value="3" />
                            <input type="radio" name="example" class="rating" value="4" />
                            <input type="radio" name="example" class="rating" value="5" />
                         </div>}

约束字段总是有一个值,当它与唯一性无关时,它不会妨碍你。