JPA deleta depois de inserir

17 respostas
F
Pessoal, estou quebrando a cabeça aqui com jpa. Tenho um relacionamento OnetoMany de juiz pra lotações o caso é que depois de inserir uma ou mais lotações para um juiz após persistir o hibernate insere depois deleta as lotações.
@Entity
@Table(name = "juiz")
public class Juiz implements Serializable  {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Integer id;
    @Column(name = "j_ds_nomejuiz")
    private String nome;
    @Column(name = "j_ds_tipojuiz")
    private String tipo;
    @Column(name = "matricula")
    private String matricula;
    @ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST})
    @JoinTable(name = "juiz_vara", joinColumns = @JoinColumn(name = "id_juiz"),
    inverseJoinColumns = @JoinColumn(name = "id_vara"))
    @OrderBy(value = "numero")
    private Set<Vara> varas;

    @OneToMany(mappedBy = "juiz",  fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @OrderBy(value = "dataInicio DESC")
    
    private Set<JuizVara> juizVaras;

    @OneToMany(mappedBy="juiz",fetch=FetchType.LAZY,cascade=CascadeType.ALL)
    @OrderBy(value="dataInicio")
    private Set<Afastamento> afastamentos;

    public Juiz() {
        if(juizVaras==null){
            juizVaras=new HashSet();
        }
    }
O código na classe juiz.
@Entity
@Table(name = "juiz_vara")
public class JuizVara implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id_juiz_vara")
    private Integer id;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_juiz")
    private Juiz juiz;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_vara")
    private Vara vara;
     @Column(name = "jv_dt_inicio")
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date dataInicio;
      @Column(name = "jv_dt_fim")
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date dataFim;
    @Column(name = "jv_cd_motivo")
    private String motivo;
O código da classe lotação cujo nome é JuizVara.

Alguém teria um luz? Já mudei a coleção juizVaras List, depois retornei pra Set.

17 Respostas

R

Kd o código que insere?

F
public String cadastrar() {

        try {
            JuizDAO jDAO = new JuizDAO();
            JuizVaraDAO jvDAO=new JuizVaraDAO();
            jDAO.getConexao().getTransaction().begin();
            juiz=jDAO.getConexao().merge(juiz);
            jDAO.getConexao().persist(juiz);
            for (JuizVara jvaux : juizVaras) {
                if (juiz.getId() == null) {
                    jvaux.setJuiz(juiz);
                }
                jvaux=jvDAO.getConexao().merge(jvaux);
                jvDAO.getConexao().persist(jvaux);
                //juiz.getJuizVaras().add(jvaux);

            }
            jDAO.getConexao().getTransaction().commit();
            //jDAO.inserirEditar(juiz);

            limpar();
            JSFUtil.setaMensagemInfo("Cadastro/Edição efetuado com sucesso!");
        } catch (Exception e) {
            JSFUtil.setaMensagemError("Erro no cadastro: " + e.getMessage());
        }


        return null;
    }
De tanto tentar já está nesse código grande aí... mas o resultado está sendo o mesmo:
Hibernate: select juiz0_.id as id2_1_, juiz0_.matricula as matricula2_1_, juiz0_.j_ds_nomejuiz as j3_2_1_, juiz0_.j_ds_tipojuiz as j4_2_1_, afastament1_.id_juiz as id5_3_, afastament1_.id_afastamento as id1_3_, afastament1_.id_afastamento as id1_1_0_, afastament1_.data_fim as data2_1_0_, afastament1_.data_inicio as data3_1_0_, afastament1_.id_juiz as id5_1_0_, afastament1_.tipo_afastamento as tipo4_1_0_ from juiz juiz0_ left outer join afastamento afastament1_ on juiz0_.id=afastament1_.id_juiz where juiz0_.id=? order by afastament1_.data_inicio asc
Hibernate: insert into juiz_vara (jv_dt_fim, jv_dt_inicio, id_juiz, jv_cd_motivo, id_vara) values (?, ?, ?, ?, ?)
Hibernate: delete from juiz_vara where id_juiz=?
R

Pq vc dá um merge e depois um persist em juiz?

F

Foi de tanta tentativa e erro…
Como vc sugeriria que eu fizesse?

F
Só consegui um resultado melhor com o código seguinte, mas acho que poderia ser melhor:
public String cadastrar() {

        try {
            JuizDAO jDAO = new JuizDAO();
            JuizVaraDAO jvDAO=new JuizVaraDAO();
            jDAO.getConexao().getTransaction().begin();
            juiz=jDAO.getConexao().merge(juiz);
            jDAO.getConexao().persist(juiz);
            jDAO.getConexao().getTransaction().commit();
            jvDAO.getConexao().getTransaction().begin();
            for (JuizVara jvaux : juizVaras) {
                if (juiz.getId() == null) {
                    jvaux.setJuiz(juiz);
                }
                jvaux=jvDAO.getConexao().merge(jvaux);
                jvDAO.getConexao().persist(jvaux);
                //juiz.getJuizVaras().add(jvaux);

            }
            jvDAO.getConexao().getTransaction().commit();
            //jDAO.inserirEditar(juiz);

            limpar();
            JSFUtil.setaMensagemInfo("Cadastro/Edição efetuado com sucesso!");
        } catch (Exception e) {
            JSFUtil.setaMensagemError("Erro no cadastro: " + e.getMessage());
        }


        return null;
    }

Só consigo a inserção após fechar a transação pelo DAO do objeto JuizVara. O resultado é o que segue:
[/code]
Hibernate: select vara0_.id as id0_, vara0_.v_ds_cidade as v2_0_, vara0_.v_ds_competencia as v3_0_, vara0_.v_ds_localizacao as v4_0_, vara0_.v_id_numerovara as v5_0_ from vara vara0_
Hibernate: select juiz0_.id as id2_1_, juiz0_.matricula as matricula2_1_, juiz0_.j_ds_nomejuiz as j3_2_1_, juiz0_.j_ds_tipojuiz as j4_2_1_, afastament1_.id_juiz as id5_3_, afastament1_.id_afastamento as id1_3_, afastament1_.id_afastamento as id1_1_0_, afastament1_.data_fim as data2_1_0_, afastament1_.data_inicio as data3_1_0_, afastament1_.id_juiz as id5_1_0_, afastament1_.tipo_afastamento as tipo4_1_0_ from juiz juiz0_ left outer join afastamento afastament1_ on juiz0_.id=afastament1_.id_juiz where juiz0_.id=? order by afastament1_.data_inicio asc
Hibernate: delete from juiz_vara where id_juiz=?
Hibernate: insert into juiz_vara (jv_dt_fim, jv_dt_inicio, id_juiz, jv_cd_motivo, id_vara) values (?, ?, ?, ?, ?)

[code]

eu achei que dando apenas um merge em juiz o jpa faria tudo...

R

fabiodamasceno4:
Foi de tanta tentativa e erro…
Como vc sugeriria que eu fizesse?

Algumas mudanças que eu faria:

  • Usar um Dao Genérico pra não ter que ficar abrindo as conexões em cada DAO;
  • Tirar esse merge,e usar só persist;
F

Se usar apenas o persist, ele diz que o objeto é transient e dá erro…

todos os meus DAOs herdam de um DAO Genérico, chamado GenericDAO. A questão é que usando apenas o DAO do juiz, teoricamente o JPA já deveria persistir os objetos JuizVara não?
Segue código do DAO:

package br.jus.jfba.substituicaojuizes.persistencia.jpa.dao;

import br.jus.jfba.substituicaojuizes.vo.Juiz;
import br.jus.jfba.utils.jpa.dao.GenericDAO;
import java.util.List;
import javax.persistence.Query;

/**
 *
 * @author ba393303
 */
public class JuizDAO  extends GenericDAO<Juiz, Integer> {

    @Override
    public Class<Juiz> getEntityClass() {
        return Juiz.class;
    }


    @Override
    public List<Juiz> listar() {

        Query dynaQuery = getConexao().createQuery("FROM Juiz j order by j.nome");
        return dynaQuery.getResultList();
    }
    public List<Juiz> listar(String matricula) {

        Query dynaQuery = getConexao().createQuery("FROM Juiz j where j.matricula like :matricula");
        if (matricula==null){
            matricula="";
        }
        dynaQuery.setParameter("matricula", matricula);
        return dynaQuery.getResultList();
    }

}
R

Qual a mensagem de erro usando apenas persist?

F
R

e se vc usar apenas o DAO de Juiz,como vc mesmo comentou?

R

Outra coisa:Já que o relacionamento é bi-direcional,vc precisa ter isso:

juiz.setVaras(juizVaras);
F

raf4ever:
Outra coisa:Já que o relacionamento é bi-direcional,vc precisa ter isso:

juiz.setVaras(juizVaras);

o juiz.setVaras tem como parâmetro um Set<Varas> e juizVaras é o List<JuizVara> não há compatibilidade…

R

fabiodamasceno4:
raf4ever:
Outra coisa:Já que o relacionamento é bi-direcional,vc precisa ter isso:

juiz.setVaras(juizVaras);

o juiz.setVaras tem como parâmetro um Set<Varas> e juizVaras é o List<JuizVara> não há compatibilidade…

Uai,então tem q ser compativel

F

O juizVaras é uma coleção que representa o histórico de lotações que o Juiz teve, fica vinculado a Rich:DataTable, já o Varas é apenas mapeamento da relação.

F

raf4ever:
Outra coisa:Já que o relacionamento é bi-direcional,vc precisa ter isso:

juiz.setVaras(juizVaras);

Rapaz, vc me deu uma idéia com essa dica e parece que resolveu… Deixa eu fazer mais uns testes aqui… Se positivo eu posto o código de como ficou…

F
Velho, tá funcionando, segue o código de como ficou, eu precisava setar as varas que é o outro lado do relacionamento... por nota esse método inserirEditar fica no GenericDAO e ele nada mais faz que dar um merge no objeto:
public String cadastrar() {

        try {
            JuizDAO jDAO = new JuizDAO();

            for (JuizVara jvaux : juizVaras) {
                if (juiz.getId() == null) {
                    jvaux.setJuiz(juiz);
                }
                if(juiz.getJuizVaras()==null){
                    juiz.setJuizVaras(new HashSet());
                }
                
                if (juiz.getVaras()==null){
                    
                    juiz.setVaras(new HashSet());
                }
                juiz.getVaras().add(jvaux.getVara());
                juiz.getJuizVaras().add(jvaux);
                

            }

            jDAO.inserirEditar(juiz);
            
           
            
            

            limpar();
            JSFUtil.setaMensagemInfo("Cadastro/Edição efetuado com sucesso!");
        } catch (Exception e) {
            JSFUtil.setaMensagemError("Erro no cadastro: " + e.getMessage());
        }


        return null;
    }
R

:thumbup:

Criado 18 de janeiro de 2011
Ultima resposta 18 de jan. de 2011
Respostas 17
Participantes 2