Нужна помощь в разработке структуры и поиске EntityManager и UserTransaction в помощнике помощника - PullRequest
1 голос
/ 28 апреля 2009

Я в основном новичок, чья работа над новым веб-приложением началась. Веб-приложение в основном ваши основные операции CRUD. Для этого я решил использовать JPA с Hibernate в качестве поставщика сохраняемости и буду разрабатывать на Apache Derby для целей разработки и тестирования. Я использую GlassFish v2 в качестве сервера приложений для развертывания EJB3-компонентов. Для внешнего интерфейса я использую JSF (Visual JSF с темой woodstock, поставляемой в комплекте с NeatBeans v6.5)

Так вот как я продолжал до сих пор. В основном я использовал мастера NetBeans 6.5 для генерации классов сущностей и сессионных компонентов ejb. Я создаю новую таблицу в Apache Derby, скажем, XXX. Затем я использую «Классы сущностей из базы данных», чтобы сгенерировать класс сущностей XXX, который содержит все необходимые аннотации и методы получения и установки.

Затем я запускаю мастер «Классы контроллера JPA из классов сущностей», чтобы сгенерировать код класса контроллера, XXXJpaController, который в основном содержит следующее:

@Resource private UserTransaction utx = null;
@PersistenceUnit(unitName = "TestEnterpriseApplication-ejbPU") private EntityManagerFactory emf = null;
1. EntityManager getEntityManager() { return emf.createEntityManager() }
2. void create(XXX xxx) throws PreexistingEntityException, RollbackFailureException, Exception{}
3. void edit(XXX xxx) throws NonexistentEntityException, RollbackFailureException, Exception{}
4. void destroy(Long id) throws NonexistentEntityException, RollbackFailureException, Exception {}
5. List<XXX> findXXXEntities(){}
6. List<XXX> findXXXEntities(int maxResults, int firstResult)  {}
7. List<XXX> findXXXEntities(boolean all, int maxResults, int firstResult){}
8. XXX findXXX(Long id){}
9. int getXXXCount(){}

Затем я запускаю мастер «Сессионные компоненты для классов сущностей», чтобы сгенерировать локальные / удаленные компоненты сеанса EntityFacade, которые при необходимости могут вызываться внешним интерфейсом следующим образом:

@PersistenceContext private EntityManager em;
1. void create(XXX xxx) { em.persist(xxx); }
2. void edit(XXX xxx) { em.merge(xxx); }
3. void remove(XXX xxx) { em.remove(em.merge(xxx)); }
4. List<XXX> findAll() { return em.createQuery("select object(o) from XXX as o").getResultList();  }

Поскольку у меня уже есть генерируемые классы Controller, которые реализуют эти методы с лучшей поддержкой для try и catch и транзакций, я решил назвать это в XXXFacade.java, как показано ниже:

XXXJpaController XXXController = new XXXJpaController();
1. public void create(XXX xxx) throws PreexistingEntityException, RollbackFailureException, Exception {
        XXXController.create(xxx); }
2. public void edit(XXX xxx) throws NonexistentEntityException, RollbackFailureException, Exception{
        XXXController.edit(xxx); }
3. public void remove(XXX xxx) throws NonexistentEntityException, RollbackFailureException, Exception{
        XXXController.destroy(xxx.getId()); }
4. public XXX find(Object id) {
        return XXXController.findXXX((Long)id); }
5. public List<XXX> findAll() {
        return XXXController.findXXXEntities(); }

Итак, вот мой первый вопрос. Это правильный способ делать вещи в мире JEE или есть лучший способ сделать это? Я ввожу здесь какую-то избыточность? Это шаблон, которому я в значительной степени следовал для всех классов Entity: Создать класс сущности -> Создать класс контроллера -> Создать класс entityfacade -> Изменить класс entityfacade для вызова методов класса контроллера

ps: я использую JTA

Это, в свою очередь, привело меня к другой проблеме. Все сгенерированные классы контроллеров имеют свои собственные методы getEntityManager (). Поэтому, чтобы избавиться от этой избыточности, я решил пойти с вспомогательным классом по аналогии с HibernateUtil.java, который обычно встречается в руководствах по Hibernate (который действует как синглтон для фабрики сеансов). Поэтому я создал PersistenceUtil.java, в котором есть методы getEntityManager () и getUserTransaction (), которые должны возвращать экземпляры EntityManager и UserTransaction, используемые классами Controller.

Вот в чем проблема. Я использую @PersistenceContext ((name = "jpa / EntityManager") и @Resource (name = "jta / UserTransaction") для классов XXXFacade. Таким образом, я могу получить доступ к записям JNDI для em и utx из обоих классов XXXFacade ( если мне нужно, хотя в моем случае я этого не делаю) и в вспомогательном классе XXXJpaController (через поиск jndi). После чтения в Интернете это то, что я обнаружил. Вспомогательные классы должны использовать поиск JNDI в компонентной среде компонента ( java: comp / env), поскольку внедрение выполняется только для управляемых контейнером bean-компонентов, а не для неуправляемых вспомогательных классов. Это прекрасно работает для класса Controller, который создается в классе XXXFacade, как показано в коде выше. Однако я не могу использовать Класс PersistenceUtil для поиска либо EntityManager, либо UserTransaction, так как я предполагаю, что это вспомогательный класс помощника. Что я могу сделать, чтобы обойти это и получить доступ к управляемому контейнеру entitymanager и usertransaction в вспомогательном классе PersistenceUtil? Одна опция, которая приходит мне в голову, это создать экземпляр класса Persistence в каждом классе XXXFacade (мне это не нравится).

Единственный другой вариант, о котором я могу подумать, - это избавиться от класса Controller и переместить весь этот код в класс XXXFacade. Таким образом, мне больше не понадобится вспомогательный класс PersistenceUtil, поскольку я могу напрямую добавить его в сессионный компонент, верно?

Как я уже говорил в начале, я новичок. Я рассчитываю получить от всех вас опытных и опытных ветеранов java / jee руководство по этому вопросу. Есть ли какой-то конкретный шаблон, который я могу использовать здесь?

Извините, если что-то из этого не имеет для вас смысла. Пожалуйста, не стесняйтесь идти вперед и спрашивать меня о любых разъяснениях, и я буду более чем счастлив сделать это.

Ответы [ 2 ]

1 голос
/ 29 апреля 2009

Одна вещь, на которую вы, возможно, захотите обратить внимание, это Spring для управления вашими транзакциями, а не фабричный метод.

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

0 голосов
/ 21 августа 2009

Да .. Вы абсолютно правы. Я прошу прощения за формат вопроса. На самом деле это была моя самая первая публикация на stackoverflow и, следовательно, уродливость вопроса. В любом случае, благодаря вашим отзывам я постарался опубликовать лучшие вопросы.

В любом случае, я нашел ответы на свои вопросы. Я решил не использовать классы контроллера и просто использовать фасонные фасады сеансов для сущностей. И я использовал управляемую контейнером персистентность. Поэтому больше нет необходимости в методах getEntityManager () или вспомогательных классах. Вместо этого используйте DI формы "@PersistenceContext". Кроме того, поскольку я использую управляемое контейнером постоянство, мне больше не нужны пользовательские транзакции.

...