关于hibernate中save()的疑惑

我用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得本意。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值