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
<!-- 配置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
你直接能查到insert的数据 但是事务还未结束如果随后抛出异常 还是会回滚的吧
具体原因还是等大牛解释吧
这个就不明白,应该要么都提交,或者都不提交吧。
当调用session的save方法后,那么对象会由transient状态变为persist状态,
hibernate是通过主键来和数据关联的(也就是通过主键来识别对象)
在mysql中,如果你指定的是native来生成主键,
那么hibernate是无法获得下一个主键值的,此时就必须将数据插入数据库来获取相应的主键值,否则hibernate将无法关联该对象,
如果你是指定的increment生成主键,那么在调用session的save方法后会立即发出一条select max(id) from table 的sql语句来计算出下一个主键值。
而删除的时候,却要等待其他操作完成之后才提交。
比如我进行保存操作之后马上查找数据,数据是最新的。
但是在进行删除操作之后马上查找数据,却是先提交查找数据的操作再提交删除。
这是怎么回事,难道hibernate的操作还分优先级吗?
另外我是用的是hibernate3.2,之前用3.0的时候一直是可以的。
测试代码: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版本不一致?