hibernate的配置如下:
<!-- 配置hibernate的属性 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">
${hibernate.show_sql}
</prop>

<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">
true
</prop>
<prop key="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</prop> </props>
</property>
同一张表进行保存和删除操作。
使用getHibernateTemplate().saveOrUpdate(entity);
立刻就提交了,查看数据库确实保存了。而使用getHibernateTemplate().delete(entity);时
没有马上提交,这是怎么回事?上面两种操作之后还有其他的操作,因此事务没结束。
但是getHibernateTemplate().saveOrUpdate(entity)为什么马上就提交了?该项目使用SSH框架,hibernate的版本是3.2

解决方案 »

  1.   

    按道理事务没结束前 数据都是在数据库缓冲区的
    你直接能查到insert的数据 但是事务还未结束如果随后抛出异常 还是会回滚的吧
    具体原因还是等大牛解释吧
      

  2.   

    我也是这么想的,但是saveOrUpdate提交,而delete不提交,
    这个就不明白,应该要么都提交,或者都不提交吧。
      

  3.   

    我可以肯定你生成主键的方式一定是native,
    当调用session的save方法后,那么对象会由transient状态变为persist状态,
    hibernate是通过主键来和数据关联的(也就是通过主键来识别对象)
    在mysql中,如果你指定的是native来生成主键,
    那么hibernate是无法获得下一个主键值的,此时就必须将数据插入数据库来获取相应的主键值,否则hibernate将无法关联该对象,
    如果你是指定的increment生成主键,那么在调用session的save方法后会立即发出一条select max(id) from table 的sql语句来计算出下一个主键值。
      

  4.   

    主键是native的,现在的问题是保存或者更新是即时提交的,
    而删除的时候,却要等待其他操作完成之后才提交。
    比如我进行保存操作之后马上查找数据,数据是最新的。
    但是在进行删除操作之后马上查找数据,却是先提交查找数据的操作再提交删除。
    这是怎么回事,难道hibernate的操作还分优先级吗?
    另外我是用的是hibernate3.2,之前用3.0的时候一直是可以的。
      

  5.   

    我用的hibernate3.6
    测试代码:public static void main(String[] args) {
    Configuration configuration = new Configuration().configure();
    SessionFactory sessionFactory = configuration.buildSessionFactory();
    Session session = sessionFactory.openSession();
    /**开启事务*/
    session.beginTransaction();
    Book book = new Book();
    book.setAuthor("Tom");
    book.setTitle("Java");
    /***先删除id为4的记录,并未实际删除数据库的数据,*/
    session.delete(session.get(Book.class, 4));
    /**这里是测试native生成主键方式会发出insert语句*/
    session.saveOrUpdate(book);

    /**手动清空缓存*/
    //session.clear();
    /**之后再取该被删的记录*/
    //System.out.println(((Book)session.get(Book.class, 4)).getId());
    //System.out.println(((Book)session.load(Book.class, 4)).getId());
                    System.out.println(session.createQuery("from Book").list().size());
    List<Book> list=session.createQuery("from Book").list();
    for(Book b:list){
    System.out.println(b.getId());
    }
    /**提交事务*/
    session.getTransaction().commit();
    /** 关闭 Session*/
    session.close();
    }
    测试结果1:当手动调用session.clear强制清空缓存后,代码可以正常执行输出,因为强制清空了缓存,所以无论是get还是load(默认会查找2级缓存,但这里没启用)在缓存中都找不到该数据、就会到数据库中去查找,所以可以正确找到,但强制清除缓存会导致delete语句的失效,数据库是不会删除该条为4的记录的。最后的执行结果只是数据库多了一天save的数据。测试结果2:
    隐藏 clear 调用 get
    结果为找不到数据Hibernate: select book0_.BOOK_ID as BOOK1_0_0_, book0_.AUTHOR as AUTHOR0_0_, book0_.TITLE as TITLE0_0_ from BOOKS book0_ where book0_.BOOK_ID=?
    Hibernate: insert into BOOKS (AUTHOR, TITLE) values (?, ?)
    Exception in thread "main" java.lang.NullPointerException
    at cn.hibernate.Main.main(Main.java:20)测试3:
    隐藏clear 调用load
    也是抛出同样的错误Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [cn.hibernate.Book#4]
    at org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(SessionFactoryImpl.java:433)
    at org.hibernate.impl.SessionImpl.load(SessionImpl.java:987)
    at org.hibernate.impl.SessionImpl.load(SessionImpl.java:978)
    at cn.hibernate.Main.main(Main.java:20)测试4
    隐藏clear 、load、get
    调用list查询Hibernate: insert into BOOKS (AUTHOR, TITLE) values (?, ?)
    Hibernate: delete from BOOKS where BOOK_ID=?
    Hibernate: select book0_.BOOK_ID as BOOK1_0_, book0_.AUTHOR as AUTHOR0_, book0_.TITLE as TITLE0_ from BOOKS book0_
    6
    Hibernate: select book0_.BOOK_ID as BOOK1_0_, book0_.AUTHOR as AUTHOR0_, book0_.TITLE as TITLE0_ from BOOKS book0_可以看到,调用list方法时会先删除数据再执行查询,因为list查询是不使用缓存查询的,iterator默认是使用缓存查询的,这里不作测试了,结果肯定和get、load相同只要不手动的清空缓存,是查询不到缓存中删除的数据的,
    你说的“但是在进行删除操作之后马上查找数据,却是先提交查找数据的操作再提交删除。”没明白是怎么造成。
    也许是我和你的hibernate版本不一致?