Franck
Franck

Reputation: 1764

Hibernate @BatchSize and JPA Criteria API

Is there an incompatibility between those 2?

I have a n + 1 issue that I try to solve using the proprietary hibernate @BatchSize annotation.

public class Master{

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "master", orphanRemoval = true, cascade = CascadeType.ALL)
    @BatchSize(size=100)//how many item collections we want to load from <b>other<b> Masters currently in the PC
    private Set<Detail> details;

}

public class Detail{
  private Master master;
}

case 1

List<Master> masters = getMastersFromJPACriteria(complexParams);
assert(masters.size() == 3);
masters.get(0).getDetails().size();

It should trigger the batch collection load of details :

SELECT * FROM DETAIL WHERE MASTER_ID IN (1,2,3)

But I have (N+1 issue):

SELECT * FROM DETAIL WHERE MASTER_ID = 1

case 2

However if I'm doing:

m1 = entityManager.find(Master.class,1L);
entityManager.find(Master.class,2L);
entityManager.find(Master.class,3L);

m1.getDetails().size();

It correctly triggers :

SELECT * FROM DETAIL WHERE MASTER_ID IN (1,2,3)

I don't understand why in case 1 the detail collections are not batch loaded.

Env: Wildfly 8.2.0.Final with Hibernate 4.3.7

Upvotes: 1

Views: 3006

Answers (2)

Franck
Franck

Reputation: 1764

I've found the problem. I use CDI with an entity manager bound to the request scope. The issue is that the method getMastersFromJPACriteria is declared on an ejb and my entity manager is flushed on transaction's commit. It seems that the Batch Collection Queue from Hibernate are cleared on session flush even though my master entities are still in a MANAGED state after the method call! It is explained in this issue.

Upvotes: 0

Javier Toja
Javier Toja

Reputation: 1762

On this link there is a little info about batch-fetching mkyong.

To solve the issue you can use fetch.

I think the key to understand the difference is look in how is the data loaded each time. With the criteria a group of Masters are loaded but with em.find(class,id), only one is retrieved each time. I'm not fully sure if this is the cause but maybe someone can bring some more light.

Upvotes: 1

Related Questions