Why is Hibernate deleting before saveOrUpdate()?

Asked

Viewed 78 times

3

I have a m:n relationship between Column and Element. The entity that owns the relationship is Column. but when I’m saving a map of Columns, the following scenario happens:

1) In the first iteration, Hibernate:

1.1) saves the first element Column

1.2) inserts the two elements in the column element table

island following:

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 (?, ?)

Right now the column table 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) delete the previously saved element from the column

2.3)inserts the two elements in the column element table

How it shows the console output below:

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 then, the column table in the database looks like this:

coluna_id  |  elemento_id
   989           860
   989           861

When what I expected was this:

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 the equals and hashcode methods implemented) is thus :

@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) is 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 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

  • Do the following, put the updatable to true in the DoDominio. I think he might be trying to update the object instead of inserting a new one. Just a hunch..

  • I tried to insert the columns in a hashMap before saving in each interaction and saw that instead of the hash containing the two columns, it is containing only one. Which leads me to believe that my equals method is returning that the two columns are equal. but are not equal!!!

  • Hmm, but when it’s in the hash you have to implement the hashcode, it doesn’t use the equals. How is it implemented?

  • generated by the eclipse

  • Put the method here.

  • ready, put on!

  • You can’t imagine just by looking at this, I suggest you debug, put a breakpoint in the hashcode method and see if it is actually returning true in the second interaction and so it replaces the previous object.

  • I already did that. It returns false... therefore, they are not equal

  • I use a set and not a list.. I don’t need @Ordercolumn

Show 5 more comments

1 answer

0

well, instead of the set, I used a list and it did what I expected (the opposite of what is being suggested in Optimization Inserts Hibernate when there is relationship @Manytomany ).

placed 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 don’t know why, but it worked... if anyone can explain, you get a vote!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.