2011-08-11 50 views
6

我有4个类A,B,B1,B2,其继承映射如下所示:
A(映射到表A)是最上面的父类,它的继承映射策略是tablePerHierarchy=false(意味着它的每个子类映射到一个表)。
B类从A延伸出来,B1,B2从B延伸出来,但B1和B2与B有相同的表,所以在B类中,我声明tablePerHierarchy=true和一个区分B1和B2的鉴别器。
详细代码是在这里:Grails的继承映射中的判别器问题

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 

我按照有关鉴别(http://grails.org/doc/latest/ref/Database%20Mapping/discriminator.html)Grails的文档的指令,但事实并非如此工作。我在这里找到了关于这个文档问题的JIRA:http://jira.grails.org/browse/GRAILS-5168,并且在他们评论的时候修复了我的代码,但它仍然得到了同样的错误。

我不知道造成这个问题的原因。 B中的tablePerHierarchy = true是否覆盖A中定义的策略?
你能帮我解决这个问题吗?非常感谢。

+0

您应该标记接受的答案 – dbrin

回答

1

似乎混合继承策略的类层次结构并不真正支持,甚至到JPA /休眠级别。 我觉得你的问题是一样的(或至少非常相似),这些:

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更低的限制。可以修改您的设计以使用该层次结构的一种继承策略?