2009-05-27 5 views
75

com.something.SuperClass ID列キー生成を使用することはできません:は(TABLE_PER_CLASS)<ユニオン・サブクラス>と

@Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public abstract class SuperClass implements Serializable { 
    private static final long serialVersionUID = -695503064509648117L; 

    long confirmationCode; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) // Causes exception!!! 
    public long getConfirmationCode() { 
     return confirmationCode; 
    } 

    public void setConfirmationCode(long confirmationCode) { 
     this.confirmationCode = confirmationCode; 
    } 
} 

をcom.something.SubClass:

@Entity 
public abstract class Subclass extends SuperClass { 
    private static final long serialVersionUID = 8623159397061057722L; 

    String name; 

    @Column(nullable = false) 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

を与えます私はこの例外を除いて:

Caused by: org.hibernate.MappingException: Cannot use identity column key 
generation with <union-subclass> mapping for: com.something.SuperClass 

IDの生成にはどのような方法が便利ですか? 私は自分の継承戦略を変更したくありません。

答えて

190

ここでの問題は、 "table-per-class"継承とGenerationType.Autoを混在させることです。 MsSQLのID列を考慮してください。列ベースです。 "table-per-class"戦略では、クラスごとに1つのテーブルを使用し、それぞれがIDを持ちます。

試してみてください。

@GeneratedValue(strategy = GenerationType.TABLE)

+1

パーフェクトソリューション。 さえ、Hibernateのフォーラムは、このソリューションを持っているように見えるdidnot、彼らは話題 https://forum.hibernate.org/viewtopic.php?p=2319244&sid=4493aa54d27d3f81a0e27ecbdda075ae –

+1

の周りに起こったこの問題は、MySQLのみ、またはその定期的にはです。 Table per classアプローチのビデオの1つを見ると、postgresが使用されているという点でうまくいきました – Prashant

+1

私は最近、Dropwizardアプリケーションをテストするときにこの問題に遭遇しました。私の場合は、セッション・ファクトリを作成するためにDWで使用されていたのと同じ設定オプションを使用することで対処しました。私は本当に "hibernate.id.new_generator_mappings"プロパティを設定することはそれを固定していることを確かめています。これはDW 0.7.0、Hibernate 4.3.1、DBはH2でした。 – sfitts

6

これは私が見た基盤となるデータベースとしてPostgreSQLのでユーチューブのチュートリアルを見ているので、データベースの方言特有の問題である場合、私は疑問に思うこと、ビデオランとsuccefullyアプリの生みの親デフォルトの@GeneratedValue私の場合(基礎となるデータベースはMySQL)、@ GeneratedValue戦略をZoidbeckが提案するようにGenerationType.TABLEに変更する必要がありました。ここで

はビデオです:私たちの場合はhttps://www.youtube.com/watch?v=qIdM4KQOtH8

+0

Postgresは継承を行うことができますので、これはデータベース特有のことかもしれません: http://www.postgresql.org/docs/8.1 /static/ddl-inherit.html ビデオにはスキーマの生成方法が説明されていません。だから、おそらくNHibernateのpostgres方言はそれ自身でそれを行うことができるか、代わりに手動で 'INHERITS'を追加する必要があります。実際に私は言うことができません。 – zoidbeck

+5

PostgreSQLでは、Hibernateはデフォルトで 'GenerationType.SEQUENCE'を使用します。それがそこで自動的に動作する理由です。 PostgreSQLの 'INHERITS'とはまったく関係ありません。 – Henning

+0

私は同じチュートリアルを使用していて、@Generatedを使用していたので、私はこの投稿を見たまでMySql.Spentを使って多くの時間をデバッグしていました。 –

2

、我々はDEVと生産とテストのためのインメモリHSQLDBデータベースのPostreSQLデータベースを使用しています。どちらの場合もシーケンスを使用してIDを生成しています。明らかにGenerationType.AUTOはデフォルトでSEQUENCEになっていますが、ローカルテストでは失敗しました(デフォルトでは、hsqldbのデフォルトになっていなければなりません)。

私たちのために働いた解決策は、明示的にGenerationType.SEQUENCEを使用してください。

-1

MySQLとPostgreSQLの間にSQL標準準拠があります。 PostgreSQL Postgresは、SQL92/99の優れたサブセットと、これらのサブセットに対するいくつかのオブジェクト指向機能を理解しています。 Postgresは、宣言的なSQLクエリ、サブクエリ、ビュー、マルチユーザサポート、トランザクション、クエリの最適化、継承、配列などの複雑なルーチンやルールを処理できます。異なるデータベース間でデータを選択することはできません。

MySQLはSQL92を基盤としています。無数のプラットフォームで動作します。 Mysqlは、異なるデータベースのテーブルを結合できるクエリを作成できます。 ANSI構文とODBC構文の両方を使用して、左右の外部結合をサポートします。そのリリースのMySQL 4.1以降、MySQLはサブクエリを扱います。リリース5でサポートされているビュー。

詳しくは、こちらをご覧ください。 http://www-css.fnal.gov/dsg/external/freeware/pgsql-vs-mysql.html

+0

これについては気にしないでくださいが、MySQLとPostgreSQLの比較(たとえHibernateのデフォルトが異なっていても)トピックと無関係です。 – mrts

2

ゾイドベックの答えに同意します。 あなたがに戦略を変更する必要があります。

@GeneratedValue(strategy = GenerationType.TABLE) 

しかし、それがすべてではありません、あなたは、抽象のテーブルの主キー列を保持するものを、新しいテーブルを作成する必要があります。

@Id 
@GeneratedValue(strategy = GenerationType.TABLE, generator = "ConfirmationCodeGenerator") 
@TableGenerator(table = "SEQUENCES", name = "ConfirmationCodeGenerator") 
public long getConfirmationCode() { 
    return confirmationCode; 
} 

にあなたのマッピングを変更し、データベースに新しいテーブルには、次のようになります。 enter image description here

を、あなたのアプリケーションを実行したとき、Hibernateはsequence_nameが、この中でエンティティ名(SuperClassになります行を挿入します例)およびsequence_next_hi_valueの値は、自動的にインクリメントされ、すべての実装サブクラスのテーブルの新しいレコードに使用されます。

0

継承には@MappedSuperclassを使用できます。

+0

答えのサンプルコードを追加できますか? –

関連する問題