Grails 继承映射中的判别器问题

发布于 2024-11-29 04:48:23 字数 4603 浏览 0 评论 0原文

我有 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 中定义的策略?
你能帮我解决这个问题吗?太感谢了。

I have 4 classes A, B, B1, B2 with inheritance mapping described as below:
A (mapped to table A) is the top-most parent class and its inheritance mapping strategy is tablePerHierarchy=false (means each of its sub-classes is mapped to a single table).
Class B extends from A, and B1, B2 extends from B. But B1 and B2 share the same table with B, so in B class, I declare tablePerHierarchy=true and a discriminator to separate B1 and B2.
The detail code is here:

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
}

When I start my app, there's an error occured:

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

I have followed the instruction of Grails documentation about discriminator ( http://grails.org/doc/latest/ref/Database%20Mapping/discriminator.html ) but it did not work. I have found a JIRA about this document issue here: http://jira.grails.org/browse/GRAILS-5168 and fixed my code as they comment but it still got the same error.

I do not know the reason which caused this issue. Does the tablePerHierarchy=true in B override that strategy defined in A?
Could you please help me to fix this problem? Thank you so much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冰雪之触 2024-12-06 04:48:23

似乎并没有真正支持类层次结构的混合继承策略,甚至到 JPA/Hibernate 级别也是如此。
我认为您的问题与这些相同(或至少非常相似):

通过 JPA 注释更改类层次结构分支中的继承策略

如何将继承策略与 JPA 注释和 Hibernate 混合使用?

如果将“org.codehaus.groovy.grails.orm.hibernate”的日志设置更改为“debug”,您可以看到B 类中的“tablePerHierarchy=true”设置不会覆盖 A 中的策略。无论如何,它不起作用。同样,它看起来是一个比 GORM 级别更低的限制。可以修改您的设计以对该层次结构使用一种继承策略吗?

It seems that mixing inheritance strategies for a class hierarchy is not really supported, even down to the JPA/Hibernate level.
I think your issue is the same as (or at least very similar to) these:

Changing the inheritance strategy in branches of the class hierarchy via JPA annotations

How to mix inheritance strategies with JPA annotations and Hibernate?

If you change the logging settings for 'org.codehaus.groovy.grails.orm.hibernate' to 'debug' you can see that the 'tablePerHierarchy=true' setting in class B does NOT override the strategy in A. Regardless, it doesn't work. Again, it looks to be a limitation at a lower level than GORM. Can revise your design to use one inheritance strategy for that hierarchy?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文