Hibernate和flush:update抛出重复键错误

时间:2014-01-28 07:45:34

标签: java mysql hibernate flush

我想用一个@Transaction方法将唯一键从一个实体对象更改为另一个:

Entity oldone=dao.getEntity(oldid);
Entity newone=dao.getEntity(newid);
oldone.setBarcode(null);
dao.update(oldone); //free the unique key "barcode"
newone.setBarcode(barcode);
dao.update(newone); //set the unique key "barcode"

但是此代码抛出:关键'条形码'的重复条目 Dubugging我发现在第一个dao.update之后数据库中没有任何变化。 我试着将hibernate flushmode设置为“always”但没有改变:

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
            <prop key="hibernate.show_sql">false</prop>             
            <prop key="hibernate.bytecode.use_reflection_optimizer">false</prop>
            <prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.search.autoregister_listeners">false</prop>
            <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
            <prop key="hibernate.flushMode">always</prop>
        </props>
    </property>
</bean>

为什么hibernate不会刷新?

2 个答案:

答案 0 :(得分:1)

看来这个Hibernate属性只是Hibernate的一个提示。请参阅hereHibernate ORM Docs,他们在哪里说

  

除非你明确地刷新(),否则绝对没有保证   关于Session何时执行JDBC调用,只有订单执行   它们被执行了。

更多信息,FlushMode.ALWAYS enum value Javadoc表示

  

在每次查询之前刷新会话。这几乎总是不必要和低效的。

我不确定“查询”是否仅表示数据库查询(读取)或任何类型的操作,包括插入,更新和删除。

如果我是你,我会在第一次更新后明确发出session.flush()电话。我知道声明方式更清晰,但有时命令式编程会使您的业务更安全。

答案 1 :(得分:0)

强制此会话刷新。必须在提交事务并关闭会话之前在工作单元结束时调用(取决于flush模式,Transaction.commit()调用此方法)。

在使新对象持久化flush()然后清除()会话时,为了控制第一级缓存的大小。

Batch Processing

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    session.save(customer);
    if ( i % 20 == 0 ) { //20, same as the JDBC batch size
        //flush a batch of inserts and release memory:
        session.flush();
        session.clear();
    }
}

tx.commit();
session.close();

Look this.

IT指出当 Tx.commit(); 发生时,将调用Flush函数。甚至无需编写该功能。