Setar campo como null em relação OneToMany

5 respostas
R

Olá,

Eu estou com a seguinte dúvida, tenho uma relação OneToMany por exemplo:

class Many{

@ManyToOne

private One one;

}

class One{

@OneToMany(mappedBy=one)

private List many;

}

O que eu quero é que se eu deletar uma instância do One, ele apenas deixe como null no campo no Many. Se eu colocar um cascade remove, ele apaga.
Ex:
Um Many tem o campo one_id = 1;
Se eu deleto o one cujo id é 1, quero que o many fique one_id =null e não que ele seja deletado…

Agradeço ajuda…:slight_smile:

5 Respostas

Lavieri

hm... sem conhecer o Repositorio talvez seja dificil, pois no momento do delete, vc quer fazer um update... um forma seria assim...

class Many{ 

   @ManyToOne 
   private One one; 

   
} 

class One{ 

   @OneToMany(mappedBy="one") 
   private List<Many> many; 

   @PostRemove
   public void cascadeNull() {
       for(Many many : getManys())
             many.setOne(null);
       //o problema é que agora vc teria q ter acesso ao repositorio para salvar as modificações
       for(Many many : getManys())
             Repositories.marge(many);
   }
}

Ps.: da pra fazer de fora da classe tb, com uma classe de auditoria...

@EntityListeners(EscutaOne.class)
class One{ 

   @OneToMany(mappedBy="one") 
   private List<Many> many; 

}

class EscutaOne {
    @PostRemove
    public void cascadeNull(One one) {
         List<Many> manys = one.getManys();
         EntityManager em = EntityUtils.getEntityManager();
         em.getTransaction().begin();
         for(Many many : manys) {
              many.setOne(null);
              em.marge(many);
         }
         em.getTransaction().commit(); 
         //se o teu banco não suportar tranzações concorrentes o commit aqui dentro pode gerar erro, pois pode dar concorrencia entre as 2 tranzações...
    }
}
R

Obrigado pela resposta… :slight_smile:
Vou tentar aqui e depois aviso se funcionou legal…
Porém estou decepcionado, pensei que fosse mais simples!

R

Olá, consegui resolver o problema, vou postar aqui a solução para outros que tiverem o mesmo problema…
Como eu não queria que minha entidade ( POJO ) tivesse acesso a base de dados e nem criar uma classe apenas para tratar esse problema, resolvi da seguinte maneira.
Na própria entidade anotei um método com @PreRemove
Assim:

<blockquote>

@PreRemove

public void cascadeNull(One one) {

List manys = one.getManys();

for(Many many : manys) {

many.setOne(null);

}
} </blockquote>

Como é PreRemove essa operação vai ser efetuada entre o begin e o commit da deleção da entidade, exemplo:

<blockquote>

EntityManager em = EntityUtils.getEntityManager();

em.getTransaction().begin();

em.remove(one);

em.getTransaction().commit();

em.getTransaction().flush();</blockquote>

Ou seja, ela vai ser persistida. :slight_smile:

Lavieri

não queria, mas a verdade é que ela acessa a base de dados…

em.marge(many);   //<== se vc usa o EntityManager de dentro do POJO ele acessa a base de dados...

infelismente é isso… mais é a unica forma que encontrei de falar pra vc fazer…

R

Realmente…postei errado…
O meu POJO não tem esse merge não…vou até editar o post…

Criado 30 de março de 2009
Ultima resposta 4 de abr. de 2009
Respostas 5
Participantes 2