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
Ответы
Ответ 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 (слишком простой), но мне это нужно для моих запросов; поэтому я просто собираю их вместе.
Что-то не так с этим подходом?