Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > EntityContext


Автор: Rusico 18.7.2007, 10:26
Здрасти всем.

Продолжая мучать JBoss и себя:

Есть бин, который имеет ссылку на другой бин. Из клиентской проги надо достучаться до первого бина, а через него до второго.
Клиент и JBoss в разных JVM, т.е. как я понимаю через Container Managed Relationship это не реализовать из-за 
необходимости использования локальных интерфейсов.
    Я пошёл другим путём - использую удалённые интерфейсы - всё работает, но на поиск компонента (получение домашнего интерфейса) 
уходит много времени. Компонентов может быть очень много, и каждый раз осуществлять поиск накладно. 
Отсюда вопрос:
  Можно ли как-то кэшировать ссылки на домашние интерфейсы компонент для доступа к ним из других бинов?

Добавлено через 3 минуты и 9 секунд
да, забыл про тему:

я думаю что можно хранить ссылки в EntityContext.getEnvironment()

но когда я вызываю этот метод из бина - вылетает ошибка EJBException Deprecated

Автор: AntonSaburov 18.7.2007, 13:39
Цитата(Rusico @  18.7.2007,  10:26 Найти цитируемый пост)
Можно ли как-то кэшировать ссылки на домашние интерфейсы компонент для доступа к ним из других бинов?

Может попробовать сделать их SessionFull ? ТОгда по идее они должны быстрее подниматься.
А по поводу хранения ссылки - надо почитать - где-то я такое смотрел. Если найду - напишу

Автор: Rusico 18.7.2007, 13:52
конечно можно было бы сделать так:

 Entity Bean будут лиш отображением строк в таблице БД,
 А всю логику отношений между этими бинами реализовать в Session Bean.

Но мне как-то не нравится этот способ - некрасиво получается.

Я уж даже и не знаю: если не получится, то придётся писать используя чистый RMI, 
хотя идея EJB очень привлекательна.

Автор: ekr 18.7.2007, 14:33
Цитата(Rusico @  18.7.2007,  10:26 Найти цитируемый пост)
Я пошёл другим путём - использую удалённые интерфейсы - всё работает, но на поиск компонента (получение домашнего интерфейса) 
уходит много времени.

Т.е. в stateless или stateful-бине (клиенте) инкапсулируется логика поиска связанного с основным дочернего entity-бина? Да, так можно делать и частенько такие решения встречаются. Но это неудобно, т.к. усложняется код клиента для entity-бинов. Лучше пользоваться cmr (relations).

Цитата(Rusico @  18.7.2007,  10:26 Найти цитируемый пост)
но на поиск компонента (получение домашнего интерфейса) 
уходит много времени. 

надо кешировать домашний объект. Соответственно:
Цитата(Rusico @  18.7.2007,  10:26 Найти цитируемый пост)
Можно ли как-то кэшировать ссылки на домашние интерфейсы компонент для доступа к ним из других бинов?

в entity-бине сделать свойство типа фабрики и инициализировать его в setEntityContext

Но, в целом, могу порекомендовать другой подход. Этот же подход рекомендуют bea и ibm )))
Следует все-таки пользоваться CMP-relations, а проблема доступа к ним из удаленного клиента решается следующим образом: создается метод в удаленном интерфейсе (доступен удаленным клиентам), который локально работает с cmr-полями, а удаленному клиенту отдает Value Objects, т.е. обычные pojo, залитые свойствами связанного объекта.

Автор: AntonSaburov 18.7.2007, 15:07
Цитата(Rusico @  18.7.2007,  13:52 Найти цитируемый пост)
Entity Bean будут лиш отображением строк в таблице БД,

Цитата(ekr @  18.7.2007,  14:33 Найти цитируемый пост)
удаленному клиенту отдает Value Objects, т.е. обычные pojo, залитые свойствами связанного объекта. 

Вообщем-то этот вариант действительно считается предпочтительным. Думаю, что он может ускорить. Покопайтесь - может и правда получится ускорится

Автор: Rusico 18.7.2007, 15:54
Цитата

в entity-бине сделать свойство типа фабрики и инициализировать его в setEntityContext


как я понимаю setEntityContext вызывается каждый раз при создании бина?
Если так, то я не понимаю - ну создам я свойство в бине, а как его инициализировать, ведь если
setEntityContext вызывается каждый раз при создании бина то и инициализация (получение ссылок) будет 
вызываться каждый раз? или нет? поясните плз.

Цитата

создается метод в удаленном интерфейсе (доступен удаленным клиентам), который локально работает с cmr-полями, а удаленному клиенту отдает Value Objects, т.е. обычные pojo, залитые свойствами связанного объекта.


Т.Е. создаётся Session Bean, который локально работает с Entity Beans, а возвращает "всё что угодно" (String, Collection и т.п.) кроме самого компонента (ссылки на него)?

Автор: ekr 18.7.2007, 17:27
Цитата(Rusico @  18.7.2007,  15:54 Найти цитируемый пост)
поясните плз.

Вам нужно инфы? Их есть у меня )))

У entity-бина сложный жизненный цикл. Изначально создается пул bean instances. В пуле бины - это просто пустые болваночки, несвязанные пока с конкретным значением pk. На этих болваночках отрабатывают finder- и home-методы. При создании этой болваночки вызывается setEntCtx у неё.
Затем, когда клиенту понадобятся конкретные данные, он вызывает create или find у фабрики. Фабрика выбирает произвольную болваночку из пула, ассоциирует с ней занчение pk и, возможно, заливает в неё данные из базы. Теперь этот bean instance уже не в пуле, а в кеше (состояние ready).
Перемещение объекта из пула в кеш и обратно может происходить когда угодно, это называется пассивизация/активизация.

Автор: ekr 18.7.2007, 17:29
Цитата(Rusico @  18.7.2007,  15:54 Найти цитируемый пост)
Т.Е. создаётся Session Bean, который локально работает с Entity Beans, а возвращает "всё что угодно" (String, Collection и т.п.) кроме самого компонента (ссылки на него)? 

Да. Обычно "всё что угодно" - это pojo:
Цитата(ekr @  18.7.2007,  14:33 Найти цитируемый пост)
Value Objects, т.е. обычные pojo, залитые свойствами связанного объекта.


Автор: Rusico 18.7.2007, 19:57
Эх жаль smile - видимо EJB всё-таки оправдан для очень сильно распределённых приложений

Добавлено через 4 минуты и 18 секунд
У меня в БД есть 10000 записей (в таблице), они отображаются в Entity Beans, так вот поиск через findAll() работает настолько 
медленно (0,5-2 мин), что видимо придётся глядеть в сторону простого RMI.
 (Просто через RMI та же работа выполняется за 8 с., а прямая выборка из БД за1-2 с.)

Автор: ekr 18.7.2007, 20:01
Цитата(Rusico @  18.7.2007,  19:57 Найти цитируемый пост)
Эх жаль

а чего жаль-то? ))))
Цитата(Rusico @  18.7.2007,  19:57 Найти цитируемый пост)
видимо EJB всё-таки оправдан для очень сильно распределённых приложений

да нет, и локально они себя отлично чувствуют ))))

Добавлено @ 20:08
Цитата(Rusico @  18.7.2007,  19:57 Найти цитируемый пост)
У меня в БД есть 10000 записей (в таблице), они отображаются в Entity Beans, так вот поиск через findAll() работает настолько 
медленно (0,5-2 мин),

никогда не надо тянуть всю таблицу. любой фреймворк обломается. приложение очень сильно немасштабируемое получается. представь, если все клиенты кинутся смотреть? ))))
показывать следует пользователю страницами по N записей.
Цитата(Rusico @  18.7.2007,  19:57 Найти цитируемый пост)
что видимо придётся глядеть в сторону простого RMI.
 (Просто через RMI та же работа выполняется за 8 с., а прямая выборка из БД за1-2 с.) 

да, entity-бины не демонстрируют рекорды скорости, не для этого они. 

Цитата

так вот поиск через findAll() работает настолько медленно (0,5-2 мин),

к слову, если совсем уж все тормозит, то надо посмотреть в сторону оптимизации. может, неправильно установлены размеры пула и кеша, так что при загрузке большого количества бинов из базы просто своп сплошной получается (((

Автор: Rusico 18.7.2007, 20:08
мне бы хотелось всё-таки оперировать не чем угодно, а объектами - а это накладненько :(

Автор: ekr 18.7.2007, 20:11
Цитата(Rusico @  18.7.2007,  20:08 Найти цитируемый пост)
мне бы хотелось всё-таки оперировать не чем угодно, а объектами - а это накладненько :( 

да, накладно.
лучше логику работы со связанными (cmr) сущностями переместить в локальный для них session-бин (шаблон session facade).

Автор: Rusico 18.7.2007, 20:18
Покалупаюсь исчо, попробую как-нибуть оптимизировать работу smile

Спасибо за дискуссию.

Автор: ekr 18.7.2007, 20:20
Цитата(Rusico @  18.7.2007,  20:18 Найти цитируемый пост)
Покалупаюсь исчо

оптимизируйте, они золотые (С)золотой теленок
)))

Автор: AlexeyVorotnikov 19.7.2007, 08:40
Цитата(ekr @  18.7.2007,  21:01 Найти цитируемый пост)
да, entity-бины не демонстрируют рекорды скорости, не для этого они.

А для чего они?

Автор: ekr 19.7.2007, 11:22
Цитата(AlexeyVorotnikov @  19.7.2007,  08:40 Найти цитируемый пост)
А для чего они? 

Основная задача любого orm-решения - абстрагировать бизнес-логику от деталей underlying storage. 
И использование orm - не всегда самый производительный путь. Если нужна скорость - следует юзать низкоуровневый jdbc + хранимые процедуры )))
Альтернативные orm-решения в некоторых случаях так же не блещут скоростью (посмотрите на поддержку Hibernate-ом вызова хранимых процедур и batch-update-ов).

Для объективности следует отметить, что в случае entity-бинов можно правильным их использованием производительность очень сильно повысить:
  • для bmp можно прикрутить prepared- и callable-стейтменты
  • в случае cmp контейнер сам максимально оптимизирует underlying jdbc-вызовы 
  • следует использовать session facade с тем, чтобы изменение нескольких свойств нескольких entity-бинов проходило в рамках одной транзакции, что сильно сэкономитколичество синхронизаций с базой
  • для cmp контейнер оптимизирует jdbc-вызовы в случае relations
  • для любых типов entity очень важно правильно настроить размеры пула и кеша
и это далеко не полный список )))

Автор: AlexeyVorotnikov 19.7.2007, 11:41
 smile Я извиняюсь, с EJB я не очень знаком... Entity-bean'ы обязательно должны быть persistent? И если да, то обязательно ли в БД?

Автор: chief39 19.7.2007, 11:51
Цитата(Rusico @  18.7.2007,  10:26 Найти цитируемый пост)
Я пошёл другим путём - использую удалённые интерфейсы - всё работает, но на поиск компонента (получение домашнего интерфейса) 
уходит много времени. Компонентов может быть очень много, и каждый раз осуществлять поиск накладно. 

http://ru.sun.com/pdf/patterns/pattern9.pdf

Проблема не в еджиби, проблема в том, что данные хранятся в разных машинах(разные физически, разные СУБД, разные JVM - неважно), данные скрепляются из разных сущностей на верхнем уровне. Работа по совмещению двух сущностей - это типичная задача СУБД, которая для этого заточена. Если сделать два локальных CMR бина - они оттранслируют выборки в один СКЛ-запрос - всё быстро.
Если разнести их - тут уж ничего не поделать. Лепить в кучу их будет не СУБД, а логика верхнего уровня после перекачки по сети(в любом случае). Тут уж точно медленно.

Если задача стоит так, что бины должны быть по разным серверам - тогда стоит минимизировать обмен. Если нет - свести вместе.
Если один из бинов - а-ля словарь данных, тогда стоит паковать данные покрупнее, отдавать пользовательскому бину(бинам) и кешировать их там. Ессно, речь о value objects.


Автор: ekr 19.7.2007, 12:01
Цитата(AlexeyVorotnikov @  19.7.2007,  11:41 Найти цитируемый пост)
Entity-bean'ы обязательно должны быть persistent?

да

Цитата(AlexeyVorotnikov @  19.7.2007,  11:41 Найти цитируемый пост)
И если да, то обязательно ли в БД?

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

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)