Nesse
post eu vou falar sobre o mapeamento de
chaves compostas no Hibernate.
É
comum aparecer situações aonde precisamos de uma chave composta para garantir a
unicidade de um registro, e o Hibernate trabalha isso de uma forma simples,
tratando os campos que compõem a chave primária como um objeto separado
embutido no objeto principal.
A classe que será embutida no objeto principal e que tem as propriedades
que juntas compõem a chave primária deve ser anotada com @Embeddable. Essa classe não pode ser usada separada da classe principal, pois o
Hibernate não trata ela como uma @Entity. Na classe principal, ao invés da anotação @id será usada a
anotação @EmbeddedId.
Vou
usar o exemplo da Cidade e UF pois acho simples de compreender. Vamos ver o
código:
Vamos
começar pela classe principal, que é a classe Município, o sequencial é a
classe SeqMunicipio e o equals e hashCode são construídos em
cima dele.
@Entity
public class Municipio {
@EmbeddedId
private SeqMunicipio seqMunicipio;
@Column(name = "DSC_MUNICIPIO")
private String dscMunicipio;
@Column(name = "CEP")
private Long cep;
@ManyToOne
@JoinColumn(name = "COD_UF", referencedColumnName = "COD_UF")
private UnidadeFederacao codUF;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ( ( seqMunicipio == null ) ? 0 : seqMunicipio.hashCode() );
return result;
}
@Override
public boolean equals( Object obj ) {
if ( this == obj )
return true;
if ( obj == null )
return false;
if ( getClass() != obj.getClass() )
return false;
Municipio other = (Municipio) obj;
if ( seqMunicipio == null ) {
if ( other.seqMunicipio != null )
return false;
} else if ( !seqMunicipio.equals( other.seqMunicipio ) )
return false;
return true;
}
}
Agora
vamos a classe que contém a chave composta. Ela contém a serialização, o equals
e o hashCode, um construtor vazio, e os métodos get’s and setter’s, além é
claro das propriedades que compõem a chave composta.
@Embeddable
public class SeqMunicipio implements Serializable {
private static final long serialVersionUID = 6576422530023818928L;
@Column(name = "COD_MUNICIPIO")
private Integer codMunicipio;
@Column(name = "COD_UF")
private Integer CodUnidadeFederacao;
public SeqMunicipio() {
}
public SeqMunicipio( Integer codMunicipio, Integer codUnidadeFederacao ) {
super();
this.codMunicipio = codMunicipio;
CodUnidadeFederacao = codUnidadeFederacao;
}
public Integer getCodMunicipio() {
return codMunicipio;
}
public void setCodMunicipio( Integer codMunicipio ) {
this.codMunicipio = codMunicipio;
}
public Integer getCodUnidadeFederacao() {
return CodUnidadeFederacao;
}
public void setCodUnidadeFederacao( Integer codUnidadeFederacao ) {
CodUnidadeFederacao = codUnidadeFederacao;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ( ( CodUnidadeFederacao == null ) ? 0 : CodUnidadeFederacao.hashCode() );
result = prime * result + ( ( codMunicipio == null ) ? 0 : codMunicipio.hashCode() );
return result;
}
@Override
public boolean equals( Object obj ) {
if ( this == obj )
return true;
if ( obj == null )
return false;
if ( getClass() != obj.getClass() )
return false;
SeqMunicipio other = (SeqMunicipio) obj;
if ( CodUnidadeFederacao == null ) {
if ( other.CodUnidadeFederacao != null )
return false;
} else if ( !CodUnidadeFederacao.equals( other.CodUnidadeFederacao ) )
return false;
if ( codMunicipio == null ) {
if ( other.codMunicipio != null )
return false;
} else if ( !codMunicipio.equals( other.codMunicipio ) )
return false;
return true;
}
}
A próxima classe é
para vermos o uso de uma lista de objetos com id composto.
@Entity
public class UnidadeFederacao {
@Id
@Column(name = "COD_UF")
private Integer codUF;
@Column(name = "DSC_UF")
private String dscUF;
@Column(name = "SIGLA_UF")
private String siglaUF;
@OneToMany(mappedBy = "codUF", fetch = FetchType.LAZY)
private List<Municipio> municipios;
}
Como
eu faço para buscar um município? Supondo que o município 512 seja Fortaleza e
o Estado 3 seja o Ceará faríamos assim:
SeqMunicipio seq = new
SeqMunicipio(512,3);
Municipio m = entityManager.find(Municipio.class,
seq);
E para salvar?
ResponderExcluirVocẽ preenche como uma composição, o hibernate se encarrega de salvar.
ResponderExcluir