JPA deleta depois de inserir

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.

[code]@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();
    }
}

[/code]
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.

Kd o código que insere?

[code]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;
}[/code]

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=?

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

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

Só consegui um resultado melhor com o código seguinte, mas acho que poderia ser melhor:

[code]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;
}[/code]

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…

[quote=fabiodamasceno4]Foi de tanta tentativa e erro…
Como vc sugeriria que eu fizesse?[/quote]

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;

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();
    }

}

Qual a mensagem de erro usando apenas persist?

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

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

juiz.setVaras(juizVaras);

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

juiz.setVaras(juizVaras); [/quote]

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

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

juiz.setVaras(juizVaras); [/quote]

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

Uai,então tem q ser compativel

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.

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

juiz.setVaras(juizVaras); [/quote]

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…

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:

[code]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;
}[/code]

:thumbup: