Почему я не должен использовать @BatchSize для каждого ленивого загруженного отношения?

Аннотация @BatchSize спящего режима позволяет загружать загруженные объекты с ленивой загрузкой. Например. если я получил что-то вроде:

public class Product {


    @OneToMany(fetchType=LAZY)
    @BatchSize(size=10)
    private ProductCategory category;

}

Теперь, если я получу категорию продукта, Hibernate будет отображать категории до десяти других продуктов, которые находятся в текущем сеансе и еще не были инициализированы поле своей категории. Это экономит тонну вызовов SQL в базе данных. Все идет нормально. Теперь я задаюсь вопросом , почему бы мне не использовать аннотацию @BatchSize для КАЖДОЙ ленивой загрузки? В конце концов, зачем мне нужны дополнительные вызовы в базу данных? Очевидно, что это должно быть причиной этого, в противном случае ребята из Hibernate могли сделать это по умолчанию, но я в настоящее время не вижу его.

Ответ 1

Я не собираюсь отвечать на ваш вопрос напрямую, но я собираюсь ответить на более общий вопрос, который может быть "Я нашел то, что работает быстрее для меня, почему бы не применять его повсюду?"

Короткий ответ: вы не должны делать превентивную оптимизацию.

hibernate - замечательный ORM, который позволяет все виды оптимизации. Вы должны измерить все процессы, которые вызывают проблему (классический N + 1, даже если это быстро, любые медленные процессы и т.д.) И оптимизировать его решение.

Вы можете получить гораздо лучшую производительность, пытаясь загрузить некоторые свойства, потому что вы всегда используете их, вам может понадобиться BatchSize из 100 для другого, потому что вы знаете это о количестве отношений, которые у вас есть для этого свойства.

В конечном счете, вы не должны заботиться об оптимизации, если вам не нужна , чтобы заботиться об этом. И вам нужно заботиться о том, когда вы делали измерения и находили проблемы.

Ответ 2

почему я не должен использовать аннотацию @BatchSize для КАЖДОЙ ленивой загрузки?

Потому что это оптимизация, которая может не понадобиться в каждом отдельном случае. Пакетное извлечение, подобное этому, полезно, когда ваше приложение будет обращаться к product.category для разных products, поэтому вы можете выполнить только один запрос select from category..., а не N из них.

Однако, что, если ваше приложение обратится к product.category для одного экземпляра Product, вряд ли он получит доступ к полю category других экземпляров Product в том же сеансе? Если для этой связи включен @BatchSize, то вы просто загрузили несколько других экземпляров category в сеанс без усиления - они никогда не будут использоваться.