2010-04-22 4 views
2

Я использую стек JEE6 включая JPA 2.0, JSF 2.0, EJB 3.1 и т.д.Я правильно использую EJB?

мой путь архитектура установки заключается в следующем:

У меня есть JPA аннотированный объекты DAO, используя спящий режим, как мой провайдер JPA. У меня есть управляемые бобы JSF, которые соответствуют моим страницам facelet/xhtml. У меня есть EJB, которые обрабатывают все мои запросы к базе данных.

На моих страницах XHTML есть JSF EL, которые звонят на мои управляемые бобы. Мои управляемые бобы содержат ссылки на мои объекты DAO, которыми управляют EJB. Например, у меня есть пользовательский объект, который сопоставляется с таблицей db. У меня есть пользователь EJB, который обрабатывает все операции CRUD, которые возвращают пользователей. У меня есть страница, которая редактирует пользователя. Рабочий процесс на высоком уровне: переход на страницу редактирования пользователя -> EL вызывает метод, расположенный в управляемом компоненте, который загружает пользователя. Метод вызывает userEJB.loadUser (пользователь) из EJB, чтобы получить пользователя из базы данных. Пользователь редактируется и отправляет -> функция вызывается в управляемом компоненте, который вызывает функцию в EJB для сохранения пользователя. и т. д.

У меня проблемы с доступом к моим данным на моих страницах JSF с помощью EJB. У меня много проблем с ленивыми ошибками инициализации, которые, как я полагаю, связаны с тем, как я все наладил.

Например, у меня есть объект-клиент, который имеет список пользователей, которые лениво загружаются. Чтобы получить клиент, я вызываю метод в своем EJB, который идет в базу данных, находит клиента и возвращает его. Позже в я хочу получить доступ к этому списку пользователей, для этого мне нужно вернуться в EJB, вызвав какой-то метод для загрузки этих пользователей (поскольку они лениво загружаются). Это означает, что я должен создать такой метод, как

public List<User> getUserListByClient(Client c) 
{ 
    c = em.merge(c); return c.getUserList(); 
} 

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

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

Любая обратная связь будет принята с благодарностью.

спасибо,

ответ

1

Ваше использование кажется хорошо. Просто помните, что em.merge (c) может сохранять изменения, внесенные клиенту c в базу данных. Если вы просто хотите, чтобы получить UserList от клиента с без сохранения изменений, внесенных в Client с, то вы можете сделать это:

public List<User> getUserListByClient(Client c) 
{ 

    Client client = em.find(Client.class, c.clientId); 
    return client.getUserList(); 

} 

Или лучше просто отправить идентификатор клиента в getUserListByClient вместо прохождения полного Клиентский объект, просто чтобы сохранить битву winsy бит памяти :)

2

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

в самом деле, это open session in view шаблон (также называемый открытый EntityManager в виду). Он также может использоваться с EJB. В идеальном случае транзакции должны управляться в бизнес-слое/EJB, чтобы можно было увидеть небольшое отклонение от архитектуры чистого уровня. Но он решает проблему ленивой загрузки в представлении и прост.

В противном случае вы должны обязательно загрузить информацию, которая будет использоваться после завершения транзакции. Или вы можете полагаться на DTO, но тогда это начинает громоздко.

Вот еще две ссылки, которые покрывают тему и обсудить плюсы/минусы и альтернативы: