Hibernate saveorUpdate方法问题

时间:2011-01-09 12:49:26

标签: hibernate

我正在尝试使用Hibernate(第一次使用数据库端)以及选择使用saveOrUpdate或Save.Update的最佳方法。 我有一个目的地POJO类和其他属性需要与目标实体一起更新。 我正在获取要导入的XML文件,我使用以下代码更新/保存目标实体及其属性类。

try{
        getSessionFactory().getCurrentSession().beginTransaction();
        getSessionFactory().getCurrentSession().saveOrUpdate(entity);
        getSessionFactory().getCurrentSession().getTransaction().commit();
        }
        catch(Exception e){
            getSessionFactory().getCurrentSession().getTransaction().rollback();
        }
        finally{
            getSessionFactory().close();
        }

一切正常,直到我使用相同的会话实例。但是当我使用相同的XML文件来更新某些属性的目标PO时,它会给我以下错误。

SEVERE: Duplicate entry 'MNLI' for key 'DESTINATIONID'
9 Jan, 2011 4:58:11 PM org.hibernate.event.def.AbstractFlushingEventListener performExecutions
SEVERE: Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114)
    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109)
    at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2242)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2678)
    at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)

我使用UUID作为Destination表的主键,在目标表中我有一个唯一的目标ID。但我可以理解,在secodn情况下,hibernate无法找到是否已经有一个条目数据库中的相同目标并尝试执行insert语句而不是更新。

一种可能的解决方案是我可以使用userid来检查是否已经存在具有给定id的目的地,并且基于我可以发出save或update命令的结果。 我的问题是,这可以通过任何其他好的方式来实现..?

提前致谢

1 个答案:

答案 0 :(得分:2)

saveOrUpdate()操作的语义如下(参见11.7. Automatic state detection):

  
      
  • 如果该对象在此会话中已经持久化,则不执行任何操作
  •   
  • 如果与会话关联的另一个对象具有相同的标识符,则抛出异常
  •   
  • 如果对象没有标识符属性,则保存()它
  •   
  • 如果对象的标识符具有分配给新实例化对象的值,则保存()它
  •   
  • 如果对象由or版本化,并且version属性值是分配给新实例化对象的相同值,则save()it
  •   
  • 否则更新()对象
  •   

因此,在导入XML文件时看起来主键或版本值会丢失。