Вот что я считаю, это традиционный вид:
- Сущность в вашем проекте формирует модель предметной области. Они должны быть повторно использованы и не тесно связаны с технологией персистентности (я вернусь позже о жесткой и свободной связи)
- Бизнес-уровень использует модель домена, а также предоставляет услуги и другие продукты.
- Уровень доступа к данным отвечает за сохранение модели домена (объектов) в постоянном хранилище.
Объект не должен напрямую обращаться к уровню доступа к данным. Но бизнес-уровень будет таким образом, чтобы загружать и сохранять объекты модели домена.
Если карта, что технологии Java EE вы обычно что-то вроде:
- Entities -> POJO с Hibernate/JPA аннотации. Обратите внимание, что аннотации не подразумевают жесткой связи с JPA/Hibernate, тот же POJO может использоваться где-то еще без Hibernate.
- Бизнес слой -> Session EJB или Spring
- слой доступа к данным -> JPA/Hibernate
Это грубый набросок, и есть много возможных вариантов. Вы можете пропустить сессию EJB и реализовать бизнес-уровень другим способом. Вы также можете решить, чтобы бизнес-уровень вызывал сессию JPA/Hibernate Session/EntityManager напрямую, и в этом случае JPA/Hibernate действительно является DAL, или вы можете захотеть обернуть доступ к Session/EntityManager в так называемые объекты доступа к данным (DAO).
Что касается HQL, попробуйте придерживаться того, что переносимо, и если вы используете собственный SQL, следуйте соглашениям SQL-92. Если материал станет сложным, возможно, представите DAO. Таким образом, вы знаете, что единственное место, где есть запросы HQL, находится в DAO. Вы также можете сначала реализовать логику запроса «процедурно» в DAO, и если у вас есть проблемы с производительностью, повторите ее реализацию с помощью более сложного запроса HQL.
EDIT
Что касается ваших вопросов в комментарии:
Бизнес слоя зависит от уровня данных. Если вы хотите, чтобы бизнес-уровень не зависел от Hibernate/JPA, тогда ваш уровень данных должен соответствовать аннотация Hibernate/JPA. Если вы используете DAO для своего уровня данных, это будет так. DAO будет «тонким рукописным слоем персистентности над Hibernate» (чтобы взять ваши слова). Я бы представил DAO для всех сущностей в вашем случае.
Что вы задаете, это довольно общий вопрос дизайна. Я не могу дать окончательный рецепт для этого и не суммировать все варианты в одном ответе, поскольку это зависит от конкретного случая. Например, мы пока не говорили о проблеме транзакций, которую вы обычно начинаете с бизнес-уровня, но о том, что должен быть осведомлен об уровне данных. Это обычно зависит от используемых технологий и ваших требований.
Тем не менее, вот список ресурсов, которые могут быть заинтересованы в: книги Pattern of Enterprise Application Architecture, книга Real World Java EE Patterns - Rethinking Best Practices, книга Domain Driven Design и более конкретно модели Data Access Object, Repository pattern, Open Session in View (если это для веб-приложение), и возможно, Anemic Domain Model.
EDIT 2
Хорошо, еще несколько предложений о сделках:
Сделки должны концептуально управляться в бизнес-уровне; определение того, что должно быть сделано в одной единице работы, чтобы быть последовательной, действительно зависит от самой логики приложения.
С EJB3 транзакции могут быть объявлены аннотациями и приложением. сервер управляет этим для вас. Для получения дополнительной информации см. this other answer. С весной вы также можете отметить транзакции декларативно, но я не знаю деталей. В противном случае вам нужно будет начать/остановить транзакцию самостоятельно.Это будет немного отличаться от того, используете ли вы транзакции JDBC или транзакции JTA.
Сделки также относятся к ленивой загрузке в спящем/JPA. Объект, который был ленивым загружен, действительно может быть загружен только в случае текущей транзакции. Если транзакции завершаются на бизнес-уровне, объекты, которые возвращаются на уровень представления, должны быть загружены с высокой нагрузкой.
Чтобы обойти эту проблему, популярным образцом для веб-приложений является Open Session in View, о котором я уже упоминал. В этом случае слой презентации запускает/останавливает транзакции (что немного неверно концептуально), но отлично работает с ленивой загрузкой.
Я полностью согласен и в конечном итоге рекомендую использовать JPQL вместо HQL, чтобы придерживаться стандартов. – snowflake
Возможно, я ошибаюсь в терминологии. Когда я сказал «моделирование домена», я имел в виду M-триады MVC, которая, по сути, является «основным приложением» (включая бизнес-уровень), то, что вы могли бы потенциально управлять через интерфейс командной строки (переписывая V и C для CLI)! Теперь одна из вещей, которые этот М будет делать, - настойчивость. Для этого M должен быть свободен от любых вещей, связанных с конкретными поставщиками. Следовательно, потребность в тонком (или толстом/сложном?) Рукописном персистентном слое над Hibernate. Не могли бы вы исправить меня, если я ошибаюсь. – Harry
«Если материал станет сложным, возможно, представите DAO». Вы имеете в виду, в каждом случае (предполагая, конечно, что DAO и HQL/JPQL сосуществуют мирно). Я действительно хотел бы иметь возможность проектировать мои объекты таким образом, чтобы HQL хватался большей частью (из-за силы реляционной парадигмы), и для действительно сложных запросов я пишу императивный код. – Harry