No tutorial do Hibernate ele explica como criar e proteger relacionamentos bi-direcionais. Só ficou a seguinte dúvida:
Pessoas tem eventos e Eventos tem pessoas.
private Set participants = new HashSet();
protected void setParticipants(Set participants) {
this.participants = participants;
}
protected Set getParticipants() {
return participants;
}
public void addParticipant(Person p) {
participants.add(p);
p.events.add(this); // é! isso funciona para protected...
}
public void delParticipant(Person p) {
participants.remove(p);
p.events.remove(this);
}
Beleza. Não tem como ninguém modificar o set participants sem passar pelo add e pelo del.
Só que eu quero ter acesso ao Set para listar os participantes, isto é, quero ter um método publico getParticipants(). Só que aí a segurança é perdida, pois qualquer um poderia meter um participante no set depois de charmar getParticipants().
Soluções:
No getParticipants() fazer return Collections.unmodifiableSet(participants); (NAO FUNCIONA NO HIBERNATE!)
Erro: Exception in thread “main” org.hibernate.AssertionFailure: collection was not processed by flush()
No getParticipants() dar um clone no Set antes de retornar. Não testei isso, mas se a lista for muito grande isso deve ser uma bosta. Ainda mais que o Hibernate tá acessando essa função toda hora!
Criar um outro método público e deixar o getParticipants() privado mesmo. Ex:
public Set getParticipantsSet() {
return Collections.unmodifiableSet(participants);
}
Mas aí o nome vai está fora do padrão JavaBean e vou ter que fazer: user.participantsSet na camada view.
Deixar aberto mesmo e confiar que ninguem vai adicionar um participante por fora.
Talvez nem precise criar o MeuArraYList… acho que se vc fazer qualquer tipo de cas com uma lista que não pode ser modificado sempre acontecerá este erro!
Isso é uma opção do hibernate mesmo. Você tem que escolher de qual lado atualizar. Isso é para não violar as espectativas que temos dos pojos.
Eu tenho o habito de escrever unit tests e evitar usar qualquer API do hibernate nos meus POJOs. Usando apenas java.util não vou ter como garantir que as relações bidirecionais sejam preservadas sem escrever toneladas de código.
Bele, não faço isso e deixo meus pojos durante os testes sem isso. Quando eles estiverem sendo usados pelo hibernate, e tivessemos relacionamentos bidirecionais, ia dar um porrada de problemas.
Não tem problema sergio, se você seguir as recomendações anteriores do tutorial, e vc seguiu pelo visto. Ele não fala para nunca colocar os dois lados de um relacionamento cuidando de atualizá-lo?