6

以下に説明する継承マッピングを持つ4つのクラスA、B、B1、B2があります
。A(テーブルAにマップされる)は最上位の親クラスであり、その継承マッピング戦略はtablePerHierarchy=false(そのサブクラスのそれぞれがシングルテーブル)。
クラス B は A から拡張され、B1、B2 は B から拡張されます。ただし、B1 と B2 は B と同じテーブルを共有するため、B クラスでは、tablePerHierarchy=trueB1 と B2 を分離するために と識別子を宣言します。
詳細コードは次のとおりです。

class A {
     static mapping = {
          tablePerHierarchy false
          table 'A'
     }
}

class B extends A {
     static mapping = {
          tablePerHierarchy true
          table 'B'
          discriminator column : 'TYPE'
     }
     String bProp1
     String bProp2
}

class B1 extends B {
     static mapping = {
          discriminator column : 'TYPE', value : 'B1'
     }
     String b1Props1 
     String b1Props2
}

class B2 extends B {
     static mapping = {
          discriminator column : 'TYPE', value : 'B2'
     }
     String b2Props1
     String b2Props1
}

アプリを起動すると、エラーが発生しました:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageSource': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.MappingException: No discriminator found for edu.test.B1. Discriminator is needed when 'single-table-per-hierarchy' is used and a class has subclasses
    at org.grails.tomcat.TomcatServer.start(TomcatServer.groovy:212)
    at grails.web.container.EmbeddableServer$start.call(Unknown Source)
    at _GrailsRun_groovy$_run_closure5_closure12.doCall(_GrailsRun_groovy:158)
    at _GrailsRun_groovy$_run_closure5_closure12.doCall(_GrailsRun_groovy)
    at _GrailsSettings_groovy$_run_closure10.doCall(_GrailsSettings_groovy:280)
    at _GrailsSettings_groovy$_run_closure10.call(_GrailsSettings_groovy)
    at _GrailsRun_groovy$_run_closure5.doCall(_GrailsRun_groovy:149)
    at _GrailsRun_groovy$_run_closure5.call(_GrailsRun_groovy)
    at _GrailsRun_groovy.runInline(_GrailsRun_groovy:116)
    at _GrailsRun_groovy.this$4$runInline(_GrailsRun_groovy)
    at _GrailsRun_groovy$_run_closure1.doCall(_GrailsRun_groovy:59)
    at RunApp$_run_closure1.doCall(RunApp:33)
    at gant.Gant$_dispatch_closure5.doCall(Gant.groovy:381)
    at gant.Gant$_dispatch_closure7.doCall(Gant.groovy:415)
    at gant.Gant$_dispatch_closure7.doCall(Gant.groovy)
    at gant.Gant.withBuildListeners(Gant.groovy:427)
    at gant.Gant.this$2$withBuildListeners(Gant.groovy)
    at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source)
    at gant.Gant.dispatch(Gant.groovy:415)
    at gant.Gant.this$2$dispatch(Gant.groovy)
    at gant.Gant.invokeMethod(Gant.groovy)
    at gant.Gant.executeTargets(Gant.groovy:590)
    at gant.Gant.executeTargets(Gant.groovy:589)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.MappingException: No discriminator found for edu.test.B1. Discriminator is needed when 'single-table-per-hierarchy' is used and a class has subclasses
    ... 23 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.MappingException: No discriminator found for edu.test.B1. Discriminator is needed when 'single-table-per-hierarchy' is used and a class has subclasses
    ... 23 more
Caused by: org.hibernate.MappingException: No discriminator found for edu.test.B1. Discriminator is needed when 'single-table-per-hierarchy' is used and a class has subclasses
    ... 23 more

ディスクリミネーターに関する Grails のドキュメント ( http://grails.org/doc/latest/ref/Database%20Mapping/discriminator.html ) の指示に従いましたが、機能しませんでした。ここでこのドキュメントの問題に関する JIRA を見つけました: http://jira.grails.org/browse/GRAILS-5168、コメントとしてコードを修正しましたが、それでも同じエラーが発生しました。

この問題を引き起こした理由はわかりません。B の tablePerHierarchy=true は、A で定義された戦略をオーバーライドしますか?
この問題を解決するのを手伝ってくれませんか? どうもありがとう。

4

1 に答える 1

1

クラス階層の継承戦略の混合は、JPA/Hibernate レベルに至るまで、実際にはサポートされていないようです。あなたの問題はこれらと同じ(または少なくとも非常に似ている)と思います:

JPA アノテーションを介してクラス階層のブランチで継承戦略を変更する

継承戦略を JPA アノテーションと Hibernate と組み合わせるには?

「org.codehaus.groovy.grails.orm.hibernate」のロギング設定を「debug」に変更すると、クラス B の「tablePerHierarchy=true」設定が A の戦略をオーバーライドしないことがわかります。動作しません。繰り返しになりますが、GORM よりも低いレベルでの制限のようです。その階層に 1 つの継承戦略を使用するように設計を修正できますか?

于 2011-08-30T17:03:09.727 に答える