4

これは以前に何度も尋ねられたようで、Peter Ledbrook による「GORM Gotchas (Part 2)」を含むいくつかを調べましたが、私の場合はまだ理解できないようです. user多くの を持っているがprojectsあり、projectは に属していuserます。次に、skill多くのprojects関連付けられた がありますが、projectは に属しませんskillprojectaから aを削除しようとすると、userそのエラーが発生します。ドメイン クラスは次のとおりです。

    パッケージ grailstuts

    クラスユーザー{
        文字列名

        静的制約 = { name(nullable: true) }

        static mapping = { プロジェクト カスケード: "all-delete-orphan" }

        static hasMany = [ プロジェクト: プロジェクト ]
    }

    パッケージ grailstuts

    クラスプロジェクト{
        文字列のタイトル

        静的制約 = { title(nullable: true) }

        静的属し = [ユーザー: ユーザー]
    }

    パッケージ grailstuts

    クラススキル{
        文字列名

        静的制約 = { name(nullable: true) }

        static mapping = { プロジェクト カスケード: "all-delete-orphan" }

        static hasMany = [ プロジェクト: プロジェクト ]
    }

次のように統合テストを実行すると、含まれている部分foundUser.removeFromProjects(foundProject1)に問題があるようです。

    パッケージ grailstuts

    import spock.lang.*

    class SkillIntegrationSpec は仕様を拡張します {
        void "プロジェクトの追加と削除"() {
            与えられた:「ユーザー、およびユーザーに追加されたプロジェクト」
            def user = new User().save(failOnError: true)
            def project1 = 新しいプロジェクト(タイトル: "java, groovy")
            def project2 = 新しいプロジェクト(タイトル: "java, scala")
            user.addToProjects(project1)
            user.addToProjects(project2)

            when: 「プロジェクトもスキルのエントリに追加されます」
            def java = new Skill(name: 'java').save(failOnError: true)
            java.addToProjects(project1)
            java.addToProjects(project2)
            def groovy = new Skill(name: 'groovy').save(failOnError: true)
            groovy.addToProjects(project1)
            def scala = new Skill(name: 'scala').save(failOnError: true)
            scala.addToProjects(project2)

            その後:「各スキルエントリには対応するプロジェクトがあります」
            Skill.findByName("java").projects.size() == 2
            Skill.findByName("グルーヴィー").projects.size() == 1
            Skill.findByName("スカラ").projects.size() == 1

            when: 「一部のプロジェクトがデータベースから削除されました」
            def foundUser = User.get(user.id)
            def foundProject1 = Project.findByTitle("java, groovy")
            foundUser.removeFromProjects(foundProject1)

            その後:「削除されたプロジェクトもスキルエントリに反映されます」
            Skill.findByName("java").projects.size() == 1
            Skill.findByName("グルーヴィー").projects.size() == 0
            Skill.findByName("スカラ").projects.size() == 1
        }
    }

上記のテストの最初のgiven:... when:... then:...ブロックは問題なく検証されます。からwhen:...を削除しようとしたときの 2 番目のブロックで、エラーが発生したようです。エラーは次のようになります...projectuser

    | | 1 つの統合テストを実行しています... 1/1
    | | 失敗: プロジェクトの追加と削除 (grailstuts.SkillIntegrationSpec)
    | | org.springframework.dao.InvalidDataAccessApiUsageException: 削除されたオブジェクトはカスケードによって再保存されます (関連付けから削除されたオブジェクトを削除します): [grailstuts.Project#2]; ネストされた例外は org.hibernate.ObjectDeletedException です: 削除されたオブジェクトはカスケードによって再保存されます (関連付けから削除されたオブジェクトを削除します): [grailstuts.Project#2]
        org.grails.datastore.gorm.GormStaticApi.methodMissing_closure2 (GormStaticApi.groovy:102) で
        grailstuts.SkillIntegrationSpec.でのプロジェクトの追加と削除(SkillIntegrationSpec.groovy:34)
    原因: org.hibernate.ObjectDeletedException: 削除されたオブジェクトはカスケードによって再保存されます (関連付けから削除されたオブジェクトを削除します): [grailstuts.Project#2]
        ... 2以上
    | | 1 つの統合テストを完了、0m 0s で 1 つ失敗
    | | テスト失敗 - C:\Grails\grailstuts\target\test-reports でレポートを表示

私は使っている:

    Grails バージョン: 2.3.1
    Groovy バージョン: 2.1.8
    JVM バージョン: 1.7.0_45

解決策を探すのにかなりの時間を費やしましたが、まだ運がありません。どんな助けでも大歓迎です。ありがとうございました!

4

1 に答える 1

5

all-delete-orphan- 1 対多の関連付けにのみ適用 され、子が関連付けから削除されると、自動的に削除される必要があることを示します 。親が削除されると、子も削除されます。したがって、呼び出すときにオブジェクトfoundUser.removeFromProjects(foundProject1)を削除しようとしていますが、エンティティがまだこのプロジェクトを参照しているためfoundProject1、DB から削除できません。Skill修正方法:

  • 最初のアプローチ: から削除projects cascade: "all-delete-orphan"Userて、呼び出し時にプロジェクトが削除されないようにしますuser.removeFromProjects(...)
  • 2 番目のアプローチ:skill.removeFromProjects(...)プロジェクトを保存して呼び出すと、プロジェクトが削除されます
于 2013-11-14T08:38:50.270 に答える