2010-08-10 66 views
1

我遇到了使用唯一約束的問題。 以下組合被允許具有空分量的複合標識的唯一性

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

您正在使用哪個RDBMS? – 2010-08-10 17:33:00

+0

mysql,但問題在grails中要解決的問題及其對域名的約束 – skurt 2010-08-10 18:47:37

+0

null值int關鍵組件可能會導致嚴重的麻煩:請考慮不允許在關鍵組件中使用空值。認真:考慮不允許在關鍵組件中使用空值 – Sammyrulez 2010-08-11 07:08:02

回答

1

在數據庫結構,你可以設置列NOT NULL DEFAULT 0或類似的,然後把零點和你一樣,否則會的NULL?由於該列是用於名稱的,因此值中可能沒有數字?

+0

爲什麼0而不是'' – 2010-08-10 16:48:29

+0

某些(或至少一個Oracle)RDBMS將''''視爲'null'。 – 2010-08-10 17:33:48

+0

上面的類定義在SQL中轉換爲什麼?我們能否看到表格定義? – 2010-08-10 17:37:49

1

我不能完全肯定,但我認爲這會工作:

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

在爲唯一約束的代碼看,它似乎是可行的。約束條件絕對允許你傳遞一系列事物來比較唯一性。它稱這是唯一性組。然後,在驗證時,它遍歷這個列表。看看在開始這裏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調用是否會在同一類檢索屬性。基於它的名字應該是這樣。

我很想知道它是否適用於您。

+0

沒有不行。仍然可以使用與B相同的名稱和NULL創建兩個As – skurt 2010-08-11 14:12:03

相關問題