Коллекции Hibernate не заполняются при запуске из идеи IntelliJ - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть приложение весенней загрузки с Hibernate. IDE IntelliJ идея 2018.3, но проблема, как доказывается, возникает во всех версиях до 2019.3.4

Шаги для воспроизведения не являются полностью детерминированными c, но это выглядит примерно так:

  1. Создайте приложение с помощью maven из командной строки
  2. Запустите приложение из IntelliJ Idea
  3. В объекте выбора кода с дочерней коллекцией распечатайте его элементы - коллекция содержит мало - ожидается
  4. Не определено c шаг : перезапустить приложение, перестроить приложение из меню IntelliJ, повторить несколько раз
  5. Запустить приложение снова
  6. Выбрать тот же объект с дочерней коллекцией, распечатайте его элементы - элементы теперь пусты, ошибка не выдается - неожиданно

Существуют четкие шаги, которые нужно исправить:

  1. Очистить кэш идей / restart
  2. mvn clean package проект из командной строки
  3. Перезапустить приложение
  4. Теперь загруженный объект снова содержит элементы

Наблюдение:

  1. Никогда не происходило при беге вне идеи IntelliJ, т.е. развернуто в реальной среде

Это заставляет меня думать, что это как-то связано с тем, что он работает в IntelliJ.

Что я пробовал:

  1. Отладчик - дошел до того момента, когда запрос к БД выполняется, и запрос корректен и содержит даже элементы коллекции. При обработке результата они просто не заполняются в коллекцию.
  2. Несмотря на то, что отладить код нелегко, я думаю заполнение коллекции пропускается при условии, аналогичном isEnhancedForLazyLoading(), которое я думаю, что это может быть связано с прокси и манипуляциями с байт-кодом (?)

Я ищу понимание того, в чем может быть разница между сборкой классов с Maven и командной строкой по сравнению со сборкой проект в IntelliJ, особенно в отношении классов и прокси Hibernate.

1 Ответ

1 голос
/ 08 апреля 2020

Похоже, что это побочный эффект отложенной загрузки, возможно, при реализации с помощью улучшения байт-кода.

Если я правильно вас понимаю, вы используете отладчик для проверки свойств объекта JPA. Для реализации отложенной загрузки и грязной проверки реализации JPA необходимо получить код между кодом, который вы пишете для ваших сущностей, и кодом, использующим эти сущности.

Чтобы проверить эту догадку и уточнить, что именно точно происходит, и когда вам, вероятно, нужно прочитать условия улучшения байт-кода в Hibernate.

Есть два варианта, как это сделать:

  1. Прокси: вы не возвращаете сущности, а прокси, которые ведут себя как сущность (более или менее), но также заботятся о ленивой загрузке. Это может привести к тому, что в некоторых случаях, например, приведение может завершаться сбоем в зависимости от того, как был загружен объект.

  2. Манипулирование байтовым кодом: некоторый дополнительный байтовый код вводится в класс сущности в чтобы позаботиться о ленивой загрузке и тд. AFAIK это обычно происходит, когда класс загружается, т.е. байт-код в файловой системе не изменяется, но JVM фактически выполняет его манипулированную версию. Это означает, что байт-код не совпадает с кодом, видимым в IDE, и IDE не знает об этом, так как он проверяет, что байт-код в файловой системе совпадает с исходным кодом, и выдает предупреждение, если два не совпадают .

Я подозреваю, что когда код компилируется и выполняется через Maven, используется второй вариант, но если он компилируется / запускается средой IDE, используется первый вариант, что приводит к путанице и изменение поведения.

Я предлагаю использовать геттеры и варианты «оценивать выражение» для проверки свойств ваших сущностей.

...