Hibernate flush理解 - 勿忘心安
问题
在spring框架没有事务的情况下,通过hibernate的session.save(entity),无法将数据持久化至数据库中,即使强制刷新后(flush())后也同样如此。
原因
混淆了spring框架中事务和mysql事务的概念。对于增删改操作,必须commit后才能持久化至mysql数据库。若不commit,只有在同一个连接中才能看到最新的更改,对其他连接不可见。
扩展
Hibernate的flush
执行时会清除session缓存并向数据库发送SQL语句并执行,但此时如果数据库当前存在一个事务,数据库会先将这些SQL语句缓存起来,那么此时在数据库中是无法看到SQL语句执行结果的。除非执行commit提交了事务。只要没有执行commit()方法,就能通过rollback()方法进行回滚。
Hibernate的commit
执行时会先隐式调用flush()方法,再提交事务。执行之后无法rollback()进行回滚。即commit操作才是真正的将实体数据持久化至数据库。
总结
通过hibernate进行数据库连接时,autocommit默认是false,因此仅仅做flush()是无法将数据持久化至数据库的,必须显式调用commit方法。
而如果使用jdbcTemplate进行数据库连接的话,无需显式执行commit方法,因为此时autocommit默认为true。通过以下代码验证之:
Connection conn = DriverManager.getConnection(JdbcTest.URL, JdbcTest.USER, JdbcTest.PWD); // 通过JDBC进行连接SessionFactory sFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory(); Session session = sFactory.openSession(conn); // 使用jdbc的连接初始化hibernate的sessionSystem.out.println(session.connection().getAutoCommit()); // autoCommit默认为true