Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate - про борьбу с LAZY / 17 сообщений из 17, страница 1 из 1
11.10.2012, 09:06:12
    #37992992
GKS_Samara
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
Добрый день!

Хочется критики на идею и реализацию.

Проблема известная- ссылки с "fetch = FetchType.LAZY" надо подгружать
пока не завершилась сессия. А она завершается быстро :)
А хочется иметь возможно загрузить потом не городя кучу кода.

Решение.
1. Сделаем так, чтобы один Remote-интерфейс всегда реализовывался одним
бином и их имена были строго связаны (у меня для xx.xxx.YyyRemote всегда
xx.xxx.YyyBL).
2. Пишем класс со статическим методом, который по Class<YyyRemote>
получает ссылку на реализацию.
3. Пишем класс LazyLink с геттером
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
  public E get(Class<? extends Remote<E>> sourceClass) {
    if (elem == null && id != null) {
      Remote<E> source = JndiHelper.find(sourceClass);
      elem = source.getElem(id);
    }
    return (E) elem;
  }
  // set тривиален



4. Где нужна ленивая ссылка пишем
[src]
@Column(name = "svcId")
@Type(type="xx.xxx.LazyLinkMapping")
private LazyLink svc;

public NsSvcRef getSvc() {
return svc.get(NsSvcRefRemote.class);
}
[src]

Соответственно ленивая ссылка будет разрешена ровно в нужный момент без
всяких exception'ов.

Как сама идея? Попробую обобщить на @OneToMany - надо будет изучить
хибернейт получше...

--
Алексей
JID: alxt@ya.ru

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
11.10.2012, 11:20:50
    #37993264
vimba
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
GKS_Samara,

А так ли нужно бороться с LAZY? У меня никогда в жизни проблем с ним не возникало. ИМХО если программист отгребает LazyLoadingExeption значит он не в теме как должна работать его программа, заблудился в ORM и не отдаёт себе отчёт какие данные ему понадобятся в каждый конкретный момент времени.
...
Рейтинг: 0 / 0
11.10.2012, 11:31:33
    #37993294
GKS_Samara
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
Добрый день, vimba!

> А так ли нужно бороться с LAZY?

Получили сущность A a. А у неё есть a.getB().getC().getD().getE().getF()
И вот надо в какой-то момент её получить. И либо сразу грузить это
дерево (очень большое иногда получается), либо время от времени делать
что-нибудь вроде refresh(a.getB().getC().getD()).getE() - это если мы
решили до 3 уровня грузить ссылки. Либо ещё как извращаться.

И постоянно ходишь по минному полю- то ли не получишь эту ссылку (если
грузили A, а D передали в метод, который даже не знает, что ему достался
огрызок с незагруженными ссылками), то ли загрузишь лишнего (а БД такая,
что любой сервер треснет очень быстро от такой работы).

--
Алексей
JID: alxt@ya.ru


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
11.10.2012, 11:38:40
    #37993316
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
GKS_Samara,
а можешь пример выше подкрепить минимальным кодом с ошибкой?
...
Рейтинг: 0 / 0
11.10.2012, 11:53:44
    #37993363
GKS_Samara
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
Добрый день, Petro123!

> а можешь пример выше подкрепить минимальным кодом с ошибкой?

Сейчас проблема не в лази, а в излишней загрузке. Т.е. загрузка списка
объектов иногда идёт очень долго. Чаще всего из-за того, что
подгружается очень много объектов. Если смотреть запросы на БД, то идёт
join на 20-30 таблиц- легко. И хотя индексы везде есть (PK обычно), но
при наших объёмах (десятки миллионов записей на таблицу) БД начинает
тормозить просто на физических чтениях (понятное дело, что кэша тут
никак не хватит на сотню пользователей, даже у супердома).

--
Алексей
JID: alxt@ya.ru


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
11.10.2012, 12:38:17
    #37993481
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
Session.merge() и грузим ленивые свойства. Равзе нет?
...
Рейтинг: 0 / 0
11.10.2012, 12:50:56
    #37993515
GKS_Samara
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
Добрый день, Blazkowicz!

> Session.merge() и грузим ленивые свойства. Равзе нет?

А в JPA есть подобное? persist?
Кроме того, код может выполнятся и на толстом клиенте трёхзвенки, а там
до контекста далеко :)

--
Алексей
JID: alxt@ya.ru


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
11.10.2012, 12:54:54
    #37993529
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
GKS_SamaraА в JPA есть подобное? persist?

Ты ещё про андроид спроси.
А че, в ЖПА вроде оба есть. Не?
http://stackoverflow.com/questions/1069992/jpa-entitymanager-why-use-persist-over-merge

GKS_SamaraКроме того, код может выполнятся и на толстом клиенте трёхзвенки, а там
до контекста далеко :)

Толстый клиент отдельная тема вообще. Там разные могут быть варианты.
Посмотри Gilead для GWT, он для толстого клиента не обязательно подойдёт, но мысли интересные подчерпнуть можно.
...
Рейтинг: 0 / 0
11.10.2012, 12:58:35
    #37993538
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
Не очень понял зачем какие-то аннотации. Если догружать надо на толстом клиенте, то проще все сущности обернуть в AOP и если свойство не загружено, то делать удаленный вызов по id.
Моё мнение, что это лишняя трата времени на отдельный фреймверк, потому что в дальнейшем придется все равно бороться с производительностью с помощью FetchMode. Вроде недавно был флейм на эту тему.
...
Рейтинг: 0 / 0
11.10.2012, 14:03:12
    #37993713
chpasha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
я конечно не очень давно с хибером балуюсь, но до сих пор все вопросы решались правильным указанием join fetch. у тебя проблема в определении где и какие данные нужны?
...
Рейтинг: 0 / 0
11.10.2012, 14:29:44
    #37993778
GKS_Samara
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
Добрый день, chpasha!

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

Проблема в том, что в метод, который вообще не работает с БД, приходит
объект. И ему надо прочитать какое-то свойство. А прочитано ли оно-
зависит от того, кто и как читал этот объект. Вот это и не нравится.

--
Алексей
JID: alxt@ya.ru


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
11.10.2012, 14:30:53
    #37993783
GKS_Samara
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
Добрый день, Blazkowicz!

> Не очень понял зачем какие-то аннотации. Если догружать надо на толстом
> клиенте, то проще все сущности обернуть в AOP и если свойство не
> загружено, то делать удаленный вызов по id.

В целом моё предложение похоже :)

> Посмотри Gilead для GWT, он для толстого клиента
> не обязательно подойдёт, но мысли интересные почерпнуть можно.

Почитаю, спасибо.

--
Алексей
JID: alxt@ya.ru


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
11.10.2012, 15:59:57
    #37994020
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
GKS_Samara,
Не очень врубаюсь в проблему.
Во время запроса ленивого свойства, сессия ведь открыта. Почему объект, видя что вместо данных нуллл не запросит данные в бд?
...
Рейтинг: 0 / 0
11.10.2012, 16:01:54
    #37994029
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
Petro123Во время запроса ленивого свойства, сессия ведь открыта.
При толстом клиенте - не обязательно.

Petro123Почему объект, видя что вместо данных нуллл не запросит данные в бд?
Там не null. Там id без самого объекта. По null нельзя определить то ли нет ассоциации, то ли есть, но не загружена.
...
Рейтинг: 0 / 0
11.10.2012, 16:07:37
    #37994038
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
Blazkowicz,
Я только про тонкий с сессией на запрос.
У толстого другие принципы.
У тонкого тоже айдишник?
...
Рейтинг: 0 / 0
11.10.2012, 16:27:30
    #37994072
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
Petro123Я только про тонкий с сессией на запрос.
У толстого другие принципы.
У тонкого тоже айдишник?

На толстом всё зависит от того как будешь сериализовать. Если Java сериализацией, то там будут полноценные сущности с той лишь разницей что негда взять сессию, чтобы прицепиться для ленивого чтения.
Если сериализовать в DTO, то нужно будет изобретать заново многое из того что уже есть в ORM. Трекинг удаления, например. Ну и ленивые свойства, если захочется. Но я пока не вижу нафиг они на клиенте. FetchMode наше всё.

Вот тут интересные раздумья по теме
http://blogs.gotdotnet.ru/personal/bezzus/PermaLink.aspx?guid=7a6a69bd-bedf-425f-b09c-123b4a41f686
Только там надо фильтровать отдельно Anemic vs Rich, отдельно тему ленивой загрузки.
...
Рейтинг: 0 / 0
11.10.2012, 16:45:09
    #37994101
IDVsbruck
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate - про борьбу с LAZY
Ссылка не работает.

В своем веб-проекте с удивлением заметил, что в некоторых случаях фильтр OpenSessionInViewFilter срабатывал, в некоторых нет. Поэтому иногда подчитать ленивые зависимости не получалось. Выкинул вовсе этот фильтр и воспользовался возможностями из прокси-пакета хибера:
Код: java
1.
2.
3.
4.
5.
6.
public <T> T initializeAndUnproxy(T entity) {
	if (entity == null) throw new NullPointerException("Entity passed for initialization is null");
	Hibernate.initialize(entity);
	if (entity instanceof HibernateProxy) entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
	return entity;
}


Автоматизм, конечно, свелся к нулю - каждую сущность надо прогонять через этот метод, но зато железобетон ... Хотя в рамках приложения, которое планируется как высоконагруженное масштабируемое, где количество JOIN'ов надо свести к минимуму (следовательно, архитектурно выгоднее заменить многие ленивые зависимые коллекции на дополнительный "лишний" запрос), оказывается не таким уж и затратным.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate - про борьбу с LAZY / 17 сообщений из 17, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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