Hibernate MappingException с наследованием конкретного недоменного класса в Grails - PullRequest
2 голосов
/ 25 октября 2011

Сценарий

Мне нужно представить объект в двух разных контекстах.Один контекст не должен сохраняться, а другой должен.Постоянные объекты являются фактическими данными, полученными из другой системы.Непостоянные объекты представляют собой части определения продукта.Эти два будут сравниваться, и я не заинтересован в сохранении данных определения.Постоянный объект должен иметь дополнительную информацию, хранящуюся в нем.

Реализация

Для этого я решил, что наиболее логичным будет создать базовый класс в папке src / groovy, чтобы избежать появления сохраняемых grails / hibernate.это как доменный класс.

class Resource{
    String name
    Date lastModified 
}

Класс домена, который я хочу сохранить, выглядит следующим образом.

class OwnedResource extends Resource{  
  Date dateCreated, lastUpdated
  Owner owner
  static belongsTo = [owner: Owner]
  static mapping = {
   //I assumed I would need this so that grails would not expect 
   //to store the object in the base class table that doesn't exist
   tablePerHierarchy true 
   table 'owned_resource'
  }
}

Наконец, у нас есть класс Owner, который имеет много OwnedResources.

class Owner{
  Date dateCreated, lastUpdated
  String name
  static hasMany = [
    resources: OwnedResource
  ]
}

Проблема

Когда я запускаю приложение, я получаю дружественное исключение Hibernate:

2011-10-24 20:32:01,307 [main] ERROR context.GrailsContextLoader  - Error executing bootstraps: 
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: Association references unmapped class: OwnedResource

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: Association references unmapped class: OwnedResource
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.groovy: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)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

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: Association references unmapped class: OwnedResource
... 24 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: Association references unmapped class: OwnedResource
... 24 more

Caused by: org.hibernate.MappingException: Association references unmapped class: OwnedResource
... 24 more

Возможно, моя реализация - плохая практика, так как после большого поиска в Google и поиска в StackOverflow яеще не сталкивался ни с кем сталкивающимся с той же самой проблемой или попыткой подобной реализации.Большинство людей пытаются использовать абстрактные классы, которые действительно работают.Я хочу, чтобы класс Resource был конкретным, потому что мне нужно создать его экземпляр.Ответ может просто состоять в том, что Grails не позволяет эту функциональность, но я хотел бы услышать окончательный ответ и любые возможные обходные пути.Я склоняюсь к тому, чтобы дублировать класс вместо использования наследования.

Что я делаю неправильно и почему происходит эта ошибка?Можно ли сделать эту реализацию в Grails?

Ответы [ 2 ]

3 голосов
/ 05 апреля 2013

В этом случае, если вы пытаетесь расширить класс, который находится за пределами папки домена, вы должны объявить этот класс как абстрактный.

В противном случае Hibernate попытается сопоставить его, и поскольку он не находится в папке домена, все в конечном итоге взорвется.

0 голосов
/ 26 октября 2011

Используйте абстрактный базовый класс Resource, а затем добавьте 3-й класс, расширяющий Resource, который не является объектом домена, а представляет собой простой служебный класс, который можно использовать для других целей и не беспокоиться о сохранении. Удачи... Дмитрий.

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