Considero que isso @EmbeddedId
provavelmente é mais detalhado, porque @IdClass
você não pode acessar todo o objeto de chave primária usando qualquer operador de acesso ao campo. Usando o que @EmbeddedId
você pode fazer assim:
@Embeddable class EmployeeId { name, dataOfBirth }
@Entity class Employee {
@EmbeddedId EmployeeId employeeId;
...
}
Isso fornece uma noção clara dos campos que compõem a chave composta, porque todos eles são agregados em uma classe que é acessada através de um operador de acesso a campos.
Outra diferença com @IdClass
e @EmbeddedId
é quando se trata de escrever HQL:
Com @IdClass
você escreve:
selecione e.name em Funcionário e
e com @EmbeddedId
você tem que escrever:
selecione e.employeeId.name em Funcionário e
Você precisa escrever mais texto para a mesma consulta. Alguns podem argumentar que isso difere de uma linguagem mais natural como a promovida por IdClass
. Mas na maioria das vezes, entender diretamente a partir da consulta que um determinado campo faz parte da chave composta é uma ajuda inestimável.
@IdClass
mesmo que prefira@EmbeddedId
na maioria das situações (soube disso em uma sessão de Antonio Goncalves. O que ele sugeriu é que poderíamos usar o@IdClass
caso de o composto classe de chave não é acessível ou vem de outro módulo ou legado código onde não podemos adicionar uma anotação .Em esses cenários@IdClass
nos dará uma forma como a nossa.@IdClass
anotação dada pelo @Gaurav é a razão que as listas de especificação JPA ambos os métodos de criação de uma chave composta ..@IdClass
e@EmbeddidId
Existem três estratégias para usar uma chave primária composta:
@Embeddable
e adicione à sua classe de entidade uma propriedade normal para ele, marcada com@Id
.@EmbeddedId
.@Id
e marque sua classe de entidade@IdClass
, fornecendo a classe de sua classe de chave primária.O uso de
@Id
com uma classe marcada como@Embeddable
é a abordagem mais natural. A@Embeddable
tag pode ser usada para valores incorporáveis de chave não primária de qualquer maneira. Ele permite que você trate a chave primária composta como uma propriedade única e permite a reutilização da@Embeddable
classe em outras tabelas.A próxima abordagem mais natural é o uso da
@EmbeddedId
tag. Aqui, a classe de chave primária não pode ser usada em outras tabelas, pois não é uma@Embeddable
entidade, mas nos permite tratar a chave como um atributo único de alguma classe.Por fim, o uso das anotações
@IdClass
e@Id
permite mapear a classe de chave primária composta usando propriedades da própria entidade correspondentes aos nomes das propriedades na classe de chave primária. Os nomes devem corresponder (não há mecanismo para substituir isso) e a classe de chave primária deve respeitar as mesmas obrigações que as outras duas técnicas. A única vantagem dessa abordagem é sua capacidade de "ocultar" o uso da classe de chave primária da interface da entidade envolvente. A@IdClass
anotação usa um parâmetro de valor do tipo Classe, que deve ser a classe a ser usada como chave primária composta. Todos os campos que correspondem às propriedades da classe de chave primária a serem usados devem ser anotados@Id
.Referência: http://www.apress.com/us/book/9781430228509
fonte
Eu descobri uma instância em que eu tinha que usar EmbeddedId em vez de IdClass. Nesse cenário, há uma tabela de junção que possui colunas adicionais definidas. Tentei resolver esse problema usando o IdClass para representar a chave de uma entidade que representa explicitamente as linhas na tabela de junção. Não consegui fazê-lo funcionar dessa maneira. Felizmente, "Java Persistence With Hibernate" possui uma seção dedicada a este tópico. Uma solução proposta era muito semelhante à minha, mas utilizava o EmbeddedId. Modelei meus objetos após os do livro que agora se comportam corretamente.
fonte
Tanto quanto eu sei se o seu PK composto contém FK, é mais fácil e mais simples de usar
@IdClass
Com
@EmbeddedId
você tem que definir o mapeamento para sua coluna FK duas vezes,@Embeddedable
uma vez e outra como, por exemplo,@ManyToOne
onde@ManyToOne
deve ser somente leitura (@PrimaryKeyJoinColumn
) porque você não pode ter uma coluna definida em duas variáveis (possíveis conflitos).Então você precisa definir seu FK usando o tipo simples
@Embeddedable
.No outro site
@IdClass
, é possível lidar com essa situação com muito mais facilidade, conforme mostrado em Chaves Primárias por meio dos Relacionamentos OneToOne e ManyToOne :Exemplo de anotação de identificação JPA 2.0 ManyToOne
Exemplo de classe de identificação JPA 2.0
fonte
Eu acho que a principal vantagem é que poderíamos usar
@GeneratedValue
o ID ao usar o@IdClass
? Tenho certeza de que não podemos usar@GeneratedValue
para@EmbeddedId
.fonte
Chave composta não deve ter uma
@Id
propriedade quando@EmbeddedId
é usada.fonte
Com o EmbeddedId, você pode usar a cláusula IN no HQL, por exemplo:
FROM Entity WHERE id IN :ids
onde id é um EmbeddedId, ao passo que é difícil obter o mesmo resultado com o IdClass, você deve fazer algo comoFROM Entity WHERE idPartA = :idPartA0 AND idPartB = :idPartB0 .... OR idPartA = :idPartAN AND idPartB = :idPartBN
fonte