|
|
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
Добрый день, уважаемые программисты! Кто знает, помогите пожалуйста советом. Есть вопрос по поводу ленивой загрузки. Существует объект А который связан с 1-* с объектом Б, тоесть в А есть коллекция объеков Б. Параметр lazy = true Если при такой загрузке и при закрытой сессии попробовать получить объект Б из А то появится lazyinitializationexception. Чтобы избежать этой ошибки я написал метод, который вытягивает из базы сет объектов Б которые принадлежат А и устанавливет их в объект А. Сейчас вроде как коллекция объектов Б в А заполнена. Но как теперь сказать хибернейту что эта коллекция проинициализирована? Даже если коллекция заполнена, то при попытки ее получить из А всеравно появляетя lazyinitializationexception. P.S. Hibernate v 4.2.7. Спринг не использую; lazy=false не подходит; инициализировать сразу при загрузке в открытой сессии не могу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 12:24:55 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
Объясните почему у вас одна и та же коллекция живет в разных сессиях? Можно попробовать Session.merge для новой сессии, чтобы догрузить коллекцию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 12:38:26 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, Ну вот пример: Я выгрузил из БД таблицу Departaments. В БД Departaments связано one-to-many с Employee. Записал все выгруженные данные в HashMap(Departament.getId() - ключ , Departament - значение) для быстрого доступа к департамертам. Далее я закрыл сессию. Через какое-то время мне необходимо посмотреть у конкретного департамента список его работников. Я достаю департамент из мапы и делаю getEmployees(); Тут то и возникает lazyexception. Я его перехватываю и делаю то, что описал выше - вытягиваю сотрудников с БД для этого департамента ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 12:51:30 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
И в чем глубинный смысл хранения департаментов в HashMap? Если это рукописный кэш, то достаточно просот включить Level 2 cache в хибернейт, чтобы добиться аналогичного эффекта. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 13:11:34 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, Да, это рукописный кеш. Данные у меня выгружаются из базы и попадают в мапы. Над департаментами я произвожу много различных модификаций, и над сотрудниками которые лежат в них тоже и только через определенное время (по джобам), или по событиям я обновляю эти данные обратно в базу. Задумка была такая - вся работа в оперативке и в крайних случаях с базой. Возможно это не совсем верное решение и стоит пересмотреть его. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 13:32:14 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
max_drmickBlazkowicz, Да, это рукописный кеш. Данные у меня выгружаются из базы и попадают в мапы. Над департаментами я произвожу много различных модификаций, и над сотрудниками которые лежат в них тоже и только через определенное время (по джобам), или по событиям я обновляю эти данные обратно в базу. Задумка была такая - вся работа в оперативке и в крайних случаях с базой. Возможно это не совсем верное решение и стоит пересмотреть его. вы замерьте, будут ли у вас реальные тормоза при использовании справочников. А потом уже оптимизируйте и делайте свой рукописный хеш-велосипед. Как будто никто не делает со справочниками то же самое что и вы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 13:39:25 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
max_drmickДа, это рукописный кеш. Данные у меня выгружаются из базы и попадают в мапы. Над департаментами я произвожу много различных модификаций, и над сотрудниками которые лежат в них тоже и только через определенное время (по джобам), или по событиям я обновляю эти данные обратно в базу. Задумка была такая - вся работа в оперативке и в крайних случаях с базой. Возможно это не совсем верное решение и стоит пересмотреть его. Ну, вот. Теперь понятно. Убираем свой кэш. Включаем и настраиваем Level 2 Cache в ORM и проблема ленивой инициализации уходит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 13:42:41 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
Petro123, Под справочником вы имели ввиду бд? Если да, то тормоза будут и к гадалке не ходи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 13:43:15 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
max_drmickPetro123, Под справочником вы имели ввиду бд? Если да, то тормоза будут и к гадалке не ходи. - сущность - Справочник. "Города", например. - сходи к гадалке и _приведи цифры_. Если не поможет - Blazkowicz сказал - кэш2 (обычно и без него работает) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 13:46:19 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
max_drmickПод справочником вы имели ввиду бд? Если да, то тормоза будут и к гадалке не ходи. Департаменты - это ваш справочник. К ним идёт частое обращение. Поэтому логично, что их нужно кешировать. Для этого есть Hibernate Level 2 cache. Кстати ассоциация Department -> Employee вызывает некоторое недоумение. Во-первых этот список может оказаться достаточно больших. Во-вторых Department может использовать в множестве других сущностей, и для каждой из них у Department будет своя коллекция? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 13:51:13 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
Blazkowiczmax_drmickДа, это рукописный кеш. Данные у меня выгружаются из базы и попадают в мапы. Над департаментами я произвожу много различных модификаций, и над сотрудниками которые лежат в них тоже и только через определенное время (по джобам), или по событиям я обновляю эти данные обратно в базу. Задумка была такая - вся работа в оперативке и в крайних случаях с базой. Возможно это не совсем верное решение и стоит пересмотреть его. Ну, вот. Теперь понятно. Убираем свой кэш. Включаем и настраиваем Level 2 Cache в ORM и проблема ленивой инициализации уходит. Спасибо за совет. Тогда появился второй вопрос. Получается если я загружу какой-то департамент, поменяю в нем что-то, то в БД апдейтить это не нужно будет? Если я второй раз попытаюсь его оттуда взять то т.к. он будет закеширован хибер мне вернет уже департамент с новыми значениями которые я ему установил, верно? И еще - "проблема ленивой инициализации уходит." не могли бы вы пояснить, если вам не трудно, каким образом она уходит? Т.е. я загружу департамент вместе с сотрудниками в кеш второго уровня с параметром lazy = false? Заранее благодарю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 13:53:21 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
max_drmick, если ограничить только первым кешем, то он гарантирует ВСЮ работу без запросов в БД в оперативке В ОДНОЙ СЕССИИ. Открой её, сделай работу и закрой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 13:59:55 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
Petro123max_drmickPetro123, Под справочником вы имели ввиду бд? Если да, то тормоза будут и к гадалке не ходи. - сущность - Справочник. "Города", например. - сходи к гадалке и _приведи цифры_. Если не поможет - Blazkowicz сказал - кэш2 (обычно и без него работает) У меня департаментов порядка 2млн. У каждого из них до 100 сотрудников. И запросы идут с большой скоростью (главная проблема) Так что без кеша тут никак ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 14:02:25 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
max_drmickPetro123пропущено... - сущность - Справочник. "Города", например. - сходи к гадалке и _приведи цифры_. Если не поможет - Blazkowicz сказал - кэш2 (обычно и без него работает) У меня департаментов порядка 2млн. У каждого из них до 100 сотрудников. И запросы идут с большой скоростью (главная проблема) Так что без кеша тут никак Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. тебе решать. Есть плюсы и минусы. У второго кэша их тоже не мало. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 14:08:13 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
max_drmickТогда появился второй вопрос. Получается если я загружу какой-то департамент, поменяю в нем что-то, то в БД апдейтить это не нужно будет? Как это не нужно? А как тогда фиксировать состояние? max_drmickЕсли я второй раз попытаюсь его оттуда взять то т.к. он будет закеширован хибер мне вернет уже департамент с новыми значениями которые я ему установил, верно? Нет. Хибернейт не кеширует объекты целиком. Он их разбирает\собирает. Поэтому чтобы обновить данные в кеше, нужно сохранить изменения в базу. max_drmickИ еще - "проблема ленивой инициализации уходит." не могли бы вы пояснить, если вам не трудно, каким образом она уходит? Т.е. я загружу департамент вместе с сотрудниками в кеш второго уровня с параметром lazy = false? Какждый раз грузим из Session. Если нужно без сотрудников, то они и так не грузятся. Если нужно с сотрудниками, то они соответсвенно дргрузятся при первом обращении к коллекции. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 14:09:32 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
max_drmickИ запросы идут с большой скоростью (главная проблема) тут я как раз и говорил и типе приложения. Если это HTTP ГУИ, то время инициализации сесии юзверя-ГУИ достаточно велико. Этого хватает для 1го кэша и открытия справочника. Потом активная работа и отключения юзверя. Т.е либо сессия на запрос, либо сессия "Open Session In View" и этого хватает Если ВИ или преценденты другие, то тут вопрос другой. IMHO ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 14:13:15 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
Если сам Department меняется чаще, чем эти изменения нужно фиксировать в БД. (это, например, стандартая ситуация в игровых серверах), то достаточно просто выкинуть связь Department -> Employee и вычитывать Employee каждый раз, когда они нужны. В общем, тут вариантов куча, но Petro123, действительно прав в том что нам тут массу критических нюансов, как обычно, не сообщают. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 14:16:26 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
BlazkowiczЕсли сам Department меняется чаще, чем эти изменения нужно фиксировать в БД. (это, например, стандартая ситуация в игровых серверах), то достаточно просто выкинуть связь Department -> Employee и вычитывать Employee каждый раз, когда они нужны. В общем, тут вариантов куча, но Petro123, действительно прав в том что нам тут массу критических нюансов, как обычно, не сообщают. Ну тоесть нельзя в связке 1к* сначала получилучить только департамент, потом в другой сессии сотрудников этого департамента, положить этих сотрудников в этот департамент и сделать так, чтобы хибернейт знал о том что сотрудники этого департамента были проинициализированы? (В hibernate 4.1.8 такая возможность как раз появлялась - позволяла загружать сотрудников в другой сессии и хибернейт больше не выдавал lazyinitializationexception, но в 4.1.9 ее убрали) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 14:41:03 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
Что совсем никто не инициализировал так коллекцию... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 17:20:58 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
max_drmickЧто совсем никто не инициализировал так коллекцию... Session.merge(department) не помогает? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 17:21:47 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
Фича, кстати, появилась в 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 включен? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 17:33:03 |
|
||
|
hibernate lazyinitializationexception ручная инициализация
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, Вот этот параметр как раз таки помогал отлично, но потом я наткнулся на тему https://hibernate.atlassian.net/i#browse/HHH-7971 и тут у меня начали возникать сомнения, а не сломается ли что-нибудь в самый неподходящий момент session.merge пока еще не пробовал, вот только до дома доберусь ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 18:01:39 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38478020&tid=2128123]: |
0ms |
get settings: |
8ms |
get forum list: |
10ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
69ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
57ms |
get tp. blocked users: |
1ms |
| others: | 211ms |
| total: | 369ms |

| 0 / 0 |
