Não entendo porque o Hibernate não atualiza os objetos de forma adequada quando existe relacionamento entre classes… Vejam o exemplo:
Tenho 2 classes relacionadas com a seguinte associação:
@JoinColumn(name = “ALUNO_TURMA”, referencedColumnName = “TURMA_ID”)
@ManyToOne(optional = false)
private Turma turma;
@OneToMany(cascade = CascadeType.ALL, mappedBy = “turma”)
private List alunoList;
Ou seja, relacionamento 1-N entre Turma e Aluno.
Estou instanciando o objeto Aluno(aluno1), o objeto Turma(turma1) e definindo o objeto turma em aluno, assim:
aluno1.setTurma(turma1).
e depois persisto os 2 objetos com o metodo session.save.
Não entendo agora, como o poderoso hibernate, não atualiza os 2 objetos de forma a garantir a associação. O objeto aluno fica corretamente com a turma associada, quando eu dou um getTurma ele aparece a turma, mas o
problema está do outro lado. O objeto Turma deveria fazer constar em sua lista de alunos “alunoList”, o objeto aluno recem associado. Mas a lista fica VAZIA!!!
Só quando eu comitto a transação e depois dou um Session.refresh nos objetos, é que ele vai atualizar os objetos em ambos os lados! Só que eu preciso dessa lista “alunoList” atualizada, antes de comittar a operação, pois ainda existem outros operações a realizar antes do commit. O que Fazer? Porque nesse caso, o nosso Hibernate foge de seus principios de OO, não implementando a associação???
Tenta fazer
aluno1.setTurma(turma1);
turma1.getAlunos().add(aluno);
// salvar no DB
Outra coisa é, dentro do método turma1.getAlunos() cuidado para não retornar null ou então vai rolar null pointer.
E coloca o cascade persiste dos dois lados.
E ao chamar método de salvar, o ideal é salvar no objeto que for ManyToOne
a sua primeira opção acima resolve, mas não seria mais elegante e produtivo, ele fazer a atualização automatica só com o turma.set(Aluno)?
Imagina só se quando eu for trocar um aluno de uma turma para outra:
Vou ter que fazer 3 processos…
aluno1.setTurma(turma2);
turma2.getLista.add(aluno1);
turma1.getLista.remove(aluno1);
Não deveria existir uma maneira de ele atualizar tudo só com o save em aluno?? tudo automaticamente??
ja tentei o CASCADE dos 2 lados e dei um save nos 2 objetos…
Cara, isso não se trata de elegância mas sim de java básico.
Um relacionamento bidirecional correto existe quando existe uma referência em cada ponta do relacionamento.
O JPA/Hibernate funciona com o conceito java de referência e o desenvolvedor que deve ter conhecimento disso.
Leia esse post, vai te ajudar: @OneToMany e @ManyToOne Unidirecional e Bidirecional
Tudo bem que é JAVA básico, mas ele podia já fazer tudo encapsulado. Veja a lógica… Se estou salvando um objeto que faz parte de uma associação, nada mais justo ele fazer a atualização do outro lado, automaticamente… Tudo em busca da produtividade… Não é isso que ele prega?
Eles resolveram muito bem isso do lado da camada de Persistência, no BD. Mas e no lado dos objetos? Tenho que me virar fazendo manualmente?
[quote=Giordano_CE] Tudo bem que é JAVA básico, mas ele podia já fazer tudo encapsulado. Veja a lógica… Se estou salvando um objeto que faz parte de uma associação, nada mais justo ele fazer a atualização do outro lado, automaticamente… Tudo em busca da produtividade… Não é isso que ele prega?
Eles resolveram muito bem isso do lado da camada de Persistência, no BD. Mas e no lado dos objetos? Tenho que me virar fazendo manualmente?[/quote]Ou então não seja simples como você pensa. Do nosso lado é apenas fazer um set alguma coisa. Mais fácil e performático do que ele ter que utilizar reflection para manipular isso.
Imagine ele ter que utilizar reflection para uma lista de 50 objetos apenas para fazer o set em uma relação? Agora imagine para uma coleção de 500, 5000.
No se caso, pode ser que seja pequena a coleção. Mas o framework é utilizado por milhares de pessoas e isso beneficiaria algumas prejudicaria a outras.
Por isso q eles optam por deixar que um conceito básico de relacionamento seja utilizado por parte do desenvolvedor, do que prejudicar milhares de outras pessoas.
Corretissimo… Mas o problema é que nossos amigos desenvolvedores do Framework nao pensaram em usuarios com meu simples caso…
Que tal eles terem colocado um parametro opcional “@Refection”? Assim eu teria a opção de seta-lo true or false… Não foi assim que fizeram com os vários tipos de cascade, tipos de fetch, tipos de estrategia de generator ID, etc…
Não é para isso que existem os parametros de configuração? Atender os mais diversos usuarios e situações?
Analisando bem a fundo, caro amigo jakeFrog, Na minha opinião, não seria muito complexo, ao dar um save em um objeto persistente, o hibernate checar se há associação ligadas aquele objeto, e em caso positivo, ele realizar um update em todos os objetos que forem da classe que representa o outro lado da associação, que estiverem instanciados na memória.
Assim ele garantiria a integridade dos dados instaciados naquele momento.
Da mesma forma que ele criou a collection do outro lado, quando eu dei um save no objeto, porque nao atualizar a mesma collection, quando eu alterar ou excluir esse mesmo objeto?
É cara, desculpe mas não penso assim.
Você está vendo como facilitaria apenas o seu caso.
Eu entendo que no seu caso seria fácil, mas não vejo isso uma funcionalidade aplicável em grande escala.
Eu não disse que seria difícil fazer, mas sim perfomático. Reflection é uma operação custosa, não é algo que se pode optar e o tempo todo uma vez que pode ser evitado.
No seu caso é um relacionamento bidirecional, não se esqueça que pode existir uni-direcional. Essa funcionalidade que você gostaria de ver também iria influenciar.
Se eles implementarem isso e falar que não afetaria em nada, vou xingá-los muito por não terem feito isso ainda. Até hoje não afirmaram isso e nem ouvi rumos/boatos de que isso viria a ser implementado.
Bem, é a sua opinião e respeito. [=
Qualquer outra coisa estamos aí.
\o_