Hibernate查询结果与实际结果不符
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate查询结果与实际结果不符相关的知识,希望对你有一定的参考价值。
将对应的hql语句拿到plsql中进行查询时,会显示有10多条记录,但是系统执行的结果却只有4条。
但是这种情况并不是一直存在的,在系统运行的大部分时间里,数据都能够正常查询出来,只是偶尔才会出现这种特殊情况,完全不知道是因为什么原因。虽然出现频率不高,但是都很致命,问题原因还很难查找。不知道各位日常开发中有没有遇到过,有的话还希望能分享一下,或者提供一些如何查找问题的建议也好,多谢。
多谢各位的回复!
我也觉得应该是缓存问题,但是不知道问题该从何查起。
执行hql的类我都是继承自HibernateDaoSupport,都是再简单不过的hql语句:
return this.getHibernateTemplate().find("from Product where company.id = ? and removed = ? ", new Object[]company.getId(), false);
,session都是交由spring进行管理的。
我看其他很多网友也说Hibernate3存在脏读数据的问题,但是跟我这个问题还是有些差异。
我这个问题最奇怪的地方就在于它不是查询上一次的结果,而是固定的只查出来4条,不局限哪张表,目前已发现有好几张表都出现过。
我想本地调试也不行,因为它根本就不重现,只有在生产环境运行一段时间之后才会偶尔出现。
开发时哪些东西叫“有状态”,哪些叫“无状态”,要分清。无状态是表示,每个请求之间没有依赖关系的,不存在先后,有状态的话,就可能存在依赖关系。你这个方法逻辑上应该是个无状态的,所以它使用的 hibernate 连接和其它相关的东西都应该是与上一个请求没有任何关系。你得找出来哪些地方用了 static 保存着东西。一般在 j2ee 环境中,static 不能用于共享,只能用在只读式的场合,比如,服务器启动后读取配置信息,而且这些配置信息是不会变的。任何可能变化的内容都不应该用 static 共享,因为它会限制你的程序仅运行在一台服务器上,你开个服务器集群的话就可能会有错误。 参考技术A 请确定你的的操作是在二级缓存 关闭下进行的... 我怀疑你存在缓存问题 哥.....和spring没一毛钱关系 你看下你的每一个entity配置的 hbm文件啊.. 先把hbm设置成 <cache usage="read-only">
进行测试...spring再怎么管理 每一个实体类的cache总是你自己设置的啊追问
我其实是没有用二级缓存的,这个不用配置。在没用二级缓存的情况下配置了会出错
追答那这个我也不知道了....
参考技术B 看你的hibernate中如何查询的。Hibernate Projections(投影统计不重复结果)
Hibernate除了处理查询结果集中的对象之外,还可以将结果集中的结果当做行和列集来使用,这与通过JDBC执行select查询获得的数据的使用方式相似。因此,Hibernate也支持属性、统计函数和Group By等查询。
要 想使用Hibernate的投影统计功能,首先要从org.hibernate.criterion.Projections工厂类获得 org.hibernate.criterion.Projection对象。与Restrictions类相似,Projections类提供了几个用 来获取Projection实例的静态工厂方法。在获得Projection对象之后,使用setProjection()方法将它添加到 Criteria对象中。注意,返回的结果集是Object类型,需要对结果进行适当的类型转换。
Hibernate的Projections工厂类包含了以下几个常用的统计函数:
① avg(String propertyName):计算属性字段的平均值。
② count(String propertyName):统计一个属性在结果中出现的次数。
③ countDistinct(String propertyName):统计属性包含的不重复值的数量。
④ max(String propertyName):计算属性值的最大值。
⑤ min(String propertyName):计算属性值的最小值。
⑥ sum(String propertyName):计算属性值的总和。
下面的示例演示了一些统计函数和投影列表的使用方法:
- getSession().beginTransaction();
- Criteria Crit = getSession().createCriteria(Product.class);
- ProjectionList projList = Projections.projectionList();
- projList.add(Projections.max("price"));
- projList.add(Projections.min("price"));
- projList.add(Projections.avg("price"));
- projList.add(Projections.countDistinct("description"));
- Crit.setProjection(projList);
- List result = Crit.list();
- getSession().getTransaction().commit();
上述示例执行了多个统计投影。当执行多个统计投影时,会获取一个List,并且是一个Object类型的List,其中依次包含所有的统计投影结果。
使用投影的一个好处就是,获得的结果是单独的属性而不是实体类。例如,一个产品表中包含有很多字段,我们想要获取产品表中的名称和描述,而不需要将完整的实体加载到内存中。
- Criteria Crit = getSession().createCriteria(Product.class);
- ProjectionList projList = Projections.projectionList();
- projList.add(Projections.property("name"));
- projList.add(Projections.property("description"));
- Crit.setProjection(projList);
- List result = Crit.list();
使 用这种查询风格可以减少应用服务器和数据库服务器之间的网络通信量。但是,如果客户机的内存容量的确是有限的,那么这种查询方式可以避免处理大型数据集对 内存的压力。如果不确定以后是否需要一个完整的结果集,这得要执行另外一次查询,反而降低了查询性能。所以只能在适当的时候才使用Hibernate的投 影功能。
那么如何获得结果集中的不重复的结果呢?方法为:
distinct(Projection proj):统计属性的不重复值。
- getSession().beginTransaction();
- Criteria criteria = getSession().createCriteria(Transaction.class);
- ProjectionList proList = Projections.projectionList();
- proList.add(Projections.distinct(Projections.property("module")));
- criteria.setProjection(proList);
- criteria.addOrder(Order.asc("orderSign"));
- list = criteria.list();
- getSession().getTransaction().commit();
最后,可以使用groupProperty投影对结果集进行分组(使用SQL的GROUP BY子句)。下面的示例安装名称和价格对产品进行分组:
- Criteria Crit = getSession().createCriteria(Product.class);
- ProjectionList projList = Projections.projectionList();
- projList.add(Projections.groupProperty("name"));
- projList.add(Projections.groupProperty("price"));
- Crit.setProjection(projList);
- List result = Crit.list();
以上是关于Hibernate查询结果与实际结果不符的主要内容,如果未能解决你的问题,请参考以下文章