Проектное решение для приложения Java EE 6 (EJB, JSF, CDI, JPA) - PullRequest
1 голос
/ 13 декабря 2011

Я занимаюсь разработкой небольшого (но растущего) проекта Java EE на основе технологий EJB 3.1, JSF 2, CDI (WELD) и JPA 2, развернутых на JBOSS AS 7.1Beta1.

В качестве отправной точкиЯ создал проект Maven на основе архетипов Knappsack Maven.

Моя архитектура в основном такая же, как и у архетипа, и по мере роста моего проекта я думаю, что этот архетип, похоже, выходит за пределы.Я хочу изменить основную идею архетипа в соответствии с моими потребностями.Но позвольте мне сначала объяснить, как проект организован в данный момент.

Весь проект построен вокруг Seam, как домашние классы.Представление ссылается на них (через EL в шаблонах xhtml).Большинство классов Home являются @Named и @RequestScoped (или коротко @Model) или @ConversationScoped, а Java-бины Entripse имеют значение @Inject ed.В основном эти (обычно @Local) EJB-компоненты отвечают за доступ к базе данных (некоторые виды DAO), чтобы получать транзакции, автоматически управляемые контейнером.Таким образом, каждый класс DAO имеет свой собственный EntityManager , внедренный через CDI.На данный момент каждый DAO объединяет аспекты, которые логически принадлежат друг другу (например, в архетипе есть SchoolDao, который отвечает за создание Teacher s, Student s и Course s).

Это, конечно, приводит к растущим DAO, которые не имеют четко определенной задачи и которые трудно поддерживать и трудно понять.И, как болезненный побочный эффект, возрастает риск дублирования кода.

Как следствие, я хочу разбить этот дизайн, имея только DAO, которые отвечают за одну конкретную задачу (@StudentDao, @TeacherDao искоро).И в этот момент у меня проблемы.Поскольку каждый DAO имеет ссылку на свой собственный EntityManager, нельзя гарантировать, что что-то вроде следующего будет работать (я думаю, что это никогда не будет работать):

Teacher teacher = teacherDao.find(teacherId);
course.setTeacher(teacher);
courseDao.save(course);

Реализация JPA жалуется на значение nullдля столбца COURSE.TEACHER_ID (при условии, что Course имеет ненулевое значение FK до Teacher).Каждый DAO имеет свой собственный EntityManager, teacher управляется одним из TeacherDao, но другой из CourseDao пытается объединить Course @Entity.

Может быть, я использовал архетие не подходит для больших приложений.Но какой подход был бы подходящим для такого применения, тогда ЕСЛИ бы использовались технологии, которые я использовал (EJB 3.1 для транзакций, управляемых контейнером [и позже для других связанных с бизнесом вещей], JSF как технология просмотра, JPA как преобразователь базы данных и CDI как'должен иметь, потому что это hip:)?

Редактировать:

Теперь у меня есть EntityManager, внедренный в базовый класс, от которого наследуются все другие классы DAO.Таким образом, все DAO используют один и тот же экземпляр (отладчик показывает один и тот же идентификатор объекта), но у меня все еще есть проблема, заключающаяся в том, что все объекты, которые я читаю из базы данных, немедленно отсоединяются.Это то, что заставляет меня задуматься, поскольку это означает, что либо нет управляемой контейнером транзакции, либо транзакция немедленно закрывается после того, как объект был прочитан.Каждый DAO является @Local @Stateless EJB.Они вводятся в мои компоненты JSF (@Named и @RequestScoped), откуда я хочу использовать операции CRUD.Я что-то пропустил?

1 Ответ

1 голос
/ 13 декабря 2011

Наличие каждого DOA имеет свой собственный EntityManager - очень плохой дизайн.

Вы должны иметь EntityManager для каждой транзакции / запроса и передавать его в каждый DOA, или они должны совместно использовать один и тот же или получать его из контекста.

...