出现问题:首先这段代码在action层,查询出RsLeave类后修改这个类的type属性(红色箭头所示),后面继续进行RsLeave关联类的查询(绿色箭头所示),程序运行后发现数据库中当前RsLeave中type值已经被修改,因此推出虽然表面进行只是查询,但其实内部也发生了更新操作。
解决办法:1:把修改type属性的操作放到所有查询操作后
2:在事物层的查询方法中添加事物为只读(@Transactional(readOnly=true))
问题分析:hibernate在做查询操作的时候会去查找session中当前类的属性值与关联类的属性值是否发生改变,如果发生改变则会进行更新操作。
2018-8-1:
今天被同事发现代码中又出现类似的bug问题,所以仔细的看了一下对应的hibernate源码实现。源码路径为:org.hibernate.internal.SessionImpl
/**
* detect in-memory changes, determine if the changes are to tables
* named in the query and, if so, complete execution the flush
*/
protected boolean autoFlushIfRequired(Set querySpaces) throws HibernateException {
errorIfClosed();
if ( ! isTransactionInProgress() ) {
// do not auto-flush while outside a transaction
return false;
}
AutoFlushEvent event = new AutoFlushEvent( querySpaces, this );
for ( AutoFlushEventListener listener : listeners( EventType.AUTO_FLUSH ) ) {
listener.onAutoFlush( event );
}
return event.isFlushRequired();
}