Eager Loading та Lazy Loading в JPA
Java Persistence API або JPA — це одні з найбільш перспективних і поширених інструментів для роботи з базами даних за допомогою Hibernate, ORM та інших інструментів Java. Він має складну і цікаву структуру, яка викликає велике зацікавлення. Однією з тем є eager loading (жадібне завантаження) та lazy loading (лениве завантаження).
JPA надає два методи для отримання даних за основним ключем таблиці: getById() і findById(). З першого погляду вони здаються однаковими, адже обидва виконують однакову задачу, але насправді це два різних методи, які працюють дуже по-різному.
findById базується на жадібному завантаженні, тоді як getById — на ленивому завантаженні.
Жадібне завантаження, як і випливає з назви, безпосередньо запитує базу даних і отримує всі відповідні дані, тоді як лениве завантаження повертає проксі (псевдозапис) сутності або таблиці, щоб зробити систему більш ефективною, зберегти місце і повернути реальні дані тільки тоді, коли буде викликаний будь-який геттер або сетер.
Якщо ви підключаєте кілька БД за допомогою одного Spring Boot проєкту, getById() викликає помилку, оскільки він повертає проксі-дані, навіть якщо ви використовуєте .get() для отримання значення.
У вашому основному з'єднанні з БД це працює нормально. Але після підключення до інших баз даних ви починаєте отримувати помилки.
repo2.getById(newOperator).getCurrentBalance();
ERROR 26572 --- [nio-6060-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.hibernate.LazyInitializationException: Could not initialize proxy [com.update.balance.db2.entity.Entity2#{data to be fetched}] - no session] with root cause
org.hibernate.LazyInitializationException: Could not initialize proxy [com.update.balance.db2.entity.Entity2#{data to be fetched}] - no session
findById() безпосередньо запитує БД, але повертає тип optional, що дозволяє переконатися у результаті. Якщо система не така велика, використання findById() завжди є кращим варіантом, і також getById() тепер застаріло в нових версіях Hibernate.
Це мої останні знання про жадібне і лениве завантаження в Hibernate. Якщо у вас є будь-які пропозиції, не соромтеся звертатися до мене.
Перекладено з: Java Persistence Api(JPA): getById() vs findById()