2013-08-17 2 views
0

У меня есть приложение Grails с кучей классов домена, некоторые из которых содержат много полей, некоторые из которых имеют отношение hasMany к рассматриваемому классу домена. Для этого конкретного приложения у меня есть только одно «ограничение», то есть каждый экземпляр каждого класса домена должен быть уникальным. Меня не волнует, имеет ли произвольное поле одно и то же значение для нескольких экземпляров одного и того же класса домена, если каждый экземпляр уникален значением какого-либо другого поля в этом классе домена. Поэтому в основном я хочу, чтобы проверка выполнялась на уровне экземпляра класса домена вместо уровня поля класса домена. Прямо сейчас я делаю это, используя очень сложную аннотацию @EqualsAndHashCode для генерации методов equals и hashCode, а затем вызываю equals в пользовательском валидаторе в произвольном поле класса домена.Проверка экземпляра класса домена уникальна

Два вопроса:

  1. есть более эффективный способ проверки класса домен уникален?
  2. Если нет, то есть способ, которым я могу вызвать свой собственный код валидатора в самом экземпляре класса домена вместо того, чтобы проходить через одно из полей экземпляра класса домена?
 
@groovy.transform.EqualsAndHashCode 
class MyDomainClass { 
    String some 
    int arbitrary 
    boolean field 
    static constraints = { 
     // The field I chose to validate on is irrelivant, I just need to run the validation code **somewhere** 
     arbitrary validator: { val, obj -> 
      return !MyDomainClass.getAll().contains(obj) 
     } 
    } 
} 

Я должен также добавить, что я ищу родового (надеюсь) эффективного способа сделать это. Я понимаю, что вызов getAll() очень неэффективен и вместо этого вызывает некоторый вариант find или выполнение запроса HQL для точных полей каждого класса домена будет намного более эффективным ... это займет намного больше времени, чтобы писать!

Примеры

assert MyDomainClass.getAll().isEmpty() // true 

    def myDomainClass1 = new MyDomainClass(some: "foo", arbitrary: 1, field: true) 
    assert MyDomainClass.getAll().contains(myDomainClass1); // false 
    myDomainClass1.save(flush:true) 

    def myDomainClass2 = new MyDomainClass(some: "bar", arbitrary: 1, field: true) 
    assert MyDomainClass.getAll().contains(myDomainClass2); // false. Even though this has the same `arbitrary` value as myDomianClass1, it has a different `some` value which makes it unique. 
    myDomainClass2.save(flush:true) 

    def myDomainClass3 = new MyDomainClass(some: "foo", arbitrary: 1, field: false) 
    assert MyDomainClass.getAll().contains(myDomainClass3); // false. Even though this has the same `some` value as myDomainClass1 and the same `arbitrary` value as myDomainClass1 and myDomainClass2, it has a different `field` value which makes it unique. 
    myDomainClass3.save(flush:true) 
+1

Трудно понять, что вы просите. Вы хотите знать, является ли класс домена уникальным, но не на полевом уровне. Как еще вы могли бы определить, является ли он уникальным, кроме полей домена? Не можете ли вы сказать «произвольный уникальный: истинный» ??? В этом случае это поможет обеспечить фактический пример, с которым вы работаете. –

+0

@JamesKleeh Если бы я сказал «произвольный уникальный: истинный», это означало бы, что никакое другое «произвольное» поле в любом другом экземпляре этого «MyDomainClass» не может иметь одинаковое значение. Это не то, чего я хочу. Я хочу, чтобы другой экземпляр «MyDomainClass» мог иметь то же самое «произвольное» значение, если значения других полей делают экземпляр класса домена уникальным. Я приведу лучший пример, чтобы проиллюстрировать это. – ubiquibacon

+0

Итак, вам нужно добавить уникальное ограничение, охватывающее все поля. 'some unique: ['произвольное', 'field']' –

ответ

1

Это обеспечит сочетание 3-х полей в области являются уникальными. Это также обеспечивает ограничение на уровне базы данных, а не только на уровне приложения.

class MyDomainClass { 
    String some 
    int arbitrary 
    boolean field 
    static constraints = { 
     some(unique: ['arbitrary', 'field']) 
    } 
} 
+0

Я попробую. Я тестирую это однажды (в прошлом в другом приложении), и я помню, что он работает по-другому.Надеюсь, я ошибаюсь :) – ubiquibacon

+0

Это, похоже, работает так, как вы думали. Думаю, я делал это сложнее, чем это было на самом деле: / – ubiquibacon

Смежные вопросы