Duvida JPA

6 respostas
josimarsis

Olá galera surgiu a seguinte duvida. Tenho duas entidades cabeçalho da venda (CabVenda) e parcelas (Parcelas)

//Entidade CabVenda codigoCabVenda; descricao; valor;

//Entidade Parcelas codigoParcelas; codigoCabVenda; qtdParcelas; valor;
Ou seja eu posso ter varias parcelas para uma venda. Eu preencho a entidade CabVenda que precisa ser passada como chave estrangeira para a entidade Parcelas, porém a entidade CabVenda não possui um codigo ainda. E se eu faço o seguinte:

cabVenda = manager.merge(cabVenda);
A entidade CabVenda passa a ter o codigo, porem ela fica detached (fora do contexto de transação) como resolver isso?
Obrigado…

6 Respostas

G

Vejo que muita gente não consegue entender a idéia de JPA de trabalhar com associaçao de objetos e não mais com as chaves diretamente. Mas te explico melhor.

Em SQL natural você primeiro insere o objeto pai, pega a PK dele e insere os filhos com essa PK, correto? Ou seja, você trabalha com dados planos.

Em JPA você trabalha com objetos. No caso você tem uma Compra e uma lista de Parcelas. Sendo assim você salva a compra e via cascade o JPA salva as Parcelas e você nem sequer precisa saber o id de nenhum objeto. Entendeu?

public class Compra {
    @Id
    @GeneratedValue ...
    private Long id;

    @OneToMany(cascade=CascadeType.ALL)
    private List<Parcela> parcelas; /* aqui associa aos filhos */
}
public class Parcela {
    @Id
    @GeneratedValue ...
    private Long id;

   @ManyToOne
   private Compra compra; /* aqui associa ao objeto pai, e não na PK direta */
}

Não sei se fui bem claro. Se você não entendeu, por favor, me explique tua dúvida. O correto é você apenas instanciar os objetos, e o JPA salva toda a hierarquia para você.

josimarsis

garcia-jj sou novato no JPA, me desculpe mais eu não consegui entender! Teria como vc exemplificar como eu salvaria estas 2 entidasdes? E outra duvida minha é quando um objeto é datached eu consigo fazer ele ficar managed?

G

josimarsis, o fórum é exatamente para isso, hehehehe. Porém aconselho a ler um pouco mais sobre JPA. Tem muita documentação pela internet.

Há basicamente dois estatos: deatached e managed. Deatached é quando o objeto esta solto na aplicação. Um exemplo é quando você faz new do objeto e insere alguns dados, mas AINDA não salvou. Quando você salvar via EntityManager.merge ele fica managed. Quando você carrega um objeto via EntityManager.find ele é managed.

Note que na associação de Compra e Parcela há um cascade.ALL. Isso significa que os eventos do pai são propagados para o filho, sendo assim se você salvar Compra ele vai salvar também toda a lista de Parcela.

Porém note que ela é bidirecional. Ou seja, a compra sabe suas parcelas e parcela sabe quem é a compra. Nesse caso, baseado nas minhas duas classes, vou exemplificar:

Compra c = new Compra();
List<Parcela> parcelas = new ArrayList();

Parcela primeira = new Parcela();
primeira.setValor(100);
primeira.setCompra(c);
parcelas.add(primeira);

Parcela segunda = new Parcela();
segunda.setValor(110);
segunda.setCompra(c);
parcelas.add(segunda);

c.setParcelas(parcelas);

em.merge(c); // aqui salva a compra e as parcelas por causa do cascade.all
josimarsis

Vou testar aqui. É o seguinte eu percebi que quando as entidades estão configuradas com ascade.ALL elas perdem a integridade referencial do banco de dados. Como resolver isso?

meu msn é [email removido]

Grato…

G

josimarsis:
Vou testar aqui. É o seguinte eu percebi que quando as entidades estão configuradas com ascade.ALL elas perdem a integridade referencial do banco de dados. Como resolver isso?

meu msn é [email removido]

Grato…

Não deveria perder a integridade. Creio que isso deve ser feito uma inspeção mais a fundo na aplicação. O ideal é analisar os comandos SQL que ele imprime no console.

josimarsis

garcia-jj deu certo aqui muito obrigado agora tenho que ver o pq quando uso o cascade.ALL meu banco perde a integridade referencial!

Criado 7 de outubro de 2009
Ultima resposta 7 de out. de 2009
Respostas 6
Participantes 2