<union-subclass>(TABLE_PER_CLASS)ではID列キー生成を使用できません


95

com.something.SuperClass:

@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を生成するための最良かつ最も便利な方法は何ですか?相続戦略を変えたくない。

回答:


229

ここでの問題は、「クラスごとのテーブル」の継承とを混在させることですGenerationType.Auto。MsSQLのID列について考えてみます。列ベースです。「クラスごとのテーブル」戦略では、クラスごとに1つのテーブルを使用し、それぞれにIDがあります。

試してください:

@GeneratedValue(strategy = GenerationType.TABLE)


2
完璧なソリューション。でも、Hibernateのこのソリューションを持っているように見えるdidnotフォーラム、そして彼らは、トピックの周りのつもりだったforum.hibernate.org/...を
春モンキー

1
クラスごとのアプローチのビデオの1つを見ると、この問題はMySqlのみまたはその定期的なものであり、postgresが使用されて問題なく機能していました
Prashant

1
Dropwizardアプリケーションをテストしているときに、最近これに遭遇しました。私の場合は、DWがセッションファクトリを作成するために使用したものと同じ構成オプションを使用するようにして対処しました。プロパティ "hibernate.id.new_generator_mappings"をtrueに設定することがそれを修正したものだと確信しています。これはDW 0.7.0、Hibernate 4.3.1、DBはH2でした。
2014年

1
それは完全に動作します。ただし、多くのクエリ(選択、挿入、更新)をトリガーし、ロックを維持して主キーの一意の値を生成するため、「TABLE」ID生成戦略を使用しないことを強くお勧めします。それで、もし私たちがちょっと大きな継承シナリオを持っているなら、これに対する代替の解決策は何でしょうか?それは確かにパフォーマンスに大きな影響を与えます。
MAC

8

これがデータベースの方言特有の問題かどうか疑問に思います。基盤となるデータベースとしてPostgreSQLを使用したYouTubeチュートリアルを見ると、ビデオの作成者がデフォルトの@GeneratedValueでアプリを正常に実行することがわかりました。私の場合(基盤となるデータベースはMySQLです)、@ GeneratedValue戦略をzoidbeckの提案どおりにGenerationType.TABLEに変更する必要がありました。

これがビデオです:https : //www.youtube.com/watch?v=qIdM4KQOtH8


:Postgresはあなたが、これはデータベース固有であることを正しいかもしれないので、継承を行うことができるであるpostgresql.org/docs/8.1/static/ddl-inherit.htmlスキーマを生成する方法を動画では説明していない(または私はそれを逃しました)。したがって、おそらくNHibernate postgres方言はそれ自体でそれを行うことができるか、代わりに手動で「INHERITS」を追加する必要があります。実際にはわかりません。
zoidbeck 2013年

6
PostgreSQLでは、Hibernateはデフォルトでを使用しますGenerationType.SEQUENCE。そこで自動的に機能します。PostgreSQL とはまったく関係ありませんINHERITS
ヘニング

私は同じチュートリアルを使用していて、この投稿を見るまでMySql.Spentを何度もデバッグしているため、@ Generatedを使用すると問題が発生しました
Deen John

5

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

@GeneratedValue(strategy = GenerationType.TABLE)

しかし、それだけではありません。抽象テーブルの主キーシーケンスを保持する新しいテーブルを作成する必要があります。マッピングを次のように変更します

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

また、データベースの新しいテーブルは次のようになります。 ここに画像の説明を入力してください

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


2

この例では、開発と本番にはPostreSQLデータベースを使用し、テストにはメモリ内hsqldbデータベースを使用します。どちらの場合も、IDを生成するためにシーケンスを使用しています。どうやらGenerationType.AUTOデフォルトSEQUENCEはpostgresになっていますが、ローカルテストでは失敗しました(hsqldbのデフォルトは別のものにする必要があります)。

したがって、私たちのために働いたソリューションは、明示的に使用しますGenerationType.SEQUENCE



0

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

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

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


これについては気にしないでください。ただし、MySQLとPostgreSQLの比較はトピックとは無関係だと思います(Hibernateのデフォルトが異なる場合でも)。
mrts 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.