session.save()会立即同步状态到数据库,不解!

先看代码:
[code="java"]
public static void main(String[] args) throws Exception {
Configuration cfg = new Configuration();
SessionFactory sf = cfg.configure().buildSessionFactory();
Session session = sf.openSession();
//session.setFlushMode(FlushMode.MANUAL);
session.beginTransaction();
Parent p = new Parent();
p.setName("hello");
session.save(p);
System.out.println(1);
p.setName("world");
System.out.println(2);
session.getTransaction().commit();
session.close();
}
[/code]
这是我的一段测试代码,Parent类除了id以外仅有一个name属性,我执行这段代码,在控制台的输出是这样的:
[code="java"]
Hibernate: insert into parent (name) values (?)
1
2
Hibernate: update parent set name=? where id=?
[/code]
我的疑问是,为什么save方法会在打印语句之前将sql语句发送到数据库,是立即执行的,update方法的行为可以理解,提交事务时才同步到数据库,我记得以前save方法也不会立即发送sql的,而是flush或者commit时才会,我用的hibernate是3.3.1.GA版本的,难道是这个原因吗?
当我把session.setFlushMode(FlushMode.MANUAL)的注释去掉之后输出变成了这样:
[code="java"]
Hibernate: insert into parent (name) values (?)
1
2
[/code]
因为没有手动显式调用flush,所有后来的update并没有发出,但是save仍然是立即同步的,不解啊!

2个回答

楼主可以看下,save方法返回一个Serializable标识,就是因为这个,所以他要立即执行insert语句,如果想要不执行的话,可以试一下persist方法,persist方法是把一个瞬态的实例持久化,但是并不保证标识符被立刻填入到持久化实例中,标识符的填入可能被推迟到flush的时间。这里说的表示就是save方法返回的标识,由于save方法必须立刻把标识填入持久化实例中,所以,它会立刻执行insert语句。
不知道我说的楼主是否明白。希望对楼主有帮助

这里补充下,如果用persist方法,不像insert立即执行,就要把这个方法的调用放到事务外,不管是save还是persist只要是放在事务里都会触发insert语句的立即执行。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!