[英]hibernate paging is resulting in select and update calls
我正在尝试在 hibernate 中实现分页,我看到 hibernate 的一些奇怪行为。 我尝试了两个具有相同结果的查询
List<SomeData> dataList = (List<SomeData>) session.getCurrentSession()
.createQuery("from SomeData ad where ad.bar = :bar order by ad.id.name")
.setString("bar", foo)
.setFirstResult(i*PAGE_SIZE)
.setMaxResults(PAGE_SIZE)
.setFetchSize(PAGE_SIZE) // page_size is 1000 in my case
.list();
和
List<SomeData> datalist= (List<SomeData>) session.getCurrentSession()
.createCriteria(SomeData.class)
.addOrder(Order.asc("id.name"))
.add(Expression.eq("bar", foo))
.setFirstResult(i*PAGE_SIZE)
.setMaxResults(PAGE_SIZE)
.list();
我在 for 循环中有这个,每次运行这个查询时,运行时间都会增加。 第一次调用在 100 毫秒内返回,第二次在 150 秒内返回,第五次调用需要 2 秒,依此类推。
查看服务器(MySql 5.1.36)日志,我看到 select 查询确实使用 LIMIT 子句正确生成,但对于返回的每条记录,hibernate 出于某种原因也会发出更新查询。 在第一个结果之后,它更新 1000 条记录,在第二个结果之后,它更新 2000 条记录,依此类推。 因此,对于 1000 的页面大小和 5 次循环迭代,数据库受到 15,000 个查询(5K + 4K + 3K + 2K + 1K)的影响,为什么会发生这种情况?
我尝试制作一个原生 SQL 查询,它按预期工作。 查询是
List asins = (List) session.getCurrentSession()
.createSQLQuery("SELECT * FROM some_data where foo = :foo order by bar
LIMIT :from , :page")
.addScalar(..)
.setInteger("page", PAGE_SIZE)
.setInteger("from", (i*PAGE_SIZE))
... // set other params
.list();
我的映射 class 具有用于 blob object 的设置器/获取器
void setSomeBlob(Blob blob){
this.someByteArray = this.toByteArray(blob)
}
void Blob getSomeBlob(){
return Hibernate.createBlob(someByteArray)
}
打开绑定参数日志记录(您可以通过将“org.hibernate.type”日志级别设置为“TRACE”来实现)以查看具体更新的内容。
您很可能在加载实体后修改它们 - 显式或隐式(例如,从 getter 返回不同的值或在某处使用默认值)。
另一种可能性是您最近更改了要从中选择的表(其中一个),并且表中的列默认值与实体中的默认值不匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.