为什么在saveOrUpdate()之前删除hibernate?

时间:2018-02-23 16:30:56

标签: java hibernate

我在Column和Element之间有一个m:n的关系。拥有该关系的实体是Column。但是当我保存Columns地图时,会出现以下情况:

1)在第一次迭代中,Hibernate:

1.1)保存第一个Column元素

1.2)在column_element表中插入两个元素

跟随控制台:

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

此时我的数据库的table column_element是这样的:

coluna_id | elemento_id
988        860
988        861

到目前为止,一切都在按预期发生。

2)在第二次迭代中,Hibernate:

2.1)保存第二列元素

2.2)从column_element元素中删除先前保存的元素

2.3)在column_element_element

中插入两个元素

以下控制台的输出显示:

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

然后,数据库中的column_element元素如下所示:

coluna_id  |  elemento_id
   989           860
   989           861

当我的期望如下:

coluna_id | elemento_id
   988          860
   988          861
   989          860
   989          861

我做错了什么?

我保存列映射的代码如下:

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

我的Dao类的saveOrUpdate方法如下:

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

Column类中的映射(已经实现了equals和hashCode方法)如下所示:

@ManyToMany(fetch= FetchType.LAZY, cascade= {CascadeType.PERSIST,cadeType.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;

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

我的Element类(也有实现的equals和hashCode方法)如下所示:

@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;
}

Column和Element类都有更多属性,包括Hibernate生成的id。所有人都有吸气剂和制定者。

1 个答案:

答案 0 :(得分:0)

强烈建议避免使用@ManyToMany子句,您是否可以尝试通过显式实现关联表作为实体来更改它,并改为使用@manyToOne:

ElementoDominio类

@OneToMany(mappedBy="element")
private Set<ElementoDominio> elementosDoDominio;

Coluna课程

@OneToMany(mappedBy="colunas")
private Set<Coluna> colunas;

ElementoColuna [新实体]

    @ManyToOne
    @JoinColumn(name="element_id")
    private ElementoDominio element

    @ManyToOne
    @JoinColumn(name="colunas_ID")
    private Coluna colunas