2

シナリオ

オブジェクトを 2 つの異なるコンテキストで表現する必要があります。1 つのコンテキストは保持されるべきではなく、もう 1 つのコンテキストは保持されるべきです。永続オブジェクトは、別のシステムから取得された実際のデータです。非永続オブジェクトは、製品定義の一部を表します。この 2 つを比較しますが、定義データの保存には関心がありません。永続オブジェクトには、追加情報が保存されている必要があります。

実装

これを達成するために、最も論理的な方法は、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'
  }
}

最後に、所有するリソースがたくさんある所有者クラスがあります。

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

おそらく私の実装は悪い習慣です.StackOverflowを何度もグーグル検索して検索した後、この同じ問題に直面したり、同様の実装を試みたりする人にまだ出会っていないからです. ほとんどの人は抽象クラスを使用しようとしていますが、これは機能します。インスタンス化する必要があるため、クラス Resource を具体的にしたいと考えています。答えは単に grails がこの機能を許可していないということかもしれませんが、決定的な答えと考えられる回避策を聞きたいです。継承を使用する代わりに、クラスを複製する必要があることに傾いています。

何が間違っているのですか?なぜこのエラーが発生するのですか? この実装は grails で実行できますか?

4

2 に答える 2

0

抽象基本クラス Resource を使用してから、Resource を拡張する 3 番目のクラスを追加します。このクラスは、ドメイン オブジェクトではなく、他の目的に使用でき、永続性を気にする必要のない単純なユーティリティ クラスです。がんばれ…ドミトリー。

于 2011-10-25T21:45:40.770 に答える