简体   繁体   中英

hibernate paging is resulting in select and update calls

I am trying to implement paging in hibernate and i am seeing some weird behavior from hibernate. I have tried two queries with the same result

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();

and

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();

I have this in a for loop and each time this query runs, the run time increases. The first call returns in 100 ms, the second in 150 and the 5th call takes 2 seconds and so on.

Looking in the server (MySql 5.1.36) logs, I see that the select query does get generated properly with the LIMIT clause but for each record that is returned, hibernate for some reason also emits an update query. after the first result, it updates 1000 records, after the second result, it updates 2000 records and so on. So for a page size of 1000 and 5 iterations of the loop, the database is getting hit with 15,000 queries (5K + 4K + 3K + 2K + 1K ) Why is that happening?

I tried making a native SQL query and it worked as expected. The query is

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();

My mapping class has setters/getters for the blob object as

void setSomeBlob(Blob blob){
    this.someByteArray = this.toByteArray(blob)
}

void Blob getSomeBlob(){
    return Hibernate.createBlob(someByteArray)
}

Turn on bound parameters logging (you can do that by setting "org.hibernate.type" log level to "TRACE") to see what specifically is being updated.

Most likely you're modifying the entities after they've been loaded - either explicitly or implicitly (eg returning different value from getter or using a default value somewhere).

Another possibility is that you've recently altered (one of) the table(s) you're selecting from and column default in the table doesn't match default value in the entity.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM