Проблема дискриминатора в наследовании Grails - PullRequest
6 голосов
/ 11 августа 2011

У меня есть 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 и исправил мой код, когда они комментировали, но он все еще получил ту же ошибку.

Я не знаю причину, вызвавшую эту проблему. Заменяет ли tablePerHierarchy = true в B стратегию, определенную в A?
Не могли бы вы помочь мне решить эту проблему? Большое вам спасибо.

1 Ответ

1 голос
/ 30 августа 2011

Похоже, что смешение стратегий наследования для иерархии классов на самом деле не поддерживается, даже до уровня JPA / Hibernate. Я думаю, что ваша проблема такая же (или, по крайней мере, очень похожа) на эти:

Изменение стратегии наследования в ветвях иерархии классов с помощью аннотаций JPA

Как смешать стратегии наследования с аннотациями JPA и Hibernate?

Если вы измените настройки ведения журнала для 'org.codehaus.groovy.grails.orm.hibernate' на 'debug', вы увидите, что параметр tablePerHierarchy = true в классе B НЕ переопределяет стратегию в A. не работает Опять же, это выглядит как ограничение на более низком уровне, чем GORM. Может ли ваш проект пересмотреть, чтобы использовать одну стратегию наследования для этой иерархии?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...