私は Grails 2.4.2 を使用しており、多くのInvoiceRecipientを持つクラスContractを持っています。InvoiceRecipients クラスには、 invoice -original の「O」と送り状のコピーの「C」の2 つの可能な値を持つ、 invoiceType属性があります。ご想像のとおり、1 つの契約の InvoiceRecipients には、タイプが「O」の1 つのレコードのみが許可されます。
次のスニペットのように実装しようとすると、VM で StackOverflow が発生します。
私が試した別のアプローチは、契約の受信者配列を反復処理して、invoiceType 'O' のレコードをカウントするサービス メソッドでした。 ->コントローラーの invoiceRecipients リレーション。
最後の両方のケースで、Hibernate は現在の InvoiceRecipient レコードの更新ステートメントを生成し、これを検証しようとします。また、現在の InvoiceRecipient の検証が失敗し、インスタンスのエラー オブジェクトにデータを入力した場合でも、レコードは既に更新されています (制約はクラスにコーディングされておらず、「保存」でエラーをスローしないため、問題はありません)。データベースに論理的に間違ったレコードがあります。
class Contract implements Serializable {
...
static hasMany = [recipients: InvoiceRecipient]
...
}
class InvoiceRecipient implements Serializable {
static belongsTo = [contract: Contract]
...
String invoiceType
...
static constraints = {
invoiceType nullable: false, maxLength: 1, inList: ['O', 'C'], validator: { val, obj ->
/* => This generates a StackOverflow
if (InvoiceRecipient.countByContractAndInvoiceType(obj.contract, 'O') > 1)
return "invoiceRecipient.original.max.exceed"
*/
}
}