我用hibernate,save()一个对象,必须用事务才能持久化到数据库中,
用flush()就不成,hibernate的输出sql语句显示save成功
我看书上的说不是flush也可以把对象持久化到数据库中吗
是hibernate3强制用事务吗?
-------------------------------------------------------------------------------------
必须这样:
session.beginTransaction();
session.save(pojo);
session.getTransaction.commit();
才成。
这样:
session.save(pojo)
session.flush();
session.close();
就不能持久化到数据库中。
-------------------------------------------------------------------------------------
save的作用是把一个新的对象保存
而flush是操作的在持久状态的对象
-------------------------------------------------------------------------------------
看一下这个吧
http://blog.csdn.net/noove_001/archive/2007/10/26/1844537.aspx
-------------------------------------------------------------------------------------
你们说的都不对我觉得
现在没有任何异常
-------------------------------------------------------------------------------------
就是同样的save必须防在事务中才能持久化到数据库,flush就不成
session.save(pojo)只是把对象缓存起来了,但还没有提交事物,
session.flush();
session.close();
然后你就把对象从缓存中清除了,甚至关闭了session,肯定不能保存到数据库了啊。
-------------------------------------------------------------------------------------
事务还是需要的啦!
-------------------------------------------------------------------------------------
需要事务
-------------------------------------------------------------------------------------
必须显示提交
-------------------------------------------------------------------------------------
书上说,把持久化对象更新到数据库有三种方法啊:
flush()
session.close()
commit()
为什么flush()就不成呢
-------------------------------------------------------------------------------------
书上应该还有说数据的状态!
-------------------------------------------------------------------------------------
对数据库做insert操作不commit怎么行?
你commit的时候是手动提交
没有commit的时候是自动提交
-------------------------------------------------------------------------------------
好像session有个方法类似于setFlushMode
hibernate更新是事务提交。
flush是刷新缓存和数据库同步,一般hibernate会自动调用.
如果执行数据的增删改操作,就必须开启事务并提交.
-------------------------------------------------------------------------------------
setFlushMode 并不能解决这个问题
用对hibernate2不了解
刚才阅读了下源码
AbstractSaveEventListener类
298 source.getActionQueue().execute( insert );
从这开始正式进入保存逻辑,向后在单步跟踪不超过10层就可以看到sql了,下面这段代码就是可以保存进去的,
Java code
public static void main(String[] args) throws Exception {
SessionFactory sf=HibernateSessionFactory.getSessionFactory();
Session session=sf.openSession();
System.out.println(session.connection().getAutoCommit());
session.connection().setAutoCommit(true);
User u=new User();
u.setName("aaa");
session.save(u);
}
真正的原因是数据源conn默认的提交方式,hibernate不管这件事,大部分开源数据源都是默认false的
-------------------------------------------------------------------------------------
更进一步说明问题,下面代码也是可以保存成功的。因为jdbc默认是的conn提交方式是true,
Java code
public static void main(String[] args) throws Exception {
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
Connection conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs", "sa",
"11111111");
SessionFactory sf=HibernateSessionFactory.getSessionFactory();
Session session=sf.openSession(conn);
System.out.println(session.connection().getAutoCommit());
// session.connection().setAutoCommit(true);
User u=new User();
u.setName("aaa");
session.save(u);
}
-------------------------------------------------------------------------------------
楼上高手..俺崇拜你...
-------------------------------------------------------------------------------------
牛逼
-------------------------------------------------------------------------------------
我在20楼说的测试没有通过,我当时可以测晕了,我再检测下这种情况为什么不行。19楼那段是没问题的。
-------------------------------------------------------------------------------------
晕倒,其实没问题是我的p6spy搞混了,没有监听到sql,没问题,都没问题,脑子都糊涂了,该睡觉了,晕死。上面理论是正确的。
-------------------------------------------------------------------------------------
commit()用事务当然能持久化到数据库了
我的意思是说,书上说flush() session.close() 也可以把对象持久化到数据哭,但是不成,为什么
flush()
session.close()
commit()
-------------------------------------------------------------------------------------
session.flush(); 刷新 一般用于事务的触发器
需要commit() 提交才能 插入到数据库
-------------------------------------------------------------------------------------
hibernate的事务必须显示提交
flush只是把数据缓存了
然后session.close()
数据肯定是不能持久到数据库
-------------------------------------------------------------------------------------
19楼的高手,我测试了一下,你好像少了2步:
public static void main(String[] args) throws Exception {
SessionFactory sf=HibernateSessionFactory.getSessionFactory();
Session session=sf.openSession();
System.out.println(session.connection().getAutoCommit());
session.connection().setAutoCommit(true);
User u=new User();
u.setName("aaa");
session.save(u);
session.flush();
session.close();
}
-------------------------------------------------------------------------------------
在发表之前先讨论讨论
hibernate中的缓存清理有自动清理,就是当调用session.close()是它内部自己调用session.flash()方法进行缓存清理
还有就是手动调用session.flash()方法,适合、用于对数据进行增删改的操作
另外一种就是commit() 了
当session进行缓存清理时就对数据进行持久化到数据库,也就是执行所有已经准备好的sql了
在上面情况你同时用了三个缓存清理势必会出现一些问题的
要么用一种
那这么说delete的时候也应该能成功,但是事实是:
public void test(){
Session session = getSession();
User user = session.getUserById();
session.delete(user);
}
按照你说JDBC默认是自动提交事务,那么delete的时候也是吧,但是为什么数据库还是没有删掉?
包括更新的时候也是一样
-------------------------------------------------------------------------------------
我想hibernate默认提交的方式还是false,必须手动的去控制,但是为什么save方法就总是自动提交呢?请高手点解
因为我需要三个操作在同一个事务,但是save那里没办法保证,苦恼了好几个小时了
-------------------------------------------------------------------------------------
学习……
-------------------------------------------------------------------------------------
只有FLUSH可以提交前提是autocommit=true
无论connection.autocommit=ture还是false
采用session.save()session.close()是无法提交成功的。
当connection.autocommit=true 时,
session.flush()就 可以提交成功了。
无论connection.autocommit取值如何,采用事务是最保险的,也是hibernate得本意。