[quote=ataufo]Cara, na minha atual situação aceito sua solução com annotations. Nem o meu professor de java com 6 certificações conseguiu me ajudar com esse mapeamento !! Não sei mais oq faço.
Como ficaria com annotations ? Posso usar annotation só em uma classe e o mapeamento nas demais?[/quote]
Certificações não implicam em conhecimento com Hibernate…
O mapeamento que é feito com annotation pode ser feito tb com xml, eu so não sei faze-los com xml, alem de achar annotation muito melhor
com annotation ? ta abaixo… mas primeiros algumas observações importantes…
[color=red][size=18]leia com calma e atenção o código, ele ta bem comentado, e explicando o pq de quase tudo[/size][/color]
Se não entender algo da um toque
Grupo e Funcionario, devem definir corretamente equals e hashCode, assim como toda classe java o deve fazer.
como Integrante usa um Chave Composta, IntegrantePK é uma chave dessas, e esta bem definda, e como é um ID, não tem métodos sets, pois IDs de um tabela nunca são alterados eles são parametros fixos, que definem a integridade do registro, e por isso seus campos são defindos como final, pois eles nunca são alterados, ao constrario de uma chave com estrategia de Auto_incrimento, onde seu valor só aparece no memento da persistencia, um ID composto tem seu valor conhecido defindo desde o momento de sua criação, visto que ele é enviado pelo usuario…
Note porem, que os IDs de Grupo e Funcionário não precisam ser conhecidos para criar o objeto, porem suas instancias precisam existir e serem enviadas para criar o objeto Integrante…
Obs.: se precisar definir as formas de cascatas com Grupo e FUncionario a partir de Integrante, vc pode definir em @ManyToOne, de cada uma das propriedade e assim, definir por exemplo, que ao persitir um Integrante, que automaticamente seus Grupo e Funcionario sejam persistidos / atualizados
Duvida quanto a equals e hashCode ? de pq e como implementar ? => http://java-i9se.blogspot.com/2009/04/igualdade-em-java-equals-e-hashcode.html
Abaixo seguem as 2 classes mapeadas
1 - IntegrantePK.java: é uma classe Embedable, e portanto pode ser usado como um atributo de outra classe, e esta classe é que define a Chave Primaria composta por Grupo e Funcionario, note que esta classe não é uma entidade, é apenas um propriedade.
2 - Integrante.java: é a entidade propriamente dita, ela usa como ID a classe IntegrantePK, e vc deve mapear os outros atributos da tabela nesta entidade…
[code]@Embedable
public class IntegrantePK implements Serializable {
/**
* Um vez defino o Grupo ele nunca será alterado, portanto ele é defindo como final.
* Isso ocorre pq IDs nunca devem ser alterados.
*
* Obs.: O hibernate vai sobrescrever os método caso precise criar um IntegrantePK,
* e getGrupo estara seguramente enviando dados não nulos direto do banco.
*/
@ManyToOne
@JoinColumn(name=“id_grupo”)
private final Grupo grupo;
/**
* Um vez defino o Funcionario ele nunca será alterado, portanto ele é defindo como final.
* Isso ocorre pq IDs nunca devem ser alterados.<BR>
* <BR>
* Obs.: O hibernate vai sobrescrever os método caso precise criar um IntegrantePK,
* e getFuncionario estara seguramente enviando dados não nulos direto do banco.
*/
@ManyToOne
@JoinColumn(name="id_func")
private final Funcionario funcionario;
/**
* Não deve ser usado nunca, note que mesmo a implementação setando grupo e funcionario null
* que isso não fará diferença, pois só quem usará esse Construtor é o Hibernate e este já
* sobrescreve os métodos getGrupo() e getFuncionario() e portanto os valores das propriedades
* desta sub-classe é indiferente...
* @deprecated Construtor só existe para o hibernate poder instanciar
* não deve ser usado no projeto
*/
@Deprecated
protected IntegrantePK(){grupo = null; funcionario = null;} //visibilidade protected e @Deprecated
public IntegrantePK(Grupo grupo, Funcionario funcionario) {
if (grupo == null || funcionario == null)
throw new IllegalArgumentException("Grupo e Funcionário não pode ser nulos");
this.grupo = grupo;
this.funcionario = funcionario;
}
public Grupo getGrupo() {
assert(grupo != null);
return grupo;
}
public Funcionario getFuncionario {
assert(grupo != null);
return funcionario;
}
//é importante que não existe métodos "set"s pois é um ID e ids não são alterados.
/**
* Dois IDs serão iguais, quando seu funcionario e grupo forem iguais.
/
public @Override boolean equals(Object o) {
return o instance IntegrantePK && equals((IntegrantePK)o);
}
/*
* método interno, de teste de igualdade, other nunca deve ser enviado como null
* para não dar erro
* @param other o outro IntegrantePK que nunca poderá ser enviado como null.
*/
private boolean equals(IntegantePK other) {
assert(other != null);
return getGrupo().equals(other.getGrupo()) && getFuncionario().equals(other.getFuncionario());
}
public @Override int hashCode() {
int hash = 3;
hash += 11getGrupo().hashCode();
hash += 11getFuncionario().hashCode();
return hash;
}
}[/code]
[code]@Entity
//@Table(nome=“digiteOnomeAqui”) //descomente e edit o comentário caso precise definir o nome da tabela
public class Integrante implements Serializable {
/**
* É final, pois é um ID composto, que deve ser definido ao se criar uma instancia
* a partir de um Grupo e um Funcionario.
*/
@EmbeddedId
private final IntegrantePK id;
/**
* Não deve ser usado nunca, note que mesmo a implementação setando id null
* que isso não fará diferença, pois só quem usará esse Construtor é o Hibernate e este já
* sobrescreve o método getId() e portanto os valores das propriedades desta sub-classe
* é indiferente...
* @deprecated Construtor só existe para o hibernate poder instanciar
* não deve ser usado no projeto
*/
@Deprecated
protected Integrante() {id = null;}
public Integrante(IntegrantePK id) {
this.id = id;
}
public Inegrante(Grupo grupo, Funcionario funcionario) {
this(new IntegrantePK(grupo,funcionario));
}
/**
* Retorna o ID do integrante, composto por um Grupo e um Funcionario.
* É seguro que o ID nunca será null, pois este é defindo ao criar a classe.
*/
public IntegrantePK getId() {
assert(id != null);
return id;
}
public Grupo getGrupo() {
return getId().getGrupo();
}
public Funcionario getFuncionario() {
return getId().getFuncionario();
}
//mais uma vez, é importante que os métodos acima não tenham "set"s
//pois ele fazem parte do ID que é construido junto com o objeto, e configurando
//no momento da construção da instancia.
/**
* Dois Integrantes serão iguais se, e somente se, seus IDs forem iguais.
* @see IntegrantePK#equals(Object)
/
public @Override boolean equals(Object o) {
return o instanceof Integrante && equals((Integrante)o);
}
/*
* método interno, de teste de igualdade, other nunca deve ser enviado como null
* para não dar erro
* @param other o outro Integrante que nunca poderá ser enviado como null.
*/
private boolean equals(Integrante other) {
assert(other != null);
return getId().equals(other.getId());
}
public @Override int hashCode() {
return getId().hashCode();
}
}[/code]