我想用一个@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不会刷新?
答案 0 :(得分:1)
看来这个Hibernate属性只是Hibernate的一个提示。请参阅here和Hibernate ORM Docs,他们在哪里说
除非你明确地刷新(),否则绝对没有保证 关于Session何时执行JDBC调用,只有订单执行 它们被执行了。
更多信息,FlushMode.ALWAYS enum value Javadoc表示
在每次查询之前刷新会话。这几乎总是不必要和低效的。
我不确定“查询”是否仅表示数据库查询(读取)或任何类型的操作,包括插入,更新和删除。
如果我是你,我会在第一次更新后明确发出session.flush()
电话。我知道声明方式更清晰,但有时命令式编程会使您的业务更安全。
答案 1 :(得分:0)
强制此会话刷新。必须在提交事务并关闭会话之前在工作单元结束时调用(取决于flush模式,Transaction.commit()调用此方法)。
在使新对象持久化flush()然后清除()会话时,为了控制第一级缓存的大小。
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();
IT指出当 Tx.commit(); 发生时,将调用Flush函数。甚至无需编写该功能。