Grails 2.2.0
ユーザーがマスターメールを1つだけ持つように強制するカスタム制約を作成しようとしています。エラーの原因となる簡略化されたコードは次のとおりです。
ユーザードメインクラス
class User {
static hasMany = [emails: Email]
static constraints = {
}
}
メールドメインクラス
class Email {
static belongsTo = [user: User]
String emailAddress
Boolean isMaster
static constraints = {
emailAddress unique: ['user']
isMaster validator: { val, obj ->
return !val || Email.findByUserAndIsMaster(obj.user, true) == null
}
}
}
統合テスト
class EmailTests {
@Before
void setUp() {
}
@After
void tearDown() {
// Tear down logic here
}
@Test
void testSomething() {
def john = (new User(login: 'johnDoe')).save(failOnError: true, flush: true)
assert (new Email(emailAddress: 'john@gmail.com', user: john, isMaster: true)).save(failOnError: true)
}
}
「grailstest-app-integration」を実行すると、次のようになります。
| 失敗:testSomething(webapp.EmailTests)
| org.hibernate.AssertionFailure:webapp.Emailのorg.grails.datastore.gorm.GormStaticApi $ _methodMissing_closure2.doCall(GormStaticApi.groovy:105)のEmailエントリ(例外が発生した後にセッションをフラッシュしないでください)のnull id $ __ clinit__closure1_closure2.doCall(Email.groovy:13)at org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener.onApplicationEvent(AbstractPersistenceEventListener.java:46)at webapp.EmailTests.testSomething(EmailTests.groovy:21)
一意の制約をカスタム制約の後に変更しても、問題は発生しません。ここで何が起きてるの?ここで、関連性のある制約の順序はどのようになっているのかを理解したいのですが。
明確にするために、これは問題を引き起こしません:
static constraints = {
isMaster validator: { val, obj ->
return !val || Email.findByUserAndIsMaster(obj.user, true) == null
}
emailAddress unique: ['user']
}