2013-04-16 17 views
6

Grails 2.2.1で多対1リレーションシップの埋め込みドメインを使用しようとしています。ここに私がしようとしているものの簡略版があります。GORMコンポジション - 多対1リレーションシップを持つ埋め込みドメインorg.hibernate.MappingException

私は既存のDBテーブルへのマッピングだ: "事件" テーブルにマップ

create table incident (id bigint generated by default as identity, state_id bigint not null, primary key (id)); 
create table state (id bigint generated by default as identity, name varchar(255) not null, primary key (id)); 
alter table incident add constraint FK52F44D27499E79E foreign key (state_id) references state; 

ドメイン: "状態" テーブルにマップする

class Incident { 
    Vehicle vehicle 
    static embedded = ['vehicle'] 
} 

class Vehicle{ 
    State state 
    static mapping = { 
     state column: 'state_id' 
    } 
} 

がドメイン:

class State { 
    String name 
} 

アプリケーションを実行しようとすると、次のエラーが発生します。

Message: Error creating bean with name 'transactionManagerPostProcessor': 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: Could not determine type for: test.State, at table: incident, for columns: [org.hibernate.mapping.Column(vehicle_state)]

埋め込みドメイン内で多対1の関連付けが可能ですか?

- 更新 -

私は状態を取得するための回避策を使用して終了。

class Vehicle{ 

    static transients = [ "state" ] 

    Long stateId 

    static mapping = { 
     stateId column: 'state_id' 
    } 

    State getState(){ 
     State.get(this.stateId) 
    } 
} 
+0

私は...これはGrailsのバグかもしれないと思うし始めているが、HTTPに似たサウンド://jira.grailsを。org/browse/GRAILS-9012 –

答えて

4

に文字列としてstateNameを持つ好むだろう。

  1. 関係は動作しません
  2. カスタム列マッピングが

を動作しません。あなたは、埋め込まれたエンティティに対処するためのヘルパーメソッドを作成し、その後、所有しているクラスで直接列をマッピングする方がいいでしょう。

例えば:

// grails-app/domain/yourpkg/Incident.groovy 
class Incident { 
    State state 

    public Vehicle getVehicleData() { 
     return new Vehicle(state: state) 
    } 

    public void updateWithVehicle(Vehicle vehicle) { 
     state = vehicle.state 
    } 

    static mapping = { 
     state column: 'state_id' 
    } 
} 

// src/groovy/yourpkg/Vehicle.groovy 
class Vehicle { 
    State state 
} 
+0

私はあなたの提案と同様の回避策を行って、状態を取得するヘルパーメソッドを追加しました。 埋め込みドメインのクラスでのユーザビリティの問題について、私は間違いなく同意します。これは将来のgrailsリリースで対応される予定です! :) –

0

この場合、ドメインは(src/groovyに移動した場合に持続性の一部ではないだろう埋め込みVehicle含む)serializedこととクラスのequals()hashCode()を生成しなければなりません。古い学校ですが、うまく動作し、アプリが適切に動作します。

Incedent.groovy

import groovy.transform.EqualsAndHashCode 

@EqualsAndHashCode 
class Incedent implements Serializable{ 
    Vehicle vehicle 
    static embedded = ['vehicle'] 

    class Vehicle{ 
     State state 
    } 
} 

State.groovy

import groovy.transform.EqualsAndHashCode 

@EqualsAndHashCode 
class State implements Serializable { 
    String name 
} 

でテストしたときに上記のVARBINARY(のデータ型と埋め込み用Incedentの列になるだろう続きメモリH2 db内)。私は、埋め込まれたドメインクラスは、彼らが難しい、特にレガシー・データベースでは、で動作するようにするいくつかのユーザビリティの問題を持って、Grailsの2.2.1のようVehicle

enter image description here

+0

私はこれを試しましたが、テーブルの構造が正しくないようです。残念ながら、私は既存のデータベースで作業しているので、テーブルを変更することはできません。質問にDBのddlを追加しました。うまくいけば、それは少し明確になります。 –

関連する問題