【发布时间】:2013-08-19 13:28:58
【问题描述】:
我有一个 Grails 应用程序,其中包含一堆域类,其中一些具有许多字段,其中一些与所讨论的域类具有 hasMany 关系。对于这个特定的应用程序,我只有一个“约束”,即每个域类的每个实例都必须是唯一的。我不在乎一个任意字段是否在同一个域类的多个实例中具有相同的值,只要每个实例都由该域类中某个其他字段的值唯一。所以基本上我希望验证发生在域类实例级别而不是域类字段级别。现在我正在这样做,方法是使用非常时髦的 @EqualsAndHashCode 注释来生成我的 equals 和 hashCode 方法,然后在域类的某个任意字段上的自定义验证器中调用 equals。
两个问题:
- 是否有更有效的方法来验证域类是否唯一?
- 如果不是,那么有没有一种方法可以在域类实例本身上调用我的自定义验证器代码,而不是通过域类实例的某个字段?
我还应该补充一点,我正在寻找一种通用的(希望是有效的)方法来做到这一点。我意识到调用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)
【问题讨论】:
-
很难理解你在问什么。您想知道域类是否是唯一的,但不是在字段级别。除了域的字段之外,您还如何确定它是否是唯一的?你能不说
arbitrary unique: true吗???在这种情况下,提供您正在使用的实际示例会有所帮助。 -
@JamesKleeh 如果我说
arbitrary unique: true,则意味着该MyDomainClass的任何其他实例中的任何其他arbitrary字段都不会具有相同的值。那不是我想要的。我希望MyDomainClass的其他实例能够具有完全相同的arbitrary值,只要其他字段的值使域类的实例唯一。我将添加一个更好的例子来说明这一点。 -
那么你需要添加一个跨越所有字段的唯一约束。
some unique: ['arbitrary', 'field'] -
@JamesKleeh 如果我使用多列
unique(我认为这就是您的建议)我将不得不为MyDomainClass中的每个字段执行此操作。示例:some(unique:['arbitrary', 'field']然后arbitrary(unique: ['some', 'field'])然后field(unique:['some', 'arbitrary'])。我很确定这会得到我想要的(而且它肯定比我现在做的更有效),但如果可能的话,我想要一个更通用的解决方案。 -
您只需将约束放在一个字段上。我在上面展示的示例将确保 some、任意和 field 将是唯一键。你的所有三个例子都做同样的事情,你把它放在什么顺序和字段上是......任意的:)
标签: grails