TransWikia.com

Problema ao inserir objeto com ManyToOne JPA

Stack Overflow em Português Asked by codigoalvo on November 20, 2021

Vou tentar exemplificar meu problema com classes mais simples do que na minha aplicação:

Tenho por exemplo a classe Principal e uma classe Item. Em Principal, tenho uma propriedade do tipo Item anotada com ManyToOne, que mapeio no banco apenas pelo id_item na minha tabela Principal.

Ao criar uma instância da classe principal na interface web da minha aplicação, eu seleciono uma instância de Item em um “select” que tem apenas o id e o nome do Item (Imagine que item tem várias outras propriedades que não enviei para o client da aplicação). Ao selecionar um Item para associar à Principal, Atribuo uma nova instância de Item ao Principal e seto o Id deste item corretamente nessa instancia.
envio então Principal para o lado server da aplicação e persisto usando JPA com o Insert.

Porém, ao recuperar a lista de Principais do banco, meu novo item não tem a descrição de Item nem as demais propriedades que deveria ter. Foi gravado tudo corretamente no banco, uma vez que se eu fizer um select, está lá, na minha linha 1 da tabela principal tem o id_item = 3 por exemplo referente ao item 3 corretamente cadastrado na tabela Item. Mas o JPA não traz os demais dados de Item.
É como se ele tivesse criado uma nova instância em cache do Item 3 contendo apenas o id e usa esta na listagem dos Principais.

Aí, tentei resolver este problema adicionando cascade=CascadeType.ALL na anotação ManyToOne do Item na classe Principal. Porém, ao fazer isso, tenho uma mensagem de erro ao tentar salvar o Principal contendo o Item apenas com o Id, dizendo que o Item está desatachado. (java.sql.SQLException: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist:pacote.Item)

Eu consigo imaginar 2 soluções para o problema:
1) Passar o objeto Item inteiro para o client da aplicação e devolvê-lo inteiro associado ao Principal no momento de Salvar o Principal.
2) Buscar no banco o objeto Item pelo id da instancia de Item que veio do client e associar esta instância do banco ao Principal antes de persistir o novo Principal ao banco.

Imagino que ambas devam funcionar, embora não tenha testado, mas a primeira solução, gera trafego adicional na rede, e a segunda, acessos extras ao banco.

Existe alguma terceira opção?

Se minha explicação não ficou clara o bastante com a explicação com as classes fictícias, a minha aplicação está no github em github.com/codigoalvo/lab-rest e as classes em questão são Transação como Principal e Categoria e Conta como Item.

One Answer

Acho que nem é possível a primeira opção, seria muita gabiarra, só se o objeto estiver na sessão. Mas eu faria com a segunda opção. Você pega o que o usuário selecionou no campo do select, busca no banco de dados o objeto referente ao que ele selecionou e atribiu à instância de Principal.

Answered by Sidney on November 20, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP