Discriminator in Grail Inheritance Mapping

I have 4 classes A, B, B1, B2 with the inheritance mapping described below:
A (mapped to table A) is the uppermost parent class, and its inheritance strategy is tablePerHierarchy=false (meaning that each of its subclasses is mapped to a single table).
Class B extends from A, and B1, B2 extends from B. But B1 and B2 use the same table with B, so in class B I declare tablePerHierarchy=true and the discriminator for separating B1 and B2.
Detailed code 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 launch my application, an error occurred:

 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 followed the instructions from the Grails discriminator documentation ( http://grails.org/doc/latest/ref/Database%20Mapping/discriminator.html ), but that didn't work. I found JIRA about this problem with the docs here: http://jira.grails.org/browse/GRAILS-5168 and fixed my code when they comment, but still got the same error.

I do not know the reason that caused this problem. Does tablePerHierarchy = true in B match this strategy defined in A?
Could you help me solve this problem? Thank you very much.

+6
source share
1 answer

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

Changing inheritance strategies in branches of a class hierarchy through JPA annotations

How to mix inheritance strategies with JPA and Hibernate annotations?

If you change the logging options for "org.codehaus.groovy.grails.orm.hibernate" to "debug", you will see that the parameter "tablePerHierarchy = true" in class B will NOT override the strategy in A. Regardless, it works. Again, this looks like a restriction at a lower level than GORM. Can you revise your design to use one inheritance strategy for this hierarchy?

+1
source

Source: https://habr.com/ru/post/894806/


All Articles