3

Grails で抽象 (または非抽象) 継承を使用している場合、以下は機能しません。

非常に迅速に、私の継承は次のとおりです。

abstract BaseClass               { ... }
SomeClass      extends BaseClass { ... }
SomeOtherClass extends BaseClass { ... }

そして、別のドメイン オブジェクトで:

ThirdClass {
    ...
    BaseClass baseProperty
    ...
}

しかし今、そのプロパティを aSomeClassまたはSomeOtherClassinstance に設定しようとすると、Grails は次のように言います。

エラー util.JDBCExceptionReporter - 子行を追加または更新できません: 外部キー制約が失敗しました ...

これは不可能ですか?


SomeClassまた、基本クラスを抽象化しないようにして、またはSomeOtherClassインスタンスを にキャストしようとしましたBaseClass。それらは同じエラーを生成します。


アップデート

私はちょうどチェックしました。追加する最初のサブクラスで機能します。しかし、他のサブクラスを追加しようとするとすぐに失敗します。

言い換えると:

def prop1 = new ThirdClass(baseProperty: instanceOfSomeClass).save()

正常に動作します。しかし、私が試してみると:

def prop2 = new ThridClass(baseProperty: instanceOfSomeOtherClass).save()

それは失敗します。


更新 2

さらに調査すると、テーブルの作成プロセス中に問題が発生することがわかります。テーブルに 2 つの外部キーが正しく追加されますThirdClassが、キーは正しく参照されません。

CONSTRAINT `...` FOREIGN KEY (`some_id`) REFERENCES `base_class` (`id`),
CONSTRAINT `...` FOREIGN KEY (`some_id`) REFERENCES `some_class` (`id`)

基本クラスとサブクラスの 1 つを選択する理由がわかりませんか? クリーニング等をしてみました。

4

2 に答える 2

7

まず、ドメイン構造の外側に BaseClass を作成します。外部クラスである必要があり、スクリプト フォルダー、ソース フォルダーに配置します。

package com.example.model

/**
 * @author Inocencio
 */
class BaseClass {

    Date createdAt = new Date()

}

次に、通常のドメイン クラスを作成して拡張します。

package com.example.domain

import com.example.model.BaseClass

class SomeClass extends BaseClass {

    String name

    static constraints = {
        name(nullable: false)
    }

}

ご覧のとおり、 SomeClass を永続化すると、 createdAt フィールドも入力されて保存されます。テスト クラスを確認します。

@TestFor(SomeClass)
class SomeClassTests {

    void testSomething() {
        def some = new SomeClass()
        some.name = "Hello There"
        some.save()

        //find it
        def someFind = SomeClass.list()[0]

        assert someFind

        assertTrue someFind.createdAt != null

//        println "Date: $someFind.createdAt"
//        println "Name: $someFind.name"
    }
}

お役に立てば幸いです。

于 2012-09-11T12:32:12.397 に答える
0

クラス構造をあなたのもの (Grails 2.1.0) として作成しましたが、問題はありません。モックおよび単体テストすると機能します。スキャフォールディングされ、フォームから保存された SomeClass および ThirdClass インスタンスの場合も同じです。特に「create-drop」モードを使用していない場合は、DB をきれいにしてみてください。古い制約が残っている可能性があります。最後に、エラーがいつ発生するかを指定していません - 保存時 (作成時または更新時) ですか? プロパティ セットで JDBC 例外が発生する可能性はほとんどありません。確かに覚えていませんが、単純なプロパティがデフォルトでカスケードされていない可能性があり、ThirdClass インスタンスを保存する前に SomeClass インスタンスを保存しようとします。また、単純なプロパティを宣言する代わりに、次のような hasOne リレーションを使用して自動カスケードすることもできます。

class ThirdClass {
    ...
    static hasOne = [baseProperty:BaseClass]
}
于 2012-09-11T12:06:24.537 に答える