Chaves compostas com Hibernate

Este post vai mostrar como criar chaves compostas no Hibernate usando @IdClass e @Embeddable

Wolmir Cezer Garbin por Wolmir Cezer Garbin - - Hibernate - TUTORIAL

Última atualização em: | 20886 Visualizações

Chaves compostas com Hibernate

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 e setters além do equals e hashCode, 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.


Publique seu post no Receitas de Código

Aguarde, estamos trabalhando para que você possa publicar sua postagem no Receitas de Código!