¿Cómo crear una clave primaria compuesta que contenga un atributo @ManyToOne como @EmbeddedId en JPA?
Soypreguntando y respondiendo mi propia pregunta, pero no estoy asumiendo que tengo la mejor respuesta. Si tiene uno mejor, ¡publíquelo!
Preguntas relacionadas
Cómo establecer una referencia inversa de un @EmbeddedId en JPAapeo @hibernate donde embeddedid (?)JPA Clave compuesta con @ EmbeddedIdTengo un par de clases que están en una relación de agregación simple: cualquier instancia de una posee un número de instancias de la otra. La clase propietaria tiene algún tipo de clave primaria propia, y la clase propietaria tiene una clave de muchos a uno a través de la clave externa correspondiente. Me gustaría que la clase propia tenga una clave principal que comprenda esa clave externa más alguna información adicional.
En aras de la discusión, usemos esos favoritos perennes, Order y OrderLine.
El SQL se parece a esto:
-- '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)
);
Me gustaría mapear esto en Java usando JPA. El orden es trivial, y OrderLine se puede manejar con una @IdClass. @ Aquí está el código para ese - el código es bastante convencional, y espero que perdones mis idiosincrasias.
in embargo, el uso de @IdClass implica escribir una clase de ID que duplica los campos en la línea de pedido. Me gustaría evitar esa duplicación, así que me gustaría usar @EmbeddedId en su lugar.
Sin embargo, un ingenuo intento de hacer esto falla:
@Embeddable
public class OrderLineKey {
@ManyToOne
private Order order;
private int lineNo;
}
OpenJPA rechaza el uso de eso como un @EmbeddedId. No he probado otros proveedores, pero no esperaría que tuvieran éxito, porque la especificación JPA requiere que los campos que componen una clase ID sean básicos, no relaciones.
¿Entonces Que puedo hacer? ¿Cómo puedo escribir una clase cuya clave contiene la relación @ManyToOne, pero se maneja como un @EmbeddedId?