Why is hibernate deleting before saveOrUpdate ()?

3

I have a m: n relation between Column and Element. The entity that owns the relationship is Column. however when I'm saving a map of Columns, the following scenario occurs:

1) In the first iteration, Hibernate:

1.1) saves the first Column element

1.2) inserts the two elements in the column column_element

follows console:

Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into coluna (COLUNA_ALIAS_OPERACAO, COLUNA_CLAUSULA, COLUNA_DATA_DOIS, COLUNA_DATA_UM, COLUNA_EXIBE_FILTRO, COLUNA_EXIBE_NO_RELATORIO, COLUNA_EXIBE_TOTALIZADOR, COLUNA_INDEX, COLUNA_LABEL, COLUNA_NOME, COLUNA_OPERACAO, COLUNA_OPERACAO_REFERNCIANDO_ALIAS, RELATORIO_ID, COLUNA_TEMPO_DOIS, COLUNA_TEMPO_UM, COLUNA_TIPO_CLAUSULA_TEXTO, COLUNA_TIPO_EXIBICAO, COLUNA_TIPO_FILTRO, COLUNA_ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into coluna_elemento (COLUNA_ID, ELEMENTO_DOMINIO_ID) values (?, ?)
Hibernate: insert into coluna_elemento (COLUNA_ID, ELEMENTO_DOMINIO_ID) values (?, ?)

At this point, the column_element of my bank is like this:

coluna_id | elemento_id
    988        860
    988        861

So far everything is happening as expected.

2) In the second iteration, Hibernate:

2.1) saves the second column element

2.2) deleting the column element_element the previously saved element

2.3) inserts the two elements in the column column_element

As the output from the following console shows:

Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into coluna (COLUNA_ALIAS_OPERACAO, COLUNA_CLAUSULA, COLUNA_DATA_DOIS, COLUNA_DATA_UM, COLUNA_EXIBE_FILTRO, COLUNA_EXIBE_NO_RELATORIO, COLUNA_EXIBE_TOTALIZADOR, COLUNA_INDEX, COLUNA_LABEL, COLUNA_NOME, COLUNA_OPERACAO, COLUNA_OPERACAO_REFERNCIANDO_ALIAS, RELATORIO_ID, COLUNA_TEMPO_DOIS, COLUNA_TEMPO_UM, COLUNA_TIPO_CLAUSULA_TEXTO, COLUNA_TIPO_EXIBICAO, COLUNA_TIPO_FILTRO, COLUNA_ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: delete from coluna_elemento where COLUNA_ID=?
Hibernate: insert into coluna_elemento (COLUNA_ID, ELEMENTO_DOMINIO_ID) values (?, ?)
Hibernate: insert into coluna_elemento (COLUNA_ID, ELEMENTO_DOMINIO_ID) values (?, ?)

And so, the column_element element in the database looks like this:

coluna_id  |  elemento_id
   989           860
   989           861

When what I expected was the following:

coluna_id | elemento_id
  988          860
  988          861
  989          860
  989          861

What am I doing wrong?

The code where I save the column map is as follows:

private void salvaColunas() {
    for (Map.Entry<Integer, Coluna> entry : mapaColunas.entrySet()){
        Coluna coluna = entry.getValue();
        coluna.setRelatorio(relatorio);
        colunaDao.saveOrUpdate(coluna);
    }
}

The saveOrUpdate method of my Dao class is as follows:

public void saveOrUpdate(T obj) {
    Session session;
    Transaction tx = null; 
    try {
        session = HibernateUtil.getSessionFactory().getCurrentSession();
    }catch (HibernateException ex) {
        session = HibernateUtil.getSessionFactory().openSession();
    }
    try{
        tx = session.beginTransaction();
        session.saveOrUpdate(obj);
        tx.commit();
      } catch (RuntimeException e) {
          e.printStackTrace();
      } finally {
          if(session.isOpen()) {
              session.close();
          }
      }
 }

The mapping in the column class (already with equals and hashCode methods implemented) looks like this:

@ManyToMany(fetch= FetchType.LAZY, cascade= {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE})
@JoinTable(name="coluna_elemento",  joinColumns={
        @JoinColumn(name="COLUNA_ID", nullable=false, updatable=false )},
        inverseJoinColumns = {@JoinColumn(name = "ELEMENTO_DOMINIO_ID", nullable=false, updatable = false)  })
private Set<ElementoDominio> elementosDoDominio;

public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    result = prime * result + ((label == null) ? 0 : label.hashCode());
    result = prime * result + ((nome == null) ? 0 : nome.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Coluna other = (Coluna) obj;
    if (id == null) {
        if (other.id != null)
            return false;
    } else if (!id.equals(other.id))
        return false;
    if (label == null) {
        if (other.label != null)
            return false;
    } else if (!label.equals(other.label))
        return false;
    if (nome == null) {
        if (other.nome != null)
            return false;
    } else if (!nome.equals(other.nome))
        return false;
    return true;
}

And my Element class (which also has the equals and hashCode methods implemented) looks like this:

@ManyToMany(fetch = FetchType.LAZY, mappedBy = "elementosDoDominio")
private Set<Coluna> colunas;



@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    result = prime * result + ((label == null) ? 0 : label.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    ElementoDominio other = (ElementoDominio) obj;
    if (id == null) {
        if (other.id != null)
            return false;
    } else if (!id.equals(other.id))
        return false;
    if (label == null) {
        if (other.label != null)
            return false;
    } else if (!label.equals(other.label))
        return false;
    return true;
}

Both the Column and Element classes have more attributes, including the id that is generated by Hibernate. All with getters and setters.

Can someone help me? Thank you

    
asked by anonymous 23.02.2018 / 14:32

1 answer

0

Good, rather than set, I used a list and it did what I expected (the opposite of what is being suggested in Hibernate inserts optimization when there is relationship @ManyToMany ).

I put it in the Column class:

private List<ElementoDominio> elementosDoDominio;// ao inves do Set

and in the Element class I changed to:

private List<Coluna> colunas; // tb mudei para list

I do not know why, but it worked ... if anyone can explain, get a vote!

    
23.02.2018 / 19:06