@ManyToOne and @BatchSize

I found a strange thing in some old code (at least for me).

The field annotated by @ManyToOne is also annotated using @BatchSize .

I always thought that the @BatchSize annotation @BatchSize affects the annotation at the class level or in the collection ( @OneToMany ) and affects the prefetch on repeat.

But maybe I'm wrong and the @ManyToOne annotation with @BatchSize affects something. I can not find the answer in the documentation.

Does annotating @ManyToOne with @BatchSize ?

+6
source share
3 answers

@ManyToOne associated with @BatchSize can only make sense if the corresponding field is marked as lazy ( lazy=true ).

In fact, if the field is not lazy , it is already loaded by definition, since the loadable object is loaded, so the problem with database calls does not apply.

Imagine a Person class that has a collection of the ShoesPair element ( ShoesPair .class), and this field contains the owner field marked as lazy (since it is optional and does not bring important information when retrieving a specific pair of shoes).

One wants to repeat a pair of 25 pairs of shoes (25 ShoesPair objects) to get their owner.

If the owner field (corresponding to one person) is annotated only with @ManyToOne , the database will be 25 .

However, if annotated using @BatchSize(size=5) , there will only be 5 calls, and therefore an increase in performance.

From the Hibernate documentation , it is clarified that batch size does not apply only to collections:

You can also enable batch sampling of collections.

Hibenate is especially relevant for @OneToMany cases, because they apply with fields that are marked as lazy in 90% of cases.

+4
source

I think the question relates to combining @ManyToOne and @BatchSize in one field, for example:

 @ManyToOne @BatchSize(size = 5) private User owner; 

This use case is not supported by Hibernate, at least when using annotations. The only use of the referenced batch selection is:

  • In the collection fields, i.e. @OneToMany or @ManyToMany (but not @ManyToOne )
  • In the entity class to be selected

eg:.

 @Entity @BatchSize(size = 5) public class User { ... } 

This latter case allows batch processing for all relationships of type User, including many-to-one relationships. However, with annotation to the entity class, it is not possible to control the behavior in the fields.

A search in the Hibernate source code for all @BatchSize confirms the lack of support for your use. From what I see in AnnotationBinder.java , the @BatchSize annotation @BatchSize checked only in the entity class and in fields that have some @XxxToMany annotation.

+9
source

Solving the N + 1 Request Problem with Hibernate

1 Using Criteria Queries with fetchMode

Criteria Criteria = session.createCriteria (Customer.class); criteria.setFetchMode ("contact", FetchMode.EAGER);

2 HOL fetch join

3 @BatchSize

The @BatchSize annotation can be used to determine the number of identical associations to populate in a single database query. If 100 clients are connected to the session, and the contact collection mapping is annotated with @BatchSize of size n. This means that whenever Hibernate needs to populate a lazy collection of contacts, it checks the session, and if it has more clients that need to populate their contact collections, it retrieves up to n collections.

 @OneToMany(mappedBy="customer",cascade=CascadeType.ALL, fetch=FetchType.LAZY) @BatchSize(size=25) private Set<Contact> contacts = new HashSet<Contact>(); 
0
source

All Articles