Apagar N objetos com hibernate

4 respostas
J

Olá pessoal,

Estou com o seguinte problema:

Tenho um objeto X que contém uma lista de objetos Y, que por sua vez contém uma lista de objetos Z.

Preciso apagar todos esses objetos, com cascade… porém gostaria de fazer sem trazê-los em memoria:
Por exemplo:
HQL:

Quando apagasse este objeto X, o hibernate já removesse as listas dos objetos que compõe este objeto.

Sei que o hibernate irá trazer em memória para fazer o DELETE, mas alguém tem alguma sugestão de como fazer isso sem trazer os objetos memória? Ou alguma maneira com que melhore a performance? Preciso usar HQL. não posso chumbar Instruções sql ali.

Desde já obrigado.

4 Respostas

Lavieri

Com a lista em modo LAZY, ele não vai chamar a lista a não ser que vc faça getYs() ou getZs()
e como o cascade mode é REMOVE... quando vc remove 1... o hibernate vai remover todo o resto...

bom... não vou escrever os getters e setter pra minimizar código... faça assim

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import static javax.persistence.CascadeType.REMOVE;
import static javax.persistence.FetchType.LAZY;
import javax.persistence.OneToMany;

public class X implements Serializable {
    @Id
    @GeneratedValue
    private Integer id;
    
    @OneToMany(cascade=REMOVE, mappedBy = "x", fetch = LAZY)
    private List<Y> ys = new ArrayList<Y>(0);
}
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import static javax.persistence.CascadeType.REMOVE;
import static javax.persistence.FetchType.LAZY;
import javax.persistence.OneToMany;

public class Y implements Serializable {
    @Id
    @GeneratedValue
    private Integer id;

    @ManyToOne(fetch=LAZY)
    @JoinColumn(name="x_id", nullable=false, referencedColumnName="id")
    private X x;

    @OneToMany(cascade=REMOVE, mappedBy = "y", fetch = LAZY)
    private List<Z> zs = new ArrayList<Z>(0);
}
import java.io.Serializable;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import static javax.persistence.FetchType.LAZY;

public class Z implements Serializable {
    @Id
    @GeneratedValue
    private Integer id;

    @ManyToOne(fetch=LAZY)
    @JoinColumn(name="y_id", nullable=false, referencedColumnName="id")
    private Y y;
}
J

Lavieri,

Obrigado por me responder.

Mas seguinte… meu relacionamento está todo montado e aparentemente correto. Quando tenho um objeto em mãos já persistido ele apaga na boa, agora quando gero a instrução para remoção em lotes como:

me retorna um erro de violação de chave. Pois o hibernate gera a instrução para remoção do objeto X. A instrução para seus depentendes ele não gera.

Se dou um:

ele me retorna todo o conjunto de objetos, inclusive os que estão pendurados.

Tem alguma idéia o porquê disso?

Mais uma vez obrigado.

Lavieri

se o fetch for LAZY ele não retorna os pendurados, so retorna os objetos da consulta… os pendurados ele só retorna c vc tentar verificar o seu valor ^^ pq o Hibernate usa reflection, e caso vc tente olhar o valor, é nessa hora q ele carrega a lista dos pendurados…

c vc colocar fetch para LAZY ele so vai mostrar a consulta…

quanto a sua string de delete… não sei c vou acertar, mais deveria ser algo assim

J

Lavieri,

Obrigado pelas respostas…

Acho que agora estou no caminho certo… ainda está dando um erro de parser, diz que tem uma vírgula que ele não espera… mas isso me viro aqui…

valeu cara, mais uma vez obrigado.

Criado 23 de março de 2009
Ultima resposta 23 de mar. de 2009
Respostas 4
Participantes 2