Як вирішити виняток зі сплячого режиму «невдало ініціалізувати колекцію ролей»


363

У мене є ця проблема:

org.hibernate.LazyInitializationException: не вдалося лінь ініціалізувати колекцію ролей: mvc3.model.Topic.comments, жодна сесія чи сесія не закриті

Ось модель:

@Entity
@Table(name = "T_TOPIC")
public class Topic {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    @ManyToOne
    @JoinColumn(name="USER_ID")
    private User author;

    @Enumerated(EnumType.STRING)    
    private Tag topicTag;

    private String name;
    private String text;

    @OneToMany(mappedBy = "topic", cascade = CascadeType.ALL)
    private Collection<Comment> comments = new LinkedHashSet<Comment>();

    ...

    public Collection<Comment> getComments() {
           return comments;
    }

}

Контролер, який викликає модель, виглядає наступним чином:

@Controller
@RequestMapping(value = "/topic")
public class TopicController {

    @Autowired
    private TopicService service;

    private static final Logger logger = LoggerFactory.getLogger(TopicController.class);


    @RequestMapping(value = "/details/{topicId}", method = RequestMethod.GET)
    public ModelAndView details(@PathVariable(value="topicId") int id)
    {

            Topic topicById = service.findTopicByID(id);
            Collection<Comment> commentList = topicById.getComments();

            Hashtable modelData = new Hashtable();
            modelData.put("topic", topicById);
            modelData.put("commentList", commentList);

            return new ModelAndView("/topic/details", modelData);

     }

}

Сторінка jsp виглядає наступним чином:

<%@page import="com.epam.mvc3.helpers.Utils"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
      <title>View Topic</title>
</head>
<body>

<ul>
<c:forEach items="${commentList}" var="item">
<jsp:useBean id="item" type="mvc3.model.Comment"/>
<li>${item.getText()}</li>

</c:forEach>
</ul>
</body>
</html>

Виняток нараховується під час перегляду jsp. У рядку з c: для кожного циклу

Відповіді:


214

Якщо ви знаєте, що ви хочете бачити всі Comments щоразу, коли ви отримаєте a, Topicто змініть карту поля commentsна:

@OneToMany(fetch = FetchType.EAGER, mappedBy = "topic", cascade = CascadeType.ALL)
private Collection<Comment> comments = new LinkedHashSet<Comment>();

Колекції за замовчуванням ліниво завантажені, погляньте на це, якщо хочете дізнатися більше.


35
Вибачте, але я хотів би використовувати ледачий навантаження. Отже, я змінив тип "LinkedHashSet" на "PersistentList". Виняток все ще має місце
Євген

242
Це може бути використане як вирішення проблеми, але не є фактичним рішенням проблеми. Що робити, якщо нам потрібно ліниво взяти?
Dkyc

14
але у випадку, якщо ми хочемо лінивих, це рішення не спрацює, і в більшості випадків ми хочемо лише ледачих.
прашант такре

103
Це тип відповіді, який з’являється скрізь під час переповнення стека. Коротше, до суті, вирішує проблему і НЕПРАВИЛЬНО. Майбутнім читачам зробіть собі прихильність і дізнайтеся, що саме ліниво і нетерпляче, і зрозумійте наслідки.
Сід

13
@darrengorman Коли я запустив JPA, я поставив запитання навколо лінії ОП. Я отримав таку ж відповідь, що і ви. Досить скоро, коли я провів якийсь тест із сотнями тисяч рядків, здогадайтесь, що сталося? Я думаю, що це вводить в оману, оскільки це дає занадто простий варіант відповіді на проблему, з якою стикаються переважно початківці, і досить скоро вони будуть завантажувати в пам'ять всю свою базу даних, якщо вони не будуть обережні (і не будуть, тому що не будуть пам’ятайте про це) :).
Сід

182

Зі свого досвіду я маю такі способи вирішення відомого LazyInitializationException:

(1) Використовуйте Hibernate.initialize

Hibernate.initialize(topics.getComments());

(2) Використовуйте ПРИЄДНАЙТЕ ФЕТЧ

Ви можете використовувати синтаксис JOIN FETCH у вашому JPQL, щоб явно отримати дочірню колекцію. Це дещо, як EAGER отримання.

(3) Використовуйте OpenSessionInViewFilter

LazyInitializationException часто трапляється у шарі подання. Якщо ви використовуєте Spring Framework, ви можете використовувати OpenSessionInViewFilter. Однак я не пропоную вам це робити. Якщо це неправильно використовувати, це може призвести до появи продуктивності.


5
(1) працював для мене чудово. Мій випадок: Hibernate.initialize (register.getVehicle (). GetOwner (). GetPerson (). GetAddress ());
Leonel Sanches da Silva

6
Здається, що Hibernate.initialize не працює з EntityManager
marionmaiden

8
Це має бути правильна відповідь. Наприклад, у моєму проекті на роботі явно не слід використовувати EAGER для отримання. Це спричиняє проблеми саме в цій системі.
Стів Вотерс

Здається, привабливим, але відсутність документації для впровадження в іншому випадку ... ви можете надати ще кілька посилань чи пояснень, як реалізувати це рішення?
Піпо

58

Я знаю, що це старе питання, але я хочу допомогти. Ви можете розмістити анотацію про транзакцію на потрібному методі обслуговування. У цьому випадку findTopicByID (id) повинен мати

@Transactional(propagation=Propagation.REQUIRED, readOnly=true, noRollbackFor=Exception.class)

більше інформації про цю примітку можна знайти тут

Про інші рішення:

fetch = FetchType.EAGER 

не є хорошою практикою, її слід використовувати ТОЛЬКО при необхідності.

Hibernate.initialize(topics.getComments());

Ініціалізатор сплячого режиму прив'язує ваші класи до технології сплячого режиму. Якщо ви прагнете бути гнучкими, це не дуже хороший шлях.

Сподіваюся, це допомагає


3
Анотація @Transactional працювала для мене, але зауважте, що Propagation.REQUIRED є типовим типом, принаймні у Spring Boot 1.4.2 (Spring 4.3).
ben3000

4
Так, але я подумав, що це може бути оцінено, щоб зрозуміти, що ви насправді можете змінити параметр розповсюдження
sarbuLopex

Хіба це не @Transactionalвесна?
Кампа

@Campa так. Якщо ви хочете обробити це вручну, слід ввести свою ділову логіку в транзакцію,
sarbuLopex

54

Походження вашої проблеми:

За замовчуванням сплячий режим ліниво завантажує колекції (відносини), що означає, що коли ви використовуєте collectionу своєму коді (тут commentsполе в Topicкласі), сплячий отримує це з бази даних, тепер проблема полягає в тому, що ви отримуєте колекцію у своєму контролері (де сесія JPA це закрито). Це рядок коду, який викликає виняток (де ви завантажуєте commentsколекцію):

    Collection<Comment> commentList = topicById.getComments();

Ви отримуєте колекцію "коментарів" (topic.getComments ()) у своєму контролері (де JPA sessionзакінчилося), і це спричиняє виняток. Також якщо ви отримали commentsколекцію у вашому jsp-файлі на зразок цього (замість того, щоб отримати його у контролері):

<c:forEach items="topic.comments" var="item">
//some code
</c:forEach>

У вас все ще буде той самий виняток з тієї ж причини.

Вирішення проблеми:

Оскільки ви просто можете мати лише дві колекції з FetchType.Eager(нетерпляче зібраною колекцією) в класі Entity і тому, що ледача завантаження є більш ефективною, ніж охоче завантаження, я думаю, що цей спосіб вирішення вашої проблеми краще, ніж просто змінаFetchType на нетерплячий:

Якщо ви хочете ініціалізувати колекцію ліниво, а також зробити цю роботу, краще додати цей фрагмент коду до свого web.xml:

<filter>
    <filter-name>SpringOpenEntityManagerInViewFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SpringOpenEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Цей код робить те, що він збільшить тривалість вашої JPA sessionабо, як говорить документація, він використовується, "to allow for lazy loading in web views despite the original transactions already being completed."тому таким чином сеанс JPA буде відкритий трохи довше, і через це ви можете ледаче завантажувати колекції у ваші jsp файли та класи контролерів .


7
Чому сесія JPS закрита? Як зробити так, щоб він не був закритим? Як виконати лінивий збір?
Дімс

1
Що визначає ліміт двох колекцій FetchType.Eager на об'єкт?
chrisinmtown

У Spring Boot ви можете додати 'spring.jpa.open-in-view = true' до 'application.properties'
Askar

28

Причина полягає в тому, що при використанні ледачого навантаження сеанс закривається.

Є два рішення.

  1. Не використовуйте ледачий навантаження.

    Встановити lazy=falseв XML або Set @OneToMany(fetch = FetchType.EAGER)In annotation.

  2. Використовуйте ледаче навантаження.

    Встановити lazy=trueв XML або Set@OneToMany(fetch = FetchType.LAZY)In annotation.

    і додайте OpenSessionInViewFilter filterу свійweb.xml

Детальніше Дивіться мою пошту .


1
... і все ж обидва рішення не є хорошими. Запропонуйте використовувати EAGER може створити величезні проблеми. Використання OpenSessionInViewFilter є антитілом.
Рафаель

27
@Controller
@RequestMapping(value = "/topic")
@Transactional

Я вирішую цю проблему, додавши @Transactional, я думаю, це може зробити сеанс відкритим


Чому цей голос отримав мінус? Додавання транзакції до операції продовжує сеанс
Тюдор Григор’ю

1
Неправильно застосовувати рекламу @Transactional до контролера.
Рафаель

@Rafael Чому це погана практика?
Amr Ellafy

@AmrEllafy -> Ось це гарне пояснення: stackoverflow.com/a/18498834/1261162
Рафаель

22

Проблема викликана доступом до атрибута із закритим сеансом сплячого режиму. Ви не маєте зимової операції в контролері.

Можливі рішення:

  1. Виконайте всю цю логіку на рівні обслуговування (з @Transactional), а не в контролері. Для цього має бути правильне місце, це частина логіки програми, а не в контролері (в цьому випадку - інтерфейс для завантаження моделі). Усі операції на рівні обслуговування повинні бути транзакційними. тобто: Перемістіть цей рядок до методу TopicService.findTopicByID:

    Коментар колекціїList = topicById.getComments ();

  2. Використовуйте "нетерплячий" замість "ледачий" . Тепер ви не використовуєте "ледачий". Це не справжнє рішення, якщо ви хочете використовувати ледачий, працює як тимчасовий (дуже тимчасовий) спосіб вирішення.

  3. використовуйте @Transactional в контролері . Тут не слід використовувати, ви змішуєте сервісний шар із презентацією, це не гарний дизайн.
  4. використовуйте OpenSessionInViewFilter , повідомляється про багато недоліків, можлива нестабільність.

Загалом, найкраще рішення - це 1.


2
Вибір типу Eager припускає, що в сплячку будуть виведені всі дані в першому запиті, не у всіх місцях це правильно
Жасулан Бердибеков

Вам слід ПЕРЕГЛЯДУВАТИ, що НАЙКРАЩЕ РІШЕННЯ 1 ... насправді це ТІЛЬКО ДОБРЕ рішення, оскільки всі інші є анти-шаблонами!
Рафаель

19

Для того, щоб ліниво завантажити колекцію, повинен бути активний сеанс. У веб-додатку є два способи зробити це. Ви можете використовувати шаблон " Відкрита сесія в перегляді" , де ви використовуєте перехоплювач відкрити сеанс на початку запиту та закрити його в кінці. Існує ризик, що вам доведеться провести обробку виключних обставин, або ви можете зв’язати всі свої сеанси, і ваша програма може зависнути.

Інший спосіб впоратися з цим - зібрати всі необхідні вам дані в контролері, закрити сеанс і потім ввести дані у вашу модель. Я особисто віддаю перевагу такому підходу, оскільки це здається трохи ближчим до духу MVC-моделі. Крім того, якщо ви отримаєте помилку з бази даних таким чином, ви можете впоратися з цим набагато краще, ніж якщо це станеться у вашому рендері. Ваш друг у цьому сценарії - Hibernate.initialize (myTopic.getComments ()). Вам також доведеться повторно приєднати об’єкт до сеансу, оскільки ви створюєте нову транзакцію з кожним запитом. Використовуйте для цього session.lock (myTopic, LockMode.NONE).


15

Як я пояснив у цій статті , найкращий спосіб впоратися з цим LazyInitializationException- це отримати його під час запиту, наприклад:

select t
from Topic t
left join fetch t.comments

ЗАВЖДИ уникайте таких анти-шаблонів:

Тому переконайтеся, що ваші FetchType.LAZYасоціації ініціалізуються під час запиту або в межах початкового @Transactionalобсягу, використовуючиHibernate.initialize для вторинних колекцій.


1
Влад, чи є у вас пропозиції щодо роботи з ініціалізованою колекцією, яка ініціалізується в об'єкті, отриманому методом findById (), створеного джерелом? Я не пишу запит, і транзакція знаходиться поза моїм кодом.
chrisinmtown

Перегляньте цю статтю для отримання більш детальної інформації про ініціалізацію лінивих колекцій.
Влад Міхалча

Не могли б ви пояснити, що ви маєте на увазі під "в межах оригіналу @Transactional" Це для мене незрозуміло, оскільки я, здається, отримую цю помилку під час відкритого сеансу (але не правильного?)
Мічіель Хайсма,

Перебуваючи всередині сфери про найпопулярніший метод обслуговування транзакцій, також відомий як шлюз транзакцій. Перевірте TrassctionInterceptorслід у стеці і ось це один.
Влад

Один з найкращих відповідей на сьогоднішній день ... це слід позначити як правильне. BTW ... якщо припустимо, що OSIV є анти-шаблоном, як це можливо, що він включений за замовчуванням у останніх версіях весняного завантаження? ... може, не все так погано?
Рафаель

10

Якщо ви намагаєтесь мати зв’язок між сутністю та колекцією чи списком об’єктів java (наприклад, тип Long), це буде щось подібне:

@ElementCollection(fetch = FetchType.EAGER)
    public List<Long> ids;

1
у багатьох випадках ви дійсно не хочете цього робити. Ви втрачаєте тут усі переваги ледачого завантаження
kiedysktos

Використання EAGER не є професійним рішенням.
Рафаель

9

Одним з найкращих рішень є додавання наступного у файл application.properties: spring.jpa.properties.hibernate.enable_lazy_load_no_trans = true


1
Чи можете ви сказати ОП, що саме робить, які побічні ефекти, ефективність?
PeS

3
На задній панелі ледачого завантаження новий сеанс розщеплюється щоразу, коли асоціація завантажується ліниво, отже, більше з'єднань роздвоєне і створює певний тиск на пул з'єднань. Якщо у вас обмеження щодо кількості підключень, можливо, це властивість не є правильним для використання.
sreekmatta

2
для деяких це розглядається як анти-зразок vladmihalcea.com/…
Урі Лоя

7

Я дізнався, що оголошуючи , @PersistenceContextяк EXTENDEDі вирішує цю проблему:

@PersistenceContext(type = PersistenceContextType.EXTENDED)

1
Привіт, будьте обережні з такими змінами. ТРЕЗАКЦІЯ, що охоплює створення контексту стійкості, є лінивим, що було метою ОП Тож питання полягає в тому, хочете ви бути без громадянства чи ні. Цей параметр залежить від призначення системи, і його не слід також змінювати ... охоче. Якщо ти розумієш що я маю на увазі. Читайте тут stackoverflow.com/questions/2547817 / ...
kiedysktos

Небезпечний. Це не правильна відповідь. Є й інші вище набагато точніші та безпечніші.
Рафаель

5

це була проблема, з якою я нещодавно зіткнувся, і яку я вирішив з використанням

<f:attribute name="collectionType" value="java.util.ArrayList" />

Більш детальне роз'яснення тут і це врятувало мені день.


5

Ваш список ліниво завантажується, тому список не завантажений. Виклику, щоб потрапити до списку, недостатньо. використовувати в Hibernate.initialize для внесення списку. Якщо доснт-робота працює на елементі списку і зателефонуйте на Hibernate.initialize для кожного. це потрібно зробити перед тим, як повернутися із сфери транзакції. подивіться на цю посаду.
шукати -

Node n = // .. get the node
Hibernate.initialize(n); // initializes 'parent' similar to getParent.
Hibernate.initialize(n.getChildren()); // pass the lazy collection into the session 

4

Щоб вирішити проблему в моєму випадку, це просто не вистачало цього рядка

<tx:annotation-driven transaction-manager="myTxManager" />

у файлі контексту програми.

@TransactionalАнотація по методі не була взята до уваги.

Сподіваюся, що відповідь комусь допоможе


4

@ Трансакційна примітка на контролері відсутня

@Controller
@RequestMapping("/")
@Transactional
public class UserController {
}

17
Я б заперечував, що управління транзакціями належить до рівня обслуговування, де знаходиться бізнес-логіка.
Sõber

Анотація про трансакцію не відсутня. Контролер не повинен мати такої примітки. Ці примітки повинні бути на рівні Сервісу.
Рафаель

4

Використовуючи @Transactionalанотацію зі сплячки , якщо ви отримуєте об’єкт із бази даних із ледачими вилученими атрибутами, ви можете просто отримати їх, отримавши такі атрибути, як цей:

@Transactional
public void checkTicketSalePresence(UUID ticketUuid, UUID saleUuid) {
        Optional<Ticket> savedTicketOpt = ticketRepository.findById(ticketUuid);
        savedTicketOpt.ifPresent(ticket -> {
            Optional<Sale> saleOpt = ticket.getSales().stream().filter(sale -> sale.getUuid() == saleUuid).findFirst();
            assertThat(saleOpt).isPresent();
        });
}

Тут у транзакції, що керується Hibernate проксі, факт виклику ticket.getSales()зробіть ще один запит для отримання продажів, оскільки ви явно просили його.



2

Для тих, хто працює з Критеріями , я виявив це

criteria.setFetchMode("lazily_fetched_member", FetchMode.EAGER);

зробив усе, що мені було потрібно.

Початковий режим отримання колекцій встановлений на FetchMode.LAZY, щоб забезпечити продуктивність, але коли мені потрібні дані, я просто додаю цей рядок і насолоджуюся повністю заселеними об'єктами.


2

У моєму випадку проблема з наступним кодом:

entityManager.detach(topicById);
topicById.getComments() // exception thrown

Оскільки він відірвався від бази даних, і Hibernate більше не отримував список із поля, коли це було потрібно. Тому я ініціалізую його перед від'єднанням:

Hibernate.initialize(topicById.getComments());
entityManager.detach(topicById);
topicById.getComments() // works like a charm

1

Причина полягає в тому, що ви намагаєтеся отримати список коментарів на контролері після закриття сеансу всередині сервісу.

topicById.getComments();

Вище завантажуватимете список коментарів, лише якщо ваш активний сеанс у сплячому режимі активний, і, мабуть, ви закрили службу.

Отже, вам потрібно отримати список коментарів перед закриттям сесії.


2
Так, це проблема проблеми. Ви також повинні надати відповідь у повідомленніAnswer
Сарц,

1

Колекція commentsу вашому класі моделей Topicліниво завантажена, що є поведінкою за замовчуванням, якщо ви не коментуєте її fetch = FetchType.EAGERконкретно.

Швидше за все, ваша findTopicByIDслужба використовує сеанс сплячого стану без громадянства. Сесія без громадянства не має кеш-пам'яті першого рівня, тобто немає контексту постійності. Пізніше, коли ви спробуєте повторити comments, Hibernate викине виняток.

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: mvc3.model.Topic.comments, no session or session was closed

Рішенням може бути:

  1. Повідомлення за commentsдопомогоюfetch = FetchType.EAGER

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "topic", cascade = CascadeType.ALL)   
    private Collection<Comment> comments = new LinkedHashSet<Comment>();
  2. Якщо ви все ще хочете, щоб коментарі були ліниво завантаженими, використовуйте загальнодоступні сесії Hibernate , щоб згодом ви могли отримати коментарі на вимогу.


1

У моєму випадку я мав картографування б / в Aі Bподібне

A має

@OneToMany(mappedBy = "a", cascade = CascadeType.ALL)
Set<B> bs;

у DAOшарі, метод потрібно анотовувати, @Transactionalякщо ви ще не коментували відображення за допомогою типу Вилучення - Eager


1

Не найкраще рішення, але тим, хто стикається LazyInitializationExceptionособливо з Serializationцим, допоможе. Тут ви перевірите ліниво ініціалізовані властивості та налаштування nullна них. Для цього створіть нижчий клас

public class RepositoryUtil {
    public static final boolean isCollectionInitialized(Collection<?> collection) {
        if (collection instanceof PersistentCollection)
            return ((PersistentCollection) collection).wasInitialized();
        else 
            return true;
    }   
}

Всередині класу Entity, у якого у вас ліниво ініціалізовані властивості, додайте метод, як показано нижче. Додайте всі свої ліниво-завантажувальні властивості всередині цього методу.

public void checkLazyIntialzation() {
    if (!RepositoryUtil.isCollectionInitialized(yourlazyproperty)) {
        yourlazyproperty= null;
    }

Зателефонуйте за цим checkLazyIntialzation()способом у всіх місцях, де ви завантажуєте дані.

 YourEntity obj= entityManager.find(YourEntity.class,1L);
  obj.checkLazyIntialzation();

0

Привіт Усі публікації доволі пізно сподіваємось, що це допомагає іншим, дякуючи заздалегідь @GMK за це повідомлення Hibernate.initialize (об’єкт)

коли Lazy = "вірно"

Set<myObject> set=null;
hibernateSession.open
set=hibernateSession.getMyObjects();
hibernateSession.close();

Тепер, якщо я отримую доступ до "встановити" після закриття сесії, він кидає виняток.

Моє рішення:

Set<myObject> set=new HashSet<myObject>();
hibernateSession.open
set.addAll(hibernateSession.getMyObjects());
hibernateSession.close();

тепер я можу отримати доступ до "встановити" навіть після закриття сплячої сесії.


0

Ще один спосіб зробити це, ви можете використовувати TransactionTemplate, щоб обернутися навколо ледачого підбору. Подібно до

Collection<Comment> commentList = this.transactionTemplate.execute
(status -> topicById.getComments());

0

Проблема викликана тим, що код отримує доступ до ледачого відношення JPA, коли "з'єднання" з базою даних закрите ( постійний контекст - це правильна назва в умовах Hibernate / JPA).

Простий спосіб її вирішення у Spring Boot - це визначення рівня обслуговування та використання @Transactionalанотації. Ця анотація в методі створює транзакцію, яка поширюється в рівень сховища і зберігає відкритий контекст стійкості до завершення методу. Якщо ви отримаєте доступ до колекції всередині транзакційного методу, Hibernate / JPA отримає дані з бази даних.

У вашому випадку вам просто потрібно анотувати за @Transactionalдопомогою методу findTopicByID(id)у вашому методі TopicServiceта змусити отримати колекцію у цьому методі (наприклад, запитавши його розмір):

    @Transactional(readOnly = true)
    public Topic findTopicById(Long id) {
        Topic topic = TopicRepository.findById(id).orElse(null);
        topic.getComments().size();
        return topic;
    }

0

Для позбавлення від винятку лінивої ініціалізації ви не повинні закликати до лінівної колекції під час роботи з відокремленим об'єктом.

На мою думку, найкращим підходом є використання DTO, а не сутності. У цьому випадку ви можете чітко встановити поля, які ви хочете використовувати. Як завжди, цього достатньо. Не потрібно хвилюватися, що щось на кшталт Джексона ObjectMapperабо hashCodeпороджене Lombok буде називати ваші методи неявно.

Для деяких конкретних випадків ви можете використовувати @EntityGrpaphанотацію, яка дозволяє вам eagerзавантажувати, навіть якщо у вас є fetchType=lazyваша організація.


0

Для цього питання про ліниву ініціалізацію існує багато варіантів -

1) Змініть тип асоціації Fetch з LAZY на EAGER, але це не є хорошою практикою, оскільки це погіршить продуктивність.

2) Використовуйте FetchType.LAZY на пов'язаному Об'єкті, а також використовуйте трансакційну анотацію в методі службового рівня, щоб сеанс залишався відкритим, і коли ви будете викликати topicById.getComments (), дочірній об’єкт (коментарі) буде завантажений.

3) Крім того, будь ласка, спробуйте використовувати об'єкт DTO замість сутності в рівні контролера. У вашому випадку сеанс закритий на рівні контролера. Так краще перетворити сутність в DTO на рівні обслуговування.


-11

Я вирішив, використовуючи List, а не Set:

private List<Categories> children = new ArrayList<Categories>();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.