hibernate save的时候必须启用事务,也就是必须
beginTransaction();
然后
commit();
要不然不会insert看孙卫琴.精通Hibernate:Java对象持久化技术详解上讲
调用save方法后,hibernate并不会立即insert,而是保存在缓存里,等清理缓存时再insert
什么时候清理缓存呢?
1、事务commit();
2、find方法(hibernate3被废)
3、显示调用flush();
而为什么不用事务,只是在save();后直接显示调用flush();还是没有insert呢?
参考csdn的一个帖子http://topic.csdn.net/u/20080603/19/d6918606-3a62-43a4-b63d-cd292242bbc6.html
因为数据源的问题
真正的原因是数据源conn默认的提交方式,hibernate不管这件事,大部分开源数据源都是默认false的我试了hibernate的默认连接池,和tomcat中配的连接池用使用事务都没有insert。
下面这段代码能够insert可以说明一些问题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);}    
}
而commit和flush的区别就是commit先flush再提交,而flush没有提交
而在close的时候,孙卫琴.精通Hibernate:Java对象持久化技术详解上讲的是hibernate会清空缓存,一个清理,一个清空,一字之差,呵呵

解决方案 »

  1.   

    的确很明确,简单说些事务,hibernante默认便是必须递交事务的;再有,myeclipse生成的dao,不是很好用,一般情况是不用的public boolean add(User user) {
            boolean ks = true;
            try {
                Session session = sf.openSession();
                session.save(user);
                session.beginTransaction().commit();
                //此句便是递交事务
            } catch (HibernateException e) {
                ks = false;
                e.printStackTrace();
            } finally {
                if (session != null) {
                    session.close();
                }
            }
            return ks;
        }
      

  2.   

        那myeclipse自带的dao类的save方法不就没有用了吗?
      

  3.   

    既然没保存那为什么我用findAll方法却可以查询到最后一次保存的数据呢??不过只限于最后一次
      

  4.   

    刚回答完一次,再回答一次有两种情况,在hibernate中配置hibernate.connection.autocommit
    autocommit=true 说明允许自动提交,但是在调用save等方法后,也不会同步到数据库,必须再调用flush方法
    autocommit=false 说明必须显示的提交事务,这时即使调用了flush方法,也不会同步到数据库,必须commit之所以findAll方法可以查到最新的,那是因为findAll方法查询的是一级缓存的数据
    save操作,会更新一级缓存为最新的数据,但是不会更新数据库,而findAll方法首先查询一级缓存,如果没有再去数据库查询,如果有就直接返回