Я задаю и отвечаю на свой вопрос , но я не думаю, что у меня есть лучший ответ. Если у вас есть лучший вариант, опубликуйте его!
Вопросы по теме:
у меня есть пара классов, которые находятся в простой связи агрегирования: любой экземпляр одного владеет некоторым количеством экземпляров другого. Класс-владелец имеет своего рода собственный первичный ключ, а класс-владелец имеет отношение «многие-к-одному» к этому классу через соответствующий внешний ключ. Я бы хотел, чтобы у принадлежащего ему класса был первичный ключ, включающий этот внешний ключ плюс некоторая дополнительная информация.
В качестве аргумента, давайте воспользуемся неизменными фаворитами 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?