SSH的j2ee开发中,需要遇到一个hibernate直接操作数据库,不通过对象,直接对数据库进行操作。
Spring的orm包中,对hibernate的数据库操作进行了封装,封装以后,可以直接调用HibernateTemplate类的实例,进行DB操作。因为,需要实现对数据库操作,查了一下资料可以直接调用HibernateTemplate的bulkUpdate()操作来执行数据库的操作。
问题主要出现在这里了,这是我写的一段的HQL语言,使用bulkUpdate接口来执行的。
HibernateTemplate ht = getHibernateTemplate();
int num = ht.bulkUpdate("UPDATE Option op set op.optionMean= ? where op.optionMean= ?", new Object[]{newDimname,oldDimname});
理应我的这段代码会update DB中的Option表的相关数据。在tomcat下,这段code成功的跑完了,也没有抛出任何异常信息,但是就是DB中的相关表中没有更新。
然后我再测试组件里面同样的执行了这段code,没有任何问题。
自己查资料分析,也没有得出一个很清晰的解决思路。在水木上问了,基本认为:1.是transaction基本上是有问题的;2.或者Spring对hibernate的transaction托管会出现问题。我们来依次分析这些原因:
1. 查看原始的HibernateTemplate.bulkUPdate的源代码
public int bulkUpdate(final String queryString, final Object... values) throws DataAccessException {
return executeWithNativeSession(new HibernateCallback<Integer>() {
public Integer doInHibernate(Session session) throws HibernateException {
Query queryObject = session.createQuery(queryString);
prepareQuery(queryObject);
if (values != null) {
for (int i = 0; i < values.length; i++) {
queryObject.setParameter(i, values[i]);
}
}
return queryObject.executeUpdate();
}
});
}
从源代码中我们可以看到基本上Spring orm包中做的封装工作主要是两部分:
a.session管理。
b.简化hql语言的使用。
然后我们在查看相应的log信息:
INFO com.sgcp.system.entity.OptionDAO - 更新的数据库条目数量:80 com.sgcp.system.entity.OptionDAO.replaceDimName(OptionDAO.java:43)
说明这个transaction已经执行了,并且返回了相应更新的数据库的行数。
2.SpringFrame 的session管理,相应执行transaction应该都是没有问题的,因为在测试的code中也是由SpringFrame来管理的,执行是成功的。所以SpringFrame对hibernate的托管是没有问题的。
所以现在已经判定query已经被执行了,那么现在是什么问题呢?
在查看资料中,发现hibernate中的执行会有一个cache,为了减少code对db的hits。因为cache有一个write-behind策略,就是update的对象,对那些update的对象,如果在最近没有再read的话,那就晚些写回DB中,这样如果要再次update的话,就可以少一次update。
但是因为,我在执行完query,有对session进行了flush过,所以这种可能也被排除了。
为了确定我的判断,我后来用直接从db中用对象方式读取符合条件的Options,set相应的属性值,后在attachDirty这些对象,但是也没有用。
最后再仔细排查code以后,原来这些rows对应的对象其实已经被读取进来了。就是说那些对象已经被存储到了hibernate中的cache中了。
这个就是问题的关键所在了,如果我们直接update数据库了的话,database中的那些rows和在hibernate中的数据缓存中的相应的对象就会变成脏的对象。
所以我猜测就是有可能是hibernate在检查bulkUpdate的操作时,会检查原先的缓存中,是否已经有要更新的行对应的对象,有的话,就不允许进行这类的操作。
后来,我直接取出hibernate中缓存中的相应对象,然后更新后,对这些对象进行attachDirty().数据库就成功更新的了。
但是就是不知道为什么hibernate没有报错。
分享到:
相关推荐
《Java精通Hibernate对象持久化技术权威指南》是一本深度探讨Java开发中如何高效地使用Hibernate进行对象持久化的专业书籍。本书旨在帮助Java开发者熟练掌握Hibernate框架,实现数据库操作的简化和自动化,提升软件...
总结,Hibernate操纵持久化对象涉及多个方面,包括对象状态管理、事务处理、查询机制、缓存策略以及关系映射等。熟练掌握这些概念和操作,将极大地提高开发效率,并有助于构建高效、稳定的数据库应用程序。通过实践...
**Hibernate对象持久化** 在Java开发中,数据库操作是不可或缺的一部分。Hibernate作为一种强大的ORM(对象关系映射)框架,极大地简化了Java应用与数据库之间的交互。它通过将Java类映射到数据库表,实现了对象...
Hibernate通过将对象模型与关系数据库模型之间的映射进行自动化处理,极大地简化了数据访问层(DAO)的实现,让开发者可以专注于业务逻辑,而非底层的数据库操作。 Hibernate是什么? Hibernate是一个基于JDBC的ORM...
2. **对象关系映射(ORM)**:详述Hibernate的实体类、注解和XML映射文件,如何定义对象的属性与数据库字段的对应关系,以及如何处理一对多、一对一、多对多等复杂关系。 3. **Session和Transaction管理**:讲解...
《精通Hibernate:Java对象持久化技术详解》这本书深入剖析了Hibernate这一流行的Java对象关系映射(ORM)框架,旨在帮助开发者全面理解并熟练掌握Hibernate的使用。Hibernate是Java开发中的重要工具,它简化了...
Hibernate的本地SQL查询功能为我们提供了一种灵活的方式来执行复杂的数据库操作,同时通过`addEntity()`、`addScalar()`和`Transformers.aliasToBean()`等方法,我们可以方便地将查询结果封装成Java对象,从而简化...
### 使用Hibernate对象持久化服务简化Java数据库访问 #### 摘要 Hibernate作为一个高效且功能丰富的对象关系映射(ORM)框架,在Java开发领域扮演着举足轻重的角色。通过强大的映射机制,Hibernate能够将Java对象...
在Java编程中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它使得开发者能够以面向对象的方式处理数据库操作。Hibernate的核心概念之一就是持久化对象的生命周期,这涉及到对象在数据库中的状态及其与...
Hibernate作为ORM(对象关系映射)框架,通过提供一种面向对象的方式来处理数据库操作,极大地降低了数据访问层的复杂性。 Hibernate的核心特性包括: 1. **对象关系映射**:Hibernate通过XML配置或注解方式,将...
《妙解Hibernate 3.x:叩响面向对象思想之门》是一本深入解析Hibernate框架的专著,旨在帮助读者理解并掌握面向对象编程思想在实际开发中的应用,尤其是在使用Hibernate时如何有效地进行数据持久化。这本书是面向...
`HibernateSessionFactory.java`以及`BatchUpdateTest.java`这四个文件涵盖了Hibernate中的核心操作和测试场景,它们一起构成了一个完整的数据库操作示例,展示了如何高效地使用Hibernate处理Java实体对象。...
2. Hibernate框架概念:Hibernate是一个开源的对象关系映射(ORM)框架,它主要用于将Java对象映射到关系数据库中的表。通过Hibernate,开发者可以不必编写大量的SQL语句,就能实现Java应用与数据库之间的数据交互。...
Hibernate 的主要特点是:支持多种数据库管理系统、提供了高效的数据访问机制、支持事务处理和缓存机制等。 Hibernate 环境搭建 要使用 Hibernate,首先需要搭建 Hibernate 的开发环境。下面是 Hibernate 环境搭建...
在Java开发中,尤其是涉及到大数据量的处理时,人们往往会质疑ORM框架,如Hibernate,是否适合进行批量数据操作。然而,实际上,通过适当的技术手段,我们可以有效地解决Hibernate在批量处理时可能出现的性能问题。...
在检索大型对象时,Hibernate会自动处理BLOB和CLOB的读取。当你查询到Document对象后,可以直接访问`content`和`description`字段获取数据: ```java Document loadedDocument = session.get(Document.class, id); ...