Chaves compostas com Hibernate
Este post vai mostrar como criar chaves compostas no Hibernate usando @IdClass e @Embeddable
Última atualização em: | 21678 Visualizações
Chaves compostas são utilizadas frequentemente em bancos de dados, principalmente em sistemas legados. Para facilitar para você criamos um tutorial para mostrar as maneiras que pode trabalhar com chaves compostas no hibernate.
Chave Simples com Hibernate
Uma chave simples, é quando se tem apenas um identificador na tabela, geralmente usa um valor sequencial (Sequence ou Generator) para gravar corretamente cada registro no Banco de Dados
. Um exemplo é mostrado na entidade Carro:
import javax.persistence.*;
@Entity
@Table(name="USUARIO")
public class Usuario {
@Id
private Long id;
...
}
Neste caso, tem apenas a coluna ID
como identificador na tabela USUARIO
e será o identificador de cada registro.
Chave composta
Quando se tem apenas um identificador único é fácil criar entidades e mapea-las para que representem o nosso banco de dados, mas quando precisamos trabalhar com identificadores compostos é um pouco diferente este mapeamento. Vamos considerar que um usuário deve pertencer a uma empresa e que seus campos chaves agora serão um identificador (campo id
) e a empresa (atributo empresa
) representada pela entidade Usuario
.
Dessa forma temos a seguinte situação:
import javax.persistence.*;
@Entity
@Table(name="USUARIO")
public class Usuario {
@Id
private Long id;
@Id
private Long empresa;
// [...]
}
Parece tudo certo? Parece mas isso não vai funcionar ainda! Dito isso vamos as opções que o Hibernate nos fornece para trabalhar com essas chaves compostas:
Chave composta com @IdClass
A nossa primeira opção é trabalhar com @IdClass
, esta opção permite escrever um código exatamente igual ao mostrado acima com o acrescimo da anotação @IdClass()
passando uma classe que trata o identificador por paramentro, exemplo:
// [...]
@IdClass(UsuarioId.class)
public class Usuario {
// [...]
Veja o exemplo completo sendo mostrado as duas classes utilizadas por está opção:
Usuario.java
import javax.persistence.*;
@Entity
@Table(name="USUARIO")
@IdClass(UsuarioId.class)
public class Usuario {
@Id
private Long id;
@Id
private Long empresa;
// [...]
}
E na classe UsuarioId.java, que vai representar a chave composta fica assim:
import java.io.Serializable;
public class UsuarioId implements Serializable {
private Long id;
private Long empresa;
// must have a default construcot
public UsuarioId() { }
public UsuarioId(Long id, Long empresa) {
this.id = id;
this.empresa = empresa;
}
// getter e setter + equal e hasCode
}
Note que, todos os campos anotados com @Id na classe Usuario devem estar presentes na classe UsuarioId. Note ainda que é possível também utilizar @GeneratedValue na chave composta neste tipo de chave composta. No exemplo acima é possível adicionar @GeneratedValue ao atributo id.
Por último se estiver utilizando Spring Data
, crie os repositórios assim:
import org.springframework.data.jpa.repository.JpaRepository;
public interface ArtData extends JpaRepository<Usuario, UsuarioId> {
}
Chave composta com @Embeddable
Esta é a outra opção para trabalhar com chaves compostas com hibernate e confesso que é a minha forma preferida. Vamos estender esta forma. Primeiro vamos criar uma classe que será nosso id
, veja a classe:
import java.io.Serializable;
import javax.persistence.Embeddable;
@Embeddable
public class UsuarioId implements Serializable {
private Long id;
private Long empresa;
// must have a default construcot
public UsuarioId() { }
public UsuarioId(Long id, Long empresa) {
this.id = id;
this.empresa = empresa;
}
// getter e setter + equal e hasCode
}
A diferença entre esta classe UsuarioId para a anterior está na adição da anotação @Embeddable
adicionado a classe. Visto isso podemos partir para a nossa classe Usuario
.
import javax.persistence.*;
@Entity
@Table(name="USUARIO")
public class Usuario {
@EmbeddedId
private UsuarioId id;
//[...]
}
Nesta classe note que não utilizamos
@Id
como no exemplo anterior, apenas@EmbeddedId
informando que a classe que representa o identificador composto desta tabela é a classe UsuarioId dessa forma ficou mais simples a representação.
Por último se estiver utilizando Spring Data
, crie os repositórios assim:
import org.springframework.data.jpa.repository.JpaRepository;
public interface ArtData extends JpaRepository<Usuario, UsuarioId> {
}
Conclusão sobre chaves compostas com Hibernate
De maneira simples você pode trabalhar com chaves compostas no hibernate, apenas cabe a você saber qual forma considera ser melhor para seu caso ou sua necessidade.
Não esqueça, para que suas classes sejam 100% funcionais utilize os
getters
esetters
além doequals
ehashCode
, isso vai evitar problemas futuros que podem surgir, mas se quiser deixar seu código mais limpo recomendo ver este tutorial que escrevemos: Como deixar suas entidades limpas e completas
Não esqueca de deixar suas dúvidas nos comentários e compartilhar este post.