Подтвердить что ты не робот

JavaEE6 DAO: Должен ли он быть @Stateless или @ApplicationScoped?

В настоящее время я создаю класс доступа к данным EJB3 для обработки всех операций с базой данных в своем Java EE 6-приложении. Теперь, поскольку Java EE 6 предоставляет новую ApplicationScoped-Annotation, мне интересно, какое состояние должен иметь мой EJB, или если он должен быть без гражданства.

Можно ли позволить DAO быть сеансом @Stateless Bean или @ApplicationScoped Bean? Как насчет @Синглтона? Каковы различия между этими вариантами, связанными с DAO?

EDIT: Я использую Glassfish 3.0.1 с полной платформой Java EE 6

4b9b3361

Ответ 1

Можно ли позволить DAO быть сеансом @Stateless Bean или @ApplicationScoped Bean? Как насчет @Синглтона? Каковы различия между этими вариантами, связанными с DAO?

Я бы не использовал сессию без состояния Beans для DAO:

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

  • Реализация DAO как SLSB будет стимулировать цепочку EJB, которая не является хорошей практикой с точки зрения масштабируемости.

  • Я бы не привязал слой DAO к API EJB.

@Singleton, введенный в EJB 3.1, может улучшить ситуацию, но я бы не реализовал DAO как EJB. Я бы предпочел использовать CDI (и, возможно, собственный стереотип, например, эта статья).

Или я вообще не использовал бы DAO. Администратор сущности JPA представляет собой реализацию шаблона Хранилище домена и обертывание доступа к хранилищу доменов в DAO не придает большого значения.

Ответ 2

После некоторого переосмысления, похоже, что DAO на самом деле не правильное имя для того, что я хотел сделать. Может быть, это действительно Фасад, как сказал Паскаль. Я просто нашел пример Netbeans Petstore - пример приложения JavaEE6, см. здесь - где у них есть ItemFacade, который отвечает за поиск/создание/удаление объектов из базы данных. Это сеанс без состояния Bean. Выглядит так:

@Stateless
public class ItemFacade implements Serializable {
    @PersistenceContext(unitName = "catalogPU")
    private EntityManager em;

    public void create(Item item) { ... }
    public void edit(Item item) { ... }
    public void remove(Item item) { ... }
    public Item find(Object id) { ... }
    public List<Item> findAll() { ... }
    public List<Item> findRange(int maxResults, int firstResult) { ... }
    public int getItemCount() { ... }
}

Итак, в качестве вывода я больше не называю свой DAO DAO, а вместо этого просто, например, PersonEJB (я думаю, что "PersonFacade" может быть неправильно понят) и сделать это также @Stateless, так как я думаю, что пример Netbeans можно также рассмотреть -разработана.

Ответ 3

@Pascal: По моему мнению, мой DAO не "ответственен" за транзакцию или безопасность, поскольку контейнер управляет этими услугами. Я просто комментирую методы в моем DAO (только для обеспечения безопасности, поскольку транзакции обрабатываются автоматически). Являются ли аннотации уже "ответственными"?

Хорошо, поэтому вы заставляете меня задуматься над моим дизайном. Надеюсь, что все в порядке и не слишком не по теме, но, возможно, это помогает - вот как я использую JEE6 сегодня:

  • JSF обращается к CDI Bean,
  • CDI Bean обращается к DAO-EJB, который делает "бизнес-логику"
  • так что в настоящее время моя единственная "бизнес-логика" делает CRUD, позже я добавлю некоторые другие EJB для таких важных задач, как асинхронные методы или службы таймера.
  • мой DAO является общим и использует запрос критериев JPA2 для создания типов запросов (без каких-либо строк)
  • Я знаю, что мне не нужен DAO для persist/update/remove (слишком простой), но мне это нужно для моих запросов; поэтому я просто собираю их вместе.

Что-то не так с этим подходом?