Dúvida Tabela com chave composta

Estudando o hibernate e fazendo uns testes com o mesmo no netbeans vi que quando tem uma tabela com uma chave composta tem que se criar uma classe para essa chave.
Alguém poderia explicar o motivo disto, porque ainda não ficou muito claro este conceito.

O motivo é pq o provedor de persistencia não tem como comparar + de 1 propriedade, então isso tem que ser feito explicitamente por vc…

O objeto PK que vc criar tem que implementar corretamente os métodos equals/hashCode para o funcionamento correto da aplicação…

é uma exigencia do JPA que toda entidade tenha uma chave primaria única… o Netbeans mapea a classe totalmente em separado, o que na minha opinião é ruim, pois vc acaba tendo que fazer algo como

entrada.getId().getPessoa();
entrada.getId().getHorario();

Forma que o netbeans mapea uma calsse dessas

@Entity public class Entrada implements Serializable { @EmbeddedId private EntradaPK id; @ManyToOne private Local local; private String observacao; //... métodos getters/setters }

[code]@Embeddable
public class EntradaPK implements Serializable {
private Pessoa pessoa;
private Date horario;

//…métodos getters/setters

private boolean isDefinido() { //o ID só se define quando há pessoa e horário
return getPessoa() != null && getHorario() != null;
}

public boolean equals(Object obj) {
if (!isDefinido())
return false; //se o proprio objeto não se define, ele não é igual a ninguem
if (!(obj instanceof EntradaPK)
return false;
EntradaPK other = (EntradaPK)obj;
return getPessoa().equals(other.getPessoa())
&& getHorario().equals(other.getHorario());
}

public int hashCode() {
if (!isDefinido()) //se não é definido, não há necessidade de calcular hash.
return super.hashCode();

  int h = 35;
  h = 35*h + getPessoa().hashCode();
  h = 35*h + getHorario().hashCode();
  return h;

}
}[/code]

você pode usar uma abordagem bem mais facil, no uso da classe, que é o @IdClass, com ele vc cria o objeto em separado, que mostra para o provedor de persistência como comparar 2 objetos, mas não estraga seu objeto

nesta segunda abordagem vc pode usar direto

entrada.getPessoa();
entrada.getHorario();

pois a classe é definida assim

@Entity @IdClass(EntradaPK.class) //aqui eu defindo a chave composta public class Entrada implements Serializable { @Id private Pessoa pessoa; //esse campo é parte da chave composta @Id private Date horario; //esse campo tambem @ManyToOne private Local local; private String observacao; //... métodos getters/setters }

vc continua tendo que escrever o EntradaPK, porem o objeto Entrada fica mais claro… e o objeto EntradaPK vai existir apenas para informar ao provedor de persistencia como comparar com equals e hashCode… e neste caso do uso de @IdClass o objeto EntradaPK não precisa ser anotado como @Embedable

Ps.: Se não entender equals/hahscode, entra no meu blog na minha assinatura q la tem explicações…