Рубрики
Без рубрики

Составные первичные ключи в JPA

Узнайте, как настроить сущность JPA для более чем одного столбца первичного ключа, погрузившись в компромиссы между @EmbeddedId и @IdClass.

Автор оригинала: Vivek Balasubramaniam.

1. введение

В этом уроке мы узнаем о составных первичных ключах и соответствующих аннотациях в JPA.

2. Составные Первичные Ключи

Составной первичный ключ – также называемый составным ключом – представляет собой комбинацию двух или более столбцов, образующих первичный ключ для таблицы.

В JPA у нас есть два варианта определения составных ключей: Аннотации @IdClass и @EmbeddedId .

Чтобы определить составные первичные ключи, мы должны следовать некоторым правилам:

  • Составной класс первичного ключа должен быть открытым
  • У него должен быть конструктор no-arg
  • Он должен определить equals() и hashCode() методы
  • Он должен быть S сериализуемым

3. Аннотация IdClass

Допустим, у нас есть таблица с именем Account и в ней есть два столбца – AccountNumber, AccountType– , которые образуют составной ключ. Теперь мы должны нанести его на карту в JPA.

В соответствии со спецификацией JPA давайте создадим класс Account Id с этими полями первичного ключа:

public class AccountId implements Serializable {
    private String accountNumber;

    private String accountType;

    // default constructor

    public AccountId(String accountNumber, String accountType) {
        this.accountNumber = accountNumber;
        this.accountType = accountType;
    }

    // equals() and hashCode()
}

Далее давайте свяжем Идентификатор учетной записи класс с сущностью Учетная запись .

Для этого нам нужно аннотировать объект с помощью аннотации @IdClass . Мы также должны объявить поля из класса AccountId в сущности Account и аннотировать их с помощью @Id :

@Entity
@IdClass(AccountId.class)
public class Account {
    @Id
    private String accountNumber;

    @Id
    private String accountType;

    // other fields, getters and setters
}

4. Аннотация EmbeddedId

@EmbeddedId является альтернативой аннотации @IdClass .

Давайте рассмотрим другой пример, в котором мы должны сохранить некоторую информацию о Книге с названием и языком в качестве полей первичного ключа.

В этом случае класс первичного ключа BookID должен быть аннотирован с помощью @Embeddable :

@Embeddable
public class BookId implements Serializable {
    private String title;
    private String language;

    // default constructor

    public BookId(String title, String language) {
        this.title = title;
        this.language = language;
    }

    // getters, equals() and hashCode() methods
}

Затем нам нужно встроить этот класс в сущность B ook , используя @EmbeddedId :

@Entity
public class Book {
    @EmbeddedId
    private BookId bookId;

    // constructors, other fields, getters and setters
}

5. @IdClass против @EmbeddedId

Как мы только что видели, разница на поверхности между этими двумя заключается в том , что с помощью @IdClass нам пришлось указать столбцы дважды – один раз в AccountId и снова в Account. Но с @EmbeddedId мы этого не сделали.

Однако есть и другие компромиссы.

Например, эти различные структуры влияют на запросы JPQL, которые мы пишем.

Например, с @IdClass запрос немного проще:

SELECT account.accountNumber FROM Account account

С помощью @EmbeddedId мы должны сделать один дополнительный обход:

SELECT book.bookId.title FROM Book book

Кроме того, @IdClass может быть весьма полезен в тех местах, где мы | используем составной ключевой класс, который мы не можем изменить.

Наконец, если мы собираемся получить доступ к частям составного ключа по отдельности, мы можем использовать @IdClass, но в местах, где мы часто используем полный идентификатор в качестве объекта, предпочтительнее использовать @EmbeddedId .

6. Заключение

В этой краткой статье мы рассмотрим составные первичные ключи в JPA.

Как всегда, полный код этой статьи можно найти на Github .