Щербаченко Максим@ms_shcherbach
User
Information
- Rating
- Does not participate
- Registered
- Activity
Specialization
Бэкенд разработчик, Фулстек разработчик
Ведущий
Веб-разработка
Java
Java Spring Framework
PostgreSQL
Docker
Spring Boot
Hibernate
JavaScript
React
HTML
Сложно вам отвечать, поскольку очевидно, что статью вы не читали. Вы вырвали фразу из контекста, вложили в нее какой-то свой смысл, сами с собой не согласились и, основываясь на выдуманном противоречии, стали настаивать на том, что автор и не пытался оспаривать. В том месте, на которое вы ссылаетесь, начало статьи, первое, вводное предложение, там просто формулируется контекст, фактически там говорится, что столкнуться с проблемой N+1 можно в любом языке. Если б вы потрудились прочитать второе предложение, то увидели бы там название ORM-библиотеки. И еще, если б вы прочитали статью, то узнали бы, что в данном случае проблема не с ORM-библиотекой, а с её неправильным использованием. Учитывайте при работе с Hibernate принципы, описанные в статье, и проблем с N+1 у вас не будет.
Забавно, никогда не использовал @Data, в первый раз решил, что можно заюзать ее для уменьшения кода и такой конфуз вышел) если это отвлекает, от сути статьи видимо следует заменить.
В этой статье Hibernate, JPA, N+1 и лишние запросы в БД, более подробно описывается, что имеет в виду автор.
Проблема N+1, по моему мнению, это любой дополнительный запрос в базу, который можно избежать если сразу достать из БД все необходимые данные, вы не согласны с такой постановкой вопроса?
В начале статьи указано, что описывается как прокси классы вызывают проблему N+1. Просьба уточнить, в чем именно глупость?
Если при запросе объекта из базы, мы не запрашиваем связанные сущности и не обращаемся к полям прокси класса, проблема N+1 не возникнет, она проявится в тот момент когда мы попытаемся вызвать неинициализированное поле связанной сущности. Если мы запросим в БД книгу (Book) без связанной сущности автор (Author) и попытаемся вызвать имя автора (book.getAuthor().getName()), в этом месте возникнет N+1, то есть дополнительный запрос в базу, которого можно было избежать, если сразу достать из базы автора книги.
В целом достаточно контструктивный ответ. Возможно мое определение проблемы N+1 отличается от вашего, но статья в целом про то, как прокси классы приводят к проблеме N+1, то есть к лишним запросам в БД. В статье говориться, что пока вы не обратитесь к любому не id полю прокси класса, дополнительных запросов в БД не произойдет. Дополнительные запросы в БД появляются именно в тот момент когда вы попробуете вызвать неинициализированное поле прокси класса.
N это целевой набор запросов. В случае с книгой это запрос книги, но таких запросов может быть больше, 1,2,3…N. Целевой для определенного метода набор запросов в базу или в базы это N. Любой дополнительный запрос это +1.
Все использованные примеры синтетические и служат только одной цели - подсветить конкретный аспект.
Мне результат перевода самому не очень понравился, но в целом крупицы золота, намыть можно и здесь) Если коротко, то какие поля и стратегии извлечения данных (FetchType), вы укажете при написании класса, сформирует глобальную модель выборки объекта из базы, то есть все запросы получение по id(getById), по любому из полей(getByField), получение всех объектов(findAll) и т.д., будут доставать объект в таком виде. Если в каких-то запросах, связанный объект, помеченный EAGER, вам не нужен, это значит, что вы будете расходовать на него ресурсы без необходимости. Так же нужно понимать, что используя EAGER, вы не застрахованы от n+1.
Ключевая мысль автора в том, что "выборка подчиненных/связанных объектов должна диктоваться [только] логикой приложения...", и за это должен отвечать запрос в базу, а не сам объект. Если вы используете EAGER, то выборка будет диктоваться не "логикой приложения", а объектом. Если сейчас ваша логика предполагает обязательную загрузку связанной сущности, у вас все равно нет гарантии, что завтра не появятся дополнительные требования, по созданию запроса, где эта связанная сущность не будет нужна. Если появится такой запрос, "выборка будет диктоваться" уже не "логикой приложения".
Для этого конкретного, нового запроса, где связанная сущность вам не нужна, вы все равно будете ее доставать. Это значит, что запрос в базу будет расходовать ресурсы на эту ненужную сущность, кроме того, стратегия EAGER не защитит вас от n+1.
Соглашусь - нет предела совершенству. Но данная статья, объясняет концепцию стратегии извлечения данных. Использованные примеры, формулировались исходя из того, насколько полно они смогут подсветить конкретный тезис или аргумент.