powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / hibernate lazyinitializationexception ручная инициализация
22 сообщений из 22, страница 1 из 1
hibernate lazyinitializationexception ручная инициализация
    #38477967
max_drmick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день, уважаемые программисты!

Кто знает, помогите пожалуйста советом.
Есть вопрос по поводу ленивой загрузки.
Существует объект А который связан с 1-* с объектом Б, тоесть в А есть коллекция объеков Б.
Параметр lazy = true



Если при такой загрузке и при закрытой сессии попробовать получить объект Б из А то появится lazyinitializationexception.

Чтобы избежать этой ошибки я написал метод, который вытягивает из базы сет объектов Б которые принадлежат А и устанавливет их в объект А. Сейчас вроде как коллекция объектов Б в А заполнена. Но как теперь сказать хибернейту что эта коллекция проинициализирована? Даже если коллекция заполнена, то при попытки ее получить из А всеравно появляетя lazyinitializationexception.



P.S. Hibernate v 4.2.7. Спринг не использую;
lazy=false не подходит;
инициализировать сразу при загрузке в открытой сессии не могу.
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38477987
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Объясните почему у вас одна и та же коллекция живет в разных сессиях?
Можно попробовать Session.merge для новой сессии, чтобы догрузить коллекцию.
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478020
max_drmick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,

Ну вот пример:

Я выгрузил из БД таблицу Departaments. В БД Departaments связано one-to-many с Employee.

Записал все выгруженные данные в HashMap(Departament.getId() - ключ , Departament - значение) для быстрого доступа к департамертам. Далее я закрыл сессию.

Через какое-то время мне необходимо посмотреть у конкретного департамента список его работников.

Я достаю департамент из мапы и делаю getEmployees();

Тут то и возникает lazyexception.

Я его перехватываю и делаю то, что описал выше - вытягиваю сотрудников с БД для этого департамента
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478075
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И в чем глубинный смысл хранения департаментов в HashMap? Если это рукописный кэш, то достаточно просот включить Level 2 cache в хибернейт, чтобы добиться аналогичного эффекта.
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478123
max_drmick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,

Да, это рукописный кеш. Данные у меня выгружаются из базы и попадают в мапы.
Над департаментами я произвожу много различных модификаций, и над сотрудниками которые лежат в них тоже и только через определенное время (по джобам), или по событиям я обновляю эти данные обратно в базу. Задумка была такая - вся работа в оперативке и в крайних случаях с базой. Возможно это не совсем верное решение и стоит пересмотреть его.
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478145
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
max_drmickBlazkowicz,

Да, это рукописный кеш. Данные у меня выгружаются из базы и попадают в мапы.
Над департаментами я произвожу много различных модификаций, и над сотрудниками которые лежат в них тоже и только через определенное время (по джобам), или по событиям я обновляю эти данные обратно в базу. Задумка была такая - вся работа в оперативке и в крайних случаях с базой. Возможно это не совсем верное решение и стоит пересмотреть его.
вы замерьте, будут ли у вас реальные тормоза при использовании справочников. А потом уже оптимизируйте и делайте свой рукописный хеш-велосипед.
Как будто никто не делает со справочниками то же самое что и вы.
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478154
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
max_drmickДа, это рукописный кеш. Данные у меня выгружаются из базы и попадают в мапы.
Над департаментами я произвожу много различных модификаций, и над сотрудниками которые лежат в них тоже и только через определенное время (по джобам), или по событиям я обновляю эти данные обратно в базу. Задумка была такая - вся работа в оперативке и в крайних случаях с базой. Возможно это не совсем верное решение и стоит пересмотреть его.
Ну, вот. Теперь понятно. Убираем свой кэш. Включаем и настраиваем Level 2 Cache в ORM и проблема ленивой инициализации уходит.
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478157
max_drmick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Petro123,

Под справочником вы имели ввиду бд? Если да, то тормоза будут и к гадалке не ходи.
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478169
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
max_drmickPetro123,

Под справочником вы имели ввиду бд? Если да, то тормоза будут и к гадалке не ходи.
- сущность - Справочник. "Города", например.
- сходи к гадалке и _приведи цифры_.
Если не поможет - Blazkowicz сказал - кэш2 (обычно и без него работает)
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478188
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
max_drmickПод справочником вы имели ввиду бд? Если да, то тормоза будут и к гадалке не ходи.
Департаменты - это ваш справочник. К ним идёт частое обращение. Поэтому логично, что их нужно кешировать. Для этого есть Hibernate Level 2 cache.

Кстати ассоциация Department -> Employee вызывает некоторое недоумение.
Во-первых этот список может оказаться достаточно больших.
Во-вторых Department может использовать в множестве других сущностей, и для каждой из них у Department будет своя коллекция?
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478192
max_drmick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowiczmax_drmickДа, это рукописный кеш. Данные у меня выгружаются из базы и попадают в мапы.
Над департаментами я произвожу много различных модификаций, и над сотрудниками которые лежат в них тоже и только через определенное время (по джобам), или по событиям я обновляю эти данные обратно в базу. Задумка была такая - вся работа в оперативке и в крайних случаях с базой. Возможно это не совсем верное решение и стоит пересмотреть его.
Ну, вот. Теперь понятно. Убираем свой кэш. Включаем и настраиваем Level 2 Cache в ORM и проблема ленивой инициализации уходит.

Спасибо за совет.
Тогда появился второй вопрос. Получается если я загружу какой-то департамент, поменяю в нем что-то, то в БД апдейтить это не нужно будет? Если я второй раз попытаюсь его оттуда взять то т.к. он будет закеширован хибер мне вернет уже департамент с новыми значениями которые я ему установил, верно?

И еще - "проблема ленивой инициализации уходит." не могли бы вы пояснить, если вам не трудно, каким образом она уходит? Т.е. я загружу департамент вместе с сотрудниками в кеш второго уровня с параметром lazy = false?

Заранее благодарю.
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478204
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
max_drmick,
если ограничить только первым кешем, то он гарантирует ВСЮ работу без запросов в БД в оперативке В ОДНОЙ СЕССИИ.
Открой её, сделай работу и закрой.
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478212
max_drmick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Petro123max_drmickPetro123,

Под справочником вы имели ввиду бд? Если да, то тормоза будут и к гадалке не ходи.
- сущность - Справочник. "Города", например.
- сходи к гадалке и _приведи цифры_.
Если не поможет - Blazkowicz сказал - кэш2 (обычно и без него работает)


У меня департаментов порядка 2млн.
У каждого из них до 100 сотрудников.
И запросы идут с большой скоростью (главная проблема)
Так что без кеша тут никак
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478221
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
max_drmickPetro123пропущено...

- сущность - Справочник. "Города", например.
- сходи к гадалке и _приведи цифры_.
Если не поможет - Blazkowicz сказал - кэш2 (обычно и без него работает)


У меня департаментов порядка 2млн.
У каждого из них до 100 сотрудников.
И запросы идут с большой скоростью (главная проблема)
Так что без кеша тут никак
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Хорошими кандидатами на кэширования являются классы, которые представляют:
•    Данные, которые редко меняются
•    Не критичные данные
•    Данные, которые локальны для приложения и не являются общими
Плохими кандидатами для КЭШа второго уровня являются:
•    Данные, которые часто меняются
•    Финансовые данные
•    Данные, которые являются общими с другими приложениями
Однако, это не все правила, которые мы обычно применяем. Многие приложения имеют несколько классов, со следующими свойствами:
•    Маленькое количество экземпляров
•    На каждый экземпляр ссылается много других экземпляров другого класса или классов
•    Экземпляры редко (или никогда) обновляются
Такие данные иногда называют справочными данными. Справочные данные являются отличным кандидатом для кэширования процессным или кластерным КЭШем, и любое приложение, которое интенсивно использует  эти данные сильно выигрывает от того, что данные закэшированы. Вы позволяете данным обновляться во время истечение таймаута КЭШа.
===============
тебе решать.
Есть плюсы и минусы. У второго кэша их тоже не мало.
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478224
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
max_drmickТогда появился второй вопрос. Получается если я загружу какой-то департамент, поменяю в нем что-то, то в БД апдейтить это не нужно будет?
Как это не нужно? А как тогда фиксировать состояние?

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

Нет. Хибернейт не кеширует объекты целиком. Он их разбирает\собирает. Поэтому чтобы обновить данные в кеше, нужно сохранить изменения в базу.

max_drmickИ еще - "проблема ленивой инициализации уходит." не могли бы вы пояснить, если вам не трудно, каким образом она уходит? Т.е. я загружу департамент вместе с сотрудниками в кеш второго уровня с параметром lazy = false?

Какждый раз грузим из Session. Если нужно без сотрудников, то они и так не грузятся. Если нужно с сотрудниками,
то они соответсвенно дргрузятся при первом обращении к коллекции.
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478230
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
max_drmickИ запросы идут с большой скоростью (главная проблема)
тут я как раз и говорил и типе приложения.
Если это HTTP ГУИ, то время инициализации сесии юзверя-ГУИ достаточно велико.
Этого хватает для 1го кэша и открытия справочника. Потом активная работа и отключения юзверя.
Т.е либо сессия на запрос, либо сессия "Open Session In View"
и этого хватает
Если ВИ или преценденты другие, то тут вопрос другой.
IMHO
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478236
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если сам Department меняется чаще, чем эти изменения нужно фиксировать в БД. (это, например, стандартая ситуация в игровых серверах), то достаточно просто выкинуть связь Department -> Employee и вычитывать Employee каждый раз, когда они нужны.
В общем, тут вариантов куча, но Petro123, действительно прав в том что нам тут массу критических нюансов, как обычно, не сообщают.
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478302
max_drmick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczЕсли сам Department меняется чаще, чем эти изменения нужно фиксировать в БД. (это, например, стандартая ситуация в игровых серверах), то достаточно просто выкинуть связь Department -> Employee и вычитывать Employee каждый раз, когда они нужны.
В общем, тут вариантов куча, но Petro123, действительно прав в том что нам тут массу критических нюансов, как обычно, не сообщают.

Ну тоесть нельзя в связке 1к* сначала получилучить только департамент, потом в другой сессии сотрудников этого департамента, положить этих сотрудников в этот департамент и сделать так, чтобы хибернейт знал о том что сотрудники этого департамента были проинициализированы? (В hibernate 4.1.8 такая возможность как раз появлялась - позволяла загружать сотрудников в другой сессии и хибернейт больше не выдавал lazyinitializationexception, но в 4.1.9 ее убрали)
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478666
max_drmick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Что совсем никто не инициализировал так коллекцию...
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478667
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
max_drmickЧто совсем никто не инициализировал так коллекцию...
Session.merge(department) не помогает?
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478702
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фича, кстати, появилась в 1.4.6
https://hibernate.atlassian.net/browse/HHH-7457
И я не вижу ничего такого что бы в 1.4.9 её отменяло
https://hibernate.atlassian.net/secure/ReleaseNote.jspa?projectId=10031&version=12367
Разве что переделали выброс исключения
https://hibernate.atlassian.net/browse/HHH-7806

hibernate.enable_lazy_load_no_trans включен?
...
Рейтинг: 0 / 0
hibernate lazyinitializationexception ручная инициализация
    #38478780
max_drmick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,

Вот этот параметр как раз таки помогал отлично, но потом я наткнулся на тему

https://hibernate.atlassian.net/i#browse/HHH-7971 и тут у меня начали возникать сомнения, а не сломается ли что-нибудь в самый неподходящий момент


session.merge пока еще не пробовал, вот только до дома доберусь
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / hibernate lazyinitializationexception ручная инициализация
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]