Как создать составной первичный ключ, который содержит атрибут @ManyToOne в качестве @EmbeddedId в JPA?

Я задаю и отвечаю на свой вопрос , но я не думаю, что у меня есть лучший ответ. Если у вас есть лучший вариант, опубликуйте его!

Вопросы по теме:

у меня есть пара классов, которые находятся в простой связи агрегирования: любой экземпляр одного владеет некоторым количеством экземпляров другого. Класс-владелец имеет своего рода собственный первичный ключ, а класс-владелец имеет отношение «многие-к-одному» к этому классу через соответствующий внешний ключ. Я бы хотел, чтобы у принадлежащего ему класса был первичный ключ, включающий этот внешний ключ плюс некоторая дополнительная информация.

В качестве аргумента, давайте воспользуемся неизменными фаворитами Order и OrderLine.

SQL выглядит примерно так:

-- 'order' may have been a poor choice of name, given that it's an SQL keyword!
create table Order_ (
    orderId integer primary key
);
create table OrderLine (
    orderId integer not null references Order_,
    lineNo integer not null,
    primary key (orderId, lineNo)
);

Я хотел бы отобразить это на Java с помощью JPA. Порядок тривиален, и OrderLine можно обрабатывать с помощью @IdClass. Вот код для этого - код довольно обычный, и я надеюсь, вы простите мне мои особенности.

Однако использование @IdClass требует написания класса ID, который дублирует поля в OrderLine. Я бы хотел избежать этого дублирования, поэтому вместо этого я хотел бы использовать @EmbeddedId.

Однако наивная попытка сделать это не удалась:

@Embeddable
public class OrderLineKey {
    @ManyToOne
    private Order order;
    private int lineNo;
}

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

Итак, что я могу сделать? Как я могу написать класс, ключ которого содержит отношение @ManyToOne, но обрабатывается как @EmbeddedId?

8
задан Community 23 May 2017 в 12:17
поделиться