2009-04-28 11 views
2

私はHibernate/JPAで動作するようにしようとしている単純なクラス階層を持っています。2つのテーブル間でHibernateエンティティを分割する

基本的に私はMovementDataがデータベースの主車両テーブルの整数IDにFKを持つ独自のテーブルにあることを望んでいます。

何か間違っていますか?どのように私は同様の何かを達成することができますか? 私はJPA仕様に従っていると確信しています。 (アクションでEJB3が、これは動作するはずの言葉:EJB3 In Action: @SecondaryTable

ここで私が取得しています例外の一部されています

SEVERE: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session) 
org.hibernate.AssertionFailure: Table MOVEMENT_DATA not found 
    at org.hibernate.persister.entity.JoinedSubclassEntityPersister.getTableId(JoinedSubclassEntityPersister.java:480) 
    at org.hibernate.persister.entity.JoinedSubclassEntityPersister.<init>(JoinedSubclassEntityPersister.java:259) 
    at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:87) 
    at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:261) 
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1327) 

はここでそれは...車に関連する休止状態からのログイン情報の一部でありますそれは罰金のすべてを認識しているように...そして、それはいくつかの理由のために例外をスローに見えます。

INFO: Binding entity from annotated class: com.dataobject.Vehicle 
FINE: Import with entity name Vehicle 
INFO: Bind entity com.dataobject.Vehicle on table VEHICLE 
INFO: Adding secondary table to entity com.dataobject.Vehicle -> MOVEMENT_DATA 
FINE: Processing com.dataobject.Vehicle property annotation 
FINE: Processing annotations of com.dataobject.Vehicle.id 
FINE: Binding column id. Unique false. Nullable false. 
FINE: id is an id 
FINE: building SimpleValue for id 
FINE: Building property id 
FINEST: Cascading id with null 
FINE: Bind @Id on id 
FINE: Processing annotations of com.dataobject.Vehicle.color 
FINE: Binding column COLOR. Unique false. Nullable true. 
FINE: binding property color with lazy=false 
FINE: building SimpleValue for color 
FINE: Building property color 
FINEST: Cascading color with null 
FINE: Processing annotations of com.dataobject.Vehicle.movementData 
FINE: Binding column movementData. Unique false. Nullable true. 
FINE: Binding component with path: com.dataobject.Vehicle.movementData 
FINE: Processing com.dataobject.MovementData property annotation 
FINE: Processing annotations of com.dataobject.MovementData.latitude 
FINE: Column(s) overridden for property latitude 
FINE: Binding column LATITUDE. Unique false. Nullable true. 
FINE: binding property latitude with lazy=false 
FINE: building SimpleValue for latitude 
FINE: Building property latitude 
FINEST: Cascading latitude with null 
FINE: Processing annotations of com.dataobject.MovementData.longitude 
FINE: Column(s) overridden for property longitude 
FINE: Binding column LONGITUDE. Unique false. Nullable true. 
FINE: binding property longitude with lazy=false 
FINE: building SimpleValue for longitude 
FINE: Building property longitude 
FINEST: Cascading longitude with null 
FINE: Processing annotations of com.dataobject.MovementData.speed 
FINE: Column(s) overridden for property speed 
FINE: Binding column SPEED. Unique false. Nullable true. 
FINE: binding property speed with lazy=false 
FINE: building SimpleValue for speed 
FINE: Building property speed 
FINEST: Cascading speed with null 
FINE: Processing annotations of com.dataobject.MovementData.timeOfPosition 
FINE: Column(s) overridden for property timeOfPosition 
FINE: Binding column TIME_OF_POSITION. Unique false. Nullable true. 
FINE: binding property timeOfPosition with lazy=false 
FINE: building SimpleValue for timeOfPosition 
FINE: Building property timeOfPosition 
FINEST: Cascading timeOfPosition with null 
FINE: Building property movementData 
FINEST: Cascading movementData with null 
FINE: Processing annotations of com.dataobject.Vehicle.numWheels 
FINE: Binding column NUM_WHEELS. Unique false. Nullable true. 
FINE: binding property numWheels with lazy=false 
FINE: building SimpleValue for numWheels 
FINE: Building property numWheels 
FINEST: Cascading numWheels with null 
INFO: Binding entity from annotated class: com.dataobject.Car 
FINE: Binding column id. Unique false. Nullable false. 
FINE: Subclass joined column(s) created 
FINE: Import with entity name Car 
INFO: Bind entity com.dataobject.Car on table CAR 
FINE: Processing com.dataobject.Car property annotation 
FINE: Processing annotations of com.dataobject.Car.make 
FINE: Binding column MAKE. Unique false. Nullable true. 
FINE: binding property make with lazy=false 
FINE: building SimpleValue for make 
FINE: Building property make 

車両は、親クラス

0123です
/** 
* Entity implementation class for Entity: Vehicle 
* 
*/ 
@Entity 
@Table(name="VEHICLE") 
@Inheritance(strategy=InheritanceType.JOINED) 
@SecondaryTable(name="MOVEMENT_DATA", 
      pkJoinColumns = { 
       @PrimaryKeyJoinColumn(name = "ID") 
      } 
) 
public class Vehicle implements Serializable { 


    private int numWheels; 
    private String color; 
    private int id; 
    private MovementData movementData; 
    private static final long serialVersionUID = 1L; 


    public Vehicle() { 
     super(); 
    } 

    @Embedded 
    @AttributeOverrides({ 
    @AttributeOverride(
     name = "speed", 
     column = @Column(name = "SPEED", 
         table = "MOVEMENT_DATA") 
    ), 
    @AttributeOverride(
     name = "timeOfPosition", 
     column = @Column(name = "TIME_OF_POSITION", 
         table = "MOVEMENT_DATA") 
    ), 
    @AttributeOverride(
      name = "longitude", 
      column = @Column(name = "LONGITUDE", 
          table = "MOVEMENT_DATA") 
     ), 
    @AttributeOverride(
      name = "latitude", 
      column = @Column(name = "LATITUDE", 
          table = "MOVEMENT_DATA") 
     ) 
}) 
    public MovementData getMovementData() { 
     return movementData; 
    } 
    public void setMovementData(MovementData movementData) { 
     this.movementData = movementData; 
    } 

    @Column(name="NUM_WHEELS") 
    public int getNumWheels() { 
     return this.numWheels; 
    } 

    public void setNumWheels(int numWheels) { 
     this.numWheels = numWheels; 
    } 
    @Column(name="COLOR") 
    public String getColor() { 
     return this.color; 
    } 

    public void setColor(String color) { 
     this.color = color; 
    } 
    @Id  
    public int getId() { 
     return this.id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

} 

車は、車両

/** 
* Entity implementation class for Entity: Car 
*/ 
@Entity 
@Table(name="CAR") 
public class Car extends Vehicle implements Serializable { 


    private String make; 
    private static final long serialVersionUID = 1L; 

    public Car() { 
     super(); 
    } 
    /** 
    * @return 
    */ 
    @Column(name="MAKE") 
    public String getMake() { 
     return this.make; 
    } 

    /** 
    * @param make 
    */ 
    public void setMake(String make) { 
     this.make = make; 
    } 

} 

MovementDataは、車両に組み込まれている拡張

@Embeddable 
public class MovementData implements Serializable { 


    private double speed; 
    private Date timeOfPosition; 
    private double latitude; 
    private double longitude; 
    private static final long serialVersionUID = 1L; 

    public MovementData() { 
     super(); 
    } 



    /** 
    * @return 
    */ 
    @Column(name="SPEED") 
    public double getSpeed() { 
     return this.speed; 
    } 

    /** 
    * @param speed 
    */ 
    public void setSpeed(double speed) { 
     this.speed = speed; 
    } 
    /** 
    * @return 
    */ 
    @Column(name="TIME_OF_POSITION") 
    public Date getTimeOfPosition() { 
     return this.timeOfPosition; 
    } 

    /** 
    * @param timeOfPosition 
    */ 
    public void setTimeOfPosition(Date timeOfPosition) { 
     this.timeOfPosition = timeOfPosition; 
    } 

    /** 
    * @return 
    */ 
    @Column(name="LONGITUDE") 
    public double getLongitude() { 
     return this.longitude; 
    } 

    /** 
    * @param longitude 
    */ 
    public void setLongitude(double longitude) { 
     this.longitude = longitude; 
    } 
    /** 
    * @return 
    */ 
    @Column(name="LATITUDE") 
    public double getLatitude() { 
     return this.latitude; 
    } 

    /** 
    * @param latitude 
    */ 
    public void setLatitude(double latitude) { 
     this.latitude = latitude; 
    } 

} 

永続ユニット:

<properties> 
     <!-- The database dialect to use --> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" /> 
     <!-- drop and create tables at deployment --> 
     <property name="hibernate.hbm2ddl.auto" value="create-drop" /> 
     <!-- Hibernate Query Language (HQL) parser. --> 
     <!-- property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider" /--> 
     <!-- property name="hibernate.cache.provider_class" value="org.hibernate.cache.JbossCacheProvider" /--> 
     <property name ="hibernate.show_sql" value="false" /> 
     <property name ="hibernate.format_sql" value="false" /> 
     <property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletonEhCacheProvider" /> 
    </properties> 

答えて

1

このプロパティが有効になっていることがその便利な場合:

CFGは私AnnotationConfigurationある
cfg.setProperty(Environment.HBM2DDL_AUTO, "update"); 

この問題を解決するには、このプロパティを有効にする必要があります。組み込み可能なクラスの

+0

私は作成ドロップセットを持っています(上記のpersistence.xmlを参照してください)。私はちょうど代わりに更新プログラムでそれを試して、それはまだ同じエラーで動作しません。 – systemoutprintln

+1

この問題が発生した他の人のためのメモ:自動選択が選択されました...これは機能しません。 – systemoutprintln

0

投稿した例外から、データベースにまだテーブルが作成されていないかのように表示されます(「テーブルMOVEMENT_DATAが見つかりません」)。 Hibernate/JPAにスキーマの変更を指示していない場合は、コードを実行する前に手動でテーブルを追加する必要があります(変更を実行するためにHibernateに指示するCREATE-UPDATEです)。開発中に

+0

私は既にそれを私のpersistence.xmlに持っています。 – systemoutprintln

0

定義べきではありません参照データベーステーブル:

@Embeddable 
public class MovementData implements Serializable { 


    private double speed; 
    private Date timeOfPosition; 
    private double latitude; 
    private double longitude; 
    private static final long serialVersionUID = 1L; 

    public MovementData() { 
     super(); 
    } 

    @Column(name="SPEED") 
    public double getSpeed() { 
     return this.speed; 
    } 

    ... 

    @Column(name="TIME_OF_POSITION") 
    public Date getTimeOfPosition() { 
     return this.timeOfPosition; 
    } 

    ... 

    @Column(name="LONGITUDE") 
    public double getLongitude() { 
     return this.longitude; 
    } 

    ... 

    @Column(name="LATITUDE") 
    public double getLatitude() { 
     return this.latitude; 
    } 

    ... 
} 

、車両エンティティが列に参加するなど、埋め込み構造のセカンダリテーブルを定義する必要があります

@Entity 
@Table(name="VEHICLE") 
@Inheritance(strategy=InheritanceType.JOINED) 
@SecondaryTable(name="MOVEMENT_DATA", 
       pkJoinColumns = { 
        @PrimaryKeyJoinColumn(name = "ID") 
       } 
) 
public class Vehicle implements Serializable { 


    private int numWheels; 
    private String color; 
    private int id; 
    private MovementData movementData; 
    private static final long serialVersionUID = 1L; 


    public Vehicle() { 
     super(); 
    } 

    @Embedded 
    @AttributeOverrides({ 
     @AttributeOverride(
      name = "speed", 
      column = @Column(name = "SPEED", 
          table = "MOVEMENT_DATA") 
     ), 
     @AttributeOverride(
      name = "timeOfPosition", 
      column = @Column(name = "TIME_OF_POSITION", 
          table = "MOVEMENT_DATA") 
     ), 

     ... // override the rest of the attributes 

    }) 
    public MovementData getMovementData() { 
     return movementData; 
    } 

    ... 

    @Id  
    public int getId() { 
     return this.id; 
    } 

    ... 
} 

私はこの意志を願っていますあなたのために働く。

+0

助けてくれてありがとう...同じエラーがまだ起こる。私は私の知恵の終わりです! – systemoutprintln

+1

私はこのような問題に遭遇すると、できるだけ透明にするためにフィールドを単純化しようとします。このケースでは、Vehicleエンティティからの継承設定を取り上げます。その方法で、その時点で問題の1つ(うまくいけば)を処理します。セカンダリテーブルの埋め込みオブジェクトの問題を解決したら、継承をロールバックして、それらがどのように連携しているかを確認します。 – topchef

1

私はこの問題を見つけるためにこれを打ち破ろうとします。埋め込み可能なクラスの代わりにエンティティに移動データを作成してみてください。それが単独で立つことができることを確認してから、埋め込み可能に戻してください。

あなたが望む関係ではありませんが、MovementDataをルートの親にして、VehicleをMovementDataから継承させてみるとよいでしょう。そうすれば、継承+二次表の代わりに

@Inheritance(strategy=InheritanceType.JOINED) 

の代わりに作業するだけです。それは関係を単純化するが、依然としてすべてのテーブルを含む。

+0

ああ..あなたは正しいと思います。@SecondaryTableと結合された継承ストラテジーを混在させることは、DBの観点からは同じように見えるので、問題である可能性があります。私のJavaエンティティを上記のように見せたいので、これは理想的なソリューションではありません。 – systemoutprintln

+0

したがって、2次表ではなく、VehicleとMovementData間のOneToOne関係にすることもできます。右のカスケードでは、同じように動作します。 – ccclark

-1

テーブルが実際に存在するかどうかを確認するために、適切なdbクライアント(クエリブラウザ、MS SQL Managment Studioなど)を使用してデータベースに接続します。

コードにブレークポイントを挿入して、このエラーが発生する前のデータベースの状態を正確に確認することもできます。

以下のように「作成」、ともあなたはそれをしようとしているもの見ることができるように、それはSQLを出力するように設定を変更するhibernate.hbm2ddl.auto値を設定してみてください:

<props> 
    <!-- some possible values: create, create-drop, update --> 
    <prop key="hibernate.hbm2ddl.auto">update</prop> 
    <prop key="hibernate.show_sql">true</prop> 
    .... 
<props> 

、私を知ってみましょうあなたのデータベースには何が見えますか?

+0

私はそれを作成するために設定すると、実際のDBには何も作成されません。その前にその例外がスローされます。上記の私のポストにいくつかのログ情報を追加しました。 – systemoutprintln

+0

IDの列名をVehicleのIdフィールドに追加しないようにしてください。 @Id @Column(name = "ID") public int getId(){ return this.id; } – Cuga

1

私はこのために遅すぎると思いますが、何か他のものを探すときに質問に遭遇しました。

問題は、Embeddableクラスがテーブルにマップされないことです。EmbeddableオブジェクトはデータベースにIDがありません。

このため、MovementDataテーブルは生成されません。

私はあなたが埋め込みの意味を混同していると思います。以前のコメント作成者が述べたように、VehicleとMovementDataはOneToOneの関係にあり、埋め込み注釈は削除する必要があります。車両が取り外された場合、MovementDataも削除されていることを確認するには、カスケード除去ルールが必要な場合があります。

関連する問題