JPAで複合主キーを作成して処理する方法


108

同じデータエントリのバージョンが欲しいのですが。つまり、別のバージョン番号でエントリを複製したいのです。

id - Version 主キーになります。

エンティティはどのように見えますか?別のバージョンとどのように複製できますか?

id Version ColumnA

1   0      Some data
1   1      Some Other data
2   0      Data 2. Entry
2   1      Data

@IdClassアノテーションを使用するとき、もう1つのヒントは、@Columnアノテーションが(YourEntityRohitJanのサンプルコード内の)Entityクラスのフィールドに入る必要があることです。
KenSV 2017年

回答:


231

Embedded class2つのキーを含むを作成し、のようにそのクラスへの参照を持つことができEmbeddedIdますEntity

@EmbeddedId@Embeddableアノテーションが必要になります。

@Entity
public class YourEntity {
    @EmbeddedId
    private MyKey myKey;

    @Column(name = "ColumnA")
    private String columnA;

    /** Your getters and setters **/
}
@Embeddable
public class MyKey implements Serializable {

    @Column(name = "Id", nullable = false)
    private int id;

    @Column(name = "Version", nullable = false)
    private int version;

    /** getters and setters **/
}

このタスクを実行するもう1つの方法は、@IdClassアノテーションを使用して、両方をidに配置することIdClassです。これで@Id、両方の属性に通常の注釈を使用できます

@Entity
@IdClass(MyKey.class)
public class YourEntity {
   @Id
   private int id;
   @Id
   private int version;

}

public class MyKey implements Serializable {
   private int id;
   private int version;
}

4
@GeneratedvalueEmbeddedIdのId に使用できますか
Kayser '24

1
@Kayser。私の知る限りでは。いいえ。KeyClassインスタンスでそれらの値を明示的に設定し、Entityでそのキークラスインスタンスを設定する必要があります。
Rohit Jain

@Kayser。@GeneratedValue主キーのキー値の生成にのみ使用でき、複合キーの組み合わせを生成することはできません。
Rohit Jain

1
@RohitJainはただ1つのことです。埋め込みクラスを実際に公開することはできません(独自のファイルに公開する必要があります)
Lucas

1
@FastEngyウェイバックマシン経由で引き続きアクセスできます:web.archive.org/web/20170123035517/http : //uaihebert.com/…。この記事が取って代わられているようですweb.archive.org/web/20170202203555/http://uaihebert.com/...web.archive.org/web/20161014051056/http://uaihebert.com/...も消えました…
ラドラン2018年


5

キークラス:

@Embeddable
@Access (AccessType.FIELD)
public class EntryKey implements Serializable {

    public EntryKey() {
    }

    public EntryKey(final Long id, final Long version) {
        this.id = id;
        this.version = version;
    }

    public Long getId() {
        return this.id;
    }

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

    public Long getVersion() {
        return this.version;
    }

    public void setVersion(Long version) {
        this.version = version;
    }

    public boolean equals(Object other) {
        if (this == other)
            return true;
        if (!(other instanceof EntryKey))
            return false;
        EntryKey castOther = (EntryKey) other;
        return id.equals(castOther.id) && version.equals(castOther.version);
    }

    public int hashCode() {
        final int prime = 31;
        int hash = 17;
        hash = hash * prime + this.id.hashCode();
        hash = hash * prime + this.version.hashCode();
        return hash;
    }

    @Column (name = "ID")
    private Long id;
    @Column (name = "VERSION")
    private Long operatorId;
}

エンティティークラス:

@Entity
@Table (name = "YOUR_TABLE_NAME")
public class Entry implements Serializable {

    @EmbeddedId
    public EntryKey getKey() {
        return this.key;
    }

    public void setKey(EntryKey id) {
        this.id = id;
    }

    ...

    private EntryKey key;
    ...
}

別のバージョンとどのように複製できますか?

プロバイダから取得したエンティティを切り離し、エントリのキーを変更して、新しいエンティティとして永続化できます。


まずEntrykeyでidを定義することができますAUTOGENERATED。そのような何か @GeneratedValue(strategy = GenerationType.IDENTITY)
カイザー2012年

1
2つの長い主キーのハッシュを計算する方法も知りたいです。用としてhash及びprime方法でhashCodeクラスでEntryKeyそのアイデアはどこから来る、あなたは私を伝えることができますか?
Bruce Sun

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.