1. ホーム
  2. java

[解決済み] Hibernate JPA シーケンス(非Id)

2022-05-10 06:08:04

質問

あるカラムにDBシーケンスを使用することは可能ですか? が識別子でない、あるいは複合識別子の一部でない場合、DBシーケンスを使用することができますか? ?

私はjpaプロバイダとしてhibernateを使用しています。私は、識別子の一部ではないものの、(シーケンスを使用して)生成された値を持ついくつかのカラムを持つテーブルを持っています。

私が欲しいのは、シーケンスを使用してエンティティの新しい値を作成することで、シーケンスのカラムは NOT (主キーの一部)であることです。

@Entity
@Table(name = "MyTable")
public class MyEntity {

    //...
    @Id //... etc
    public Long getId() {
        return id;
    }

   //note NO @Id here! but this doesn't work...
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "myGen")
    @SequenceGenerator(name = "myGen", sequenceName = "MY_SEQUENCE")
    @Column(name = "SEQ_VAL", unique = false, nullable = false, insertable = true, updatable = true)
    public Long getMySequencedValue(){
      return myVal;
    }

}

では、こうすると

em.persist(new MyEntity());

の場合、idは生成されますが mySequenceVal プロパティもJPAプロバイダによって生成されます。

物事を明確にするために、私は ハイバーネート の値を生成するために mySequencedValue プロパティの値を生成します。Hibernateがデータベースから生成された値を処理できることは知っていますが、プロパティの値を生成するのに、トリガーやHibernate自身以外のものを使用したくありません。Hibernateが主キーの値を生成できるのであれば、なぜ単純なプロパティの値を生成できないのでしょうか?

どのように解決するのですか?

この問題に対する答えを探していたところ、偶然にも このリンク

Hibernate/JPAは、非IDプロパティに対して自動的に値を作成することができないようです。そのため @GeneratedValue アノテーションは @Id を併用することで、自動番号を作成することができます。

@GeneratedValue アノテーションは、データベースがこの値自体を生成していることをHibernateに伝えるだけです。

そのフォーラムで提案された解決策 (または回避策) は、次のような、生成された ID を持つ別のエンティティを作成することです。

エンティティ
public class GeneralSequenceNumber {
  ID
  @GeneratedValue(...)
  private Long number;
}

@Entity 
public class MyEntity {
  @Id ...
  private Long id;

  @OneToOne(...)
  private GeneralSequnceNumber myVal;
}