1

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

Community
  • 1
  • 1
Franck
  • 1,754
  • 1
  • 13
  • 14

2 Answers2

1

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.

Javier Toja
  • 1,630
  • 1
  • 14
  • 31
  • I've tried to join fetch but I also need to set a max results in order to limit the size of the returned result set. Unfortunately paging with join fetch is not working as hibernate select everything from db and sort in memory. – Franck Mar 21 '16 at 17:46
  • Please, could you try to put the @BatchSize annotation on the entity Detail, and post here the result. On the official doc says that also works at entity level [link](https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/annotations/BatchSize.html) – Javier Toja Mar 21 '16 at 18:20
0

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.

Community
  • 1
  • 1
Franck
  • 1,754
  • 1
  • 13
  • 14