Considero que @EmbeddedId
probablemente sea más detallado porque con @IdClass
usted no puede acceder a todo el objeto de clave primaria utilizando ningún operador de acceso de campo. Usando el @EmbeddedId
puede hacer así:
@Embeddable class EmployeeId { name, dataOfBirth }
@Entity class Employee {
@EmbeddedId EmployeeId employeeId;
...
}
Esto proporciona una noción clara de los campos que forman la clave compuesta porque todos se agregan en una clase a la que se accede a través de un operador de acceso de campo.
Otra diferencia con @IdClass
y @EmbeddedId
es cuando se trata de escribir HQL:
Contigo @IdClass
escribes:
seleccione e.name de Employee e
y @EmbeddedId
contigo tienes que escribir:
seleccione e.employeeId.name de Employee e
Tienes que escribir más texto para la misma consulta. Algunos pueden argumentar que esto difiere de un lenguaje más natural como el promovido por IdClass
. Pero la mayoría de las veces, comprender desde la consulta que un campo dado es parte de la clave compuesta es de gran ayuda.
@IdClass
, aunque lo prefiero@EmbeddedId
en la mayoría de las situaciones (Tengo que saber esto de una sesión de Antonio Goncalves. Lo que sugirió es que podríamos usar el@IdClass
en caso de que el compuesto No se puede acceder a la clase de clave o viene de otro módulo o código heredado donde no podemos agregar una anotación. En esos escenarios@IdClass
nos dará una forma de hacerlo . ”@IdClass
anotación dada por @Gaurav sea la razón por la cual la especificación JPA enumera ambos métodos para crear una clave compuesta ...@IdClass
y@EmbeddidId
Hay tres estrategias para usar una clave primaria compuesta:
@Embeddable
y agregue a su clase de entidad una propiedad normal, marcada con@Id
.@EmbeddedId
.@Id
, y marque su clase de entidad con@IdClass
, proporcionando la clase de su clase de clave primaria.El uso de
@Id
con una clase marcada como@Embeddable
es el enfoque más natural. La@Embeddable
etiqueta se puede utilizar para valores incrustables de clave no primaria de todos modos. Le permite tratar la clave primaria compuesta como una sola propiedad, y permite la reutilización de la@Embeddable
clase en otras tablas.El siguiente enfoque más natural es el uso de la
@EmbeddedId
etiqueta. Aquí, la clase de clave primaria no se puede usar en otras tablas ya que no es una@Embeddable
entidad, pero nos permite tratar la clave como un atributo único de alguna clase.Finalmente, el uso de las anotaciones
@IdClass
y@Id
nos permite mapear la clase de clave primaria compuesta usando las propiedades de la propia entidad correspondiente a los nombres de las propiedades en la clase de clave primaria. Los nombres deben corresponder (no existe un mecanismo para anular esto), y la clase de clave primaria debe cumplir con las mismas obligaciones que con las otras dos técnicas. La única ventaja de este enfoque es su capacidad de "ocultar" el uso de la clase de clave primaria de la interfaz de la entidad que lo encierra. La@IdClass
anotación toma un parámetro de valor de Tipo de clase, que debe ser la clase que se utilizará como clave primaria compuesta. Todos los campos que corresponden a las propiedades de la clase de clave primaria que se utilizarán deben estar anotados con@Id
.Referencia: http://www.apress.com/us/book/9781430228509
fuente
Descubrí una instancia en la que tenía que usar EmbeddedId en lugar de IdClass. En este escenario, hay una tabla de unión que tiene columnas adicionales definidas. Intenté resolver este problema usando IdClass para representar la clave de una entidad que representa explícitamente filas en la tabla de unión. No pude hacerlo funcionar de esta manera. Afortunadamente, "Java Persistence With Hibernate" tiene una sección dedicada a este tema. Una solución propuesta era muy similar a la mía, pero en su lugar utilizaba EmbeddedId. Modelé mis objetos según los del libro, ahora se comporta correctamente.
fuente
Hasta donde sé, si su PK compuesto contiene FK, es más fácil y sencillo de usar
@IdClass
Con
@EmbeddedId
usted debe definir el mapeo para su columna FK dos veces,@Embeddedable
una vez y una vez, es decir,@ManyToOne
dónde@ManyToOne
debe ser de solo lectura (@PrimaryKeyJoinColumn
) porque no puede tener una columna configurada en dos variables (posibles conflictos).Por lo tanto, debe configurar su FK con un tipo simple
@Embeddedable
.En el otro sitio, el uso de
@IdClass
esta situación se puede manejar mucho más fácilmente, como se muestra en las claves principales a través de las relaciones OneToOne y ManyToOne :Ejemplo de anotación de identificación ManyToOne JPA 2.0
Ejemplo de clase de id JPA 2.0
fuente
Creo que la principal ventaja es que podríamos usar
@GeneratedValue
la identificación al usar el@IdClass
? Estoy seguro de que no podemos utilizar@GeneratedValue
para@EmbeddedId
.fuente
La clave compuesta no debe tener una
@Id
propiedad cuando@EmbeddedId
se usa.fuente
Con EmbeddedId puede usar la cláusula IN en HQL, por ejemplo:
FROM Entity WHERE id IN :ids
donde id es un EmbeddedId mientras que es difícil lograr el mismo resultado con IdClass, querrá hacer algo comoFROM Entity WHERE idPartA = :idPartA0 AND idPartB = :idPartB0 .... OR idPartA = :idPartAN AND idPartB = :idPartBN
fuente