Як створити та обробити складений первинний ключ у 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анотації ще одна підказка, яку я знайшов, - це @Columnпримітка, яка повинна перейти до полів класу Entity ( YourEntityу зразковому коді RohitJan).
KenSV

Відповіді:


231

Ви можете зробити an Embedded class, який містить два ваші ключі, а потім мати посилання на цей клас, як 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 **/
}

Ще одним способом досягнення цього завдання є використання @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
Чи можна використовувати @Generatedvalueдля Id's EmbeddedId
Kayser

1
@Kayser. Наскільки мені відомо. Ні. Вам слід чітко встановити значення для них у вашому екземплярі KeyClass, а потім встановити цей екземпляр ключового класу у вашій сутності.
Rohit Jain

@Kayser. @GeneratedValueможе використовуватися лише для генерації ключових значень для первинного ключа, він не може генерувати комбінацію для складених ключів.
Рохіт Джайн

1
@RohitJain лише одне: ви фактично не можете оприлюднити вкладений клас (потрібно мати його власний файл, щоб бути загальнодоступним)
Лукас

1
@FastEngy Доступ до нього можна отримати через Wayback Machine: web.archive.org/web/20170123035517/http://uaihebert.com/… . Схоже, що цю статтю замінено веб - сайтом.archive.org/ web/ 20170202203555/ http : //uaihebert.com/… та web.archive.org/web/20161014051056/http://uaihebert.com/…, який також зник …
radlan

9

Клас MyKey повинен реалізувати, Serializableякщо ви використовуєте@IdClass


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;
    ...
}

Як я можу скопіювати його з іншою версією?

Ви можете від'єднати об'єкт, який отримано від постачальника послуг, змінити ключ Entry та зберегти його як новий об'єкт.


Так можна визначити ідентифікатор в Entrykey AUTOGENERATED. Одер щось подібне @GeneratedValue(strategy = GenerationType.IDENTITY)
Кайсер

1
Мені також цікаво, як обчислити хеш для 2 довгих первинних ключів. Що ж стосується hashі primeв методі hashCodeв класі EntryKey, ви можете сказати мені , де ця ідея виходить від?
Брюс нд

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.