web-dev-qa-db-ja.com

サブクラスでHibernateのテーブルごとに個別のシーケンスを指定する

IDがマップされたスーパークラスで定義されている場合、Hibernateのテーブルごとに個別のシーケンスを指定する方法はありますか?

アプリケーション内のすべてのエンティティは、次のようにDataObjectというスーパークラスを拡張します。

@MappedSuperclass
public abstract class DataObject implements Serializable {
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "id")
    private int id;
}

@Entity
@Table(name = "entity_a")
public class EntityA extends DataObject { ... }

@Entity
@Table(name = "entity_b")
public class EntityB extends DataObject { ... }

これにより、すべてのエンティティが共有シーケンス(デフォルトはhibernate_sequence)を使用します。

私がやりたいのは、エンティティごとに個別のシーケンスを使用することです。たとえば、上記の例ではentity_a_sequenceentity_b_sequenceです。サブクラスでIDが指定されている場合は、@SequenceGeneratorアノテーションを使用して各エンティティのシーケンスを指定できますが、この場合、IDはスーパークラスにあります。 IDがスーパークラスにある場合、エンティティごとに個別のシーケンスを使用する方法はありますか?その場合、どのように使用しますか?

(関連する場合はPostgreSQL 8.3を使用しています)

24
gutch

この方法でやってみましたか?

@MappedSuperclass
public abstract class DataObject implements Serializable {
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idgen")
    @Column(name = "id")
    private int id;
}

@Entity
@SequenceGenerator(initialValue = 1, name = "idgen", sequenceName = "entityaseq")
@Table(name = "entity_a")
public class EntityA extends DataObject { 

}

@Entity
@SequenceGenerator(initialValue = 1, name = "idgen", sequenceName = "entitybseq")
@Table(name = "entity_b")
public class EntityB extends DataObject {

}

申し訳ありませんが、現在テストに必要な環境がありませんが、後で試してみます。

37

これは、すべてのJPAエンティティの抽象スーパークラスで使用します。

@Id
@GeneratedValue(generator = "pooled")
@GenericGenerator(name = "pooled", strategy = "org.hibernate.id.enhanced.TableGenerator", parameters = {
        @org.hibernate.annotations.Parameter(name = "value_column_name", value = "sequence_next_hi_value"),
        @org.hibernate.annotations.Parameter(name = "prefer_entity_table_as_segment_value", value = "true"),
        @org.hibernate.annotations.Parameter(name = "optimizer", value = "pooled-lo"),
        @org.hibernate.annotations.Parameter(name = "increment_size", value = "100")})
private Long id;

少し冗長ですが、prefer_entity_table_as_segment_valueを設定できます。つまり、サブクラスでidフィールドやジェネレーターアノテーションを繰り返す必要はありません。

7
Frans

IHMOこれを行うためのより良い方法があります:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

それは私のアプリで動作します。

1
Gumovvy Steven

TABLE生成stretergyはテーブルごとに個別のdbシーケンスを使用しますが、少し費用のかかる操作です