2011-08-11 23 views
6

Tôi có 4 lớp A, B, B1, B2 với ánh xạ thừa kế được mô tả như sau:
A (ánh xạ tới bảng A) là lớp cha trên cùng và chiến lược ánh xạ kế thừa của nó là tablePerHierarchy=false (nghĩa là mỗi lớp con của nó được ánh xạ tới một bảng duy nhất).
Lớp B kéo dài từ A và B1, B2 kéo dài từ B. Nhưng B1 và ​​B2 chia sẻ cùng một bảng với B, vì vậy trong lớp B, tôi khai báo tablePerHierarchy=true và phân biệt đối xử để tách B1 và ​​B2.
Mã chi tiết ở đây:Vấn đề phân biệt đối xử trong bản đồ kế thừa của 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 
} 

Khi tôi bắt đầu ứng dụng của tôi, có một lỗi xảy ra:

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 

Tôi đã theo sự hướng dẫn của Grails tài liệu về phân biệt (http://grails.org/doc/latest/ref/Database%20Mapping/discriminator.html) nhưng nó đã không công việc. Tôi đã tìm thấy một JIRA về vấn đề tài liệu này tại đây: http://jira.grails.org/browse/GRAILS-5168 và sửa mã của tôi khi họ nhận xét nhưng vẫn gặp lỗi tương tự.

Tôi không biết nguyên nhân gây ra sự cố này. Liệu tablePerHierarchy = true trong B ghi đè lên chiến lược đó được định nghĩa trong A?
Bạn có thể giúp tôi khắc phục sự cố này không? Cảm ơn bạn rất nhiều.

+0

bạn nên đánh dấu câu trả lời được chấp nhận – dbrin

Trả lời

1

Dường như việc trộn các chiến lược kế thừa cho một hệ thống phân cấp lớp không thực sự được hỗ trợ, thậm chí xuống mức JPA/Hibernate. Tôi nghĩ vấn đề của bạn là giống như (hoặc ít nhất là rất giống với) sau đây:

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

How to mix inheritance strategies with JPA annotations and Hibernate?

Nếu bạn thay đổi các thiết lập đăng nhập cho 'org.codehaus.groovy.grails.orm .hibernate 'to' debug 'bạn có thể thấy rằng thiết lập' tablePerHierarchy = true 'trong lớp B KHÔNG ghi đè lên chiến lược trong A. Bất kể, nó không hoạt động. Một lần nữa, nó có vẻ là một hạn chế ở mức thấp hơn GORM. Có thể sửa đổi thiết kế của bạn để sử dụng một chiến lược thừa kế cho phân cấp đó không?

Các vấn đề liên quan