我有4个A,B,B1,B2类,其继承映射描述如下:
A(映射到表A)是最顶层的父类,它的继承映射策略是tablePerHierarchy=false
(意味着它的每个子类映射到一个表)。
B类从A延伸,B1,B2从B延伸。但B1和B2与B共用同一个表,因此在B类中,我声明tablePerHierarchy=true
和鉴别器将B1和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?中定义的策略 你能帮我解决这个问题吗?非常感谢你。
答案 0 :(得分:1)
似乎并不真正支持混合类层次结构的继承策略,甚至是JPA / Hibernate级别。 我认为你的问题与这些问题相同(或至少非常相似):
Changing the inheritance strategy in branches of the class hierarchy via JPA annotations
How to mix inheritance strategies with JPA annotations and Hibernate?
如果将'org.codehaus.groovy.grails.orm.hibernate'的日志记录设置更改为'debug',您可以看到B类中的'tablePerHierarchy = true'设置不会覆盖A中的策略。无论如何,它不起作用。同样,它看起来是一个比GORM更低级别的限制。可以修改您的设计,以便为该层次结构使用一种继承策略吗?