Я обнаружил, что JPA, или, похоже, не поощряет шаблон DAO

Я нашел JPA или, похоже, не поощрял шаблон DAO. Я не знаю, но я чувствую себя так, особенно с управляемыми серверами менеджерами JTA.

После адекватного практического использования шаблона DAO я начал создавать приложение на основе JPA вокруг этого шаблона. Но это не подходит, ИМО. Я, как правило, теряю некоторые особенности JPA и всех.

Хорошо, предположим, что вы запускаете запрос с пессимистической блокировкой, и он возвращает список entites из метода DAO. По возвращении завершаются транзакции и блокировка (случай с управляемым сервером JTA-менеджером). Итак, нет смысла, свободно говорить. Однако существуют действительные случаи.

Другой пример намного более тривиален. Предположим, что вы запускаете запрос для получения какой-либо сущности, которая имеет ленивую загрузку взаимно-однозначной связи с каким-либо другим объектом. После возврата метода DAO транзакция завершается. Lazy loading больше не будет работать, вы просто получите null или что-то еще. Чтобы справиться с этим, мы загружаем его с готовностью вручную. мы делаем что-то вроде a.getBList().size().

Таким образом, IMO лучше не делать DAO исключительно и делать это в своем бизнесе bean, таким образом вы сможете воспользоваться этими полезными функциями. Или ORM API можно считать DAO/Data-layer, возможно. Поэтому нам не нужно делать другой.

Что вы думаете об этом?

Примечание. Я не утверждаю, что шаблон DAO устарел. Действительно, это зависит от случая.

Ответы

Ответ 1

Для простых приложений я не вижу проблем с использованием EntityManager непосредственно из EJB и пропускаю шаблон DAO (я устал писать слишком много кода). И я чувствую, что именно это поддерживает JPA и Java EE API. Но это может быть оправдано для более сложных приложений (для доступа к данным из хранимой процедуры, плоских файлов...). Итак, вы правы, это зависит:)

Вы найдете еще одну просвещенную точку зрения в Убили JPA DAO? в InfoQ, но вы не будете удивлены контента и вывода, которые можно обобщить как: вам больше не нужен шаблон DAO для стандартного доступа к данным, однако вам может понадобиться его для более сложных ситуаций, но мы живем лучше без него.

Ответ 2

Если вы не определяете сам DAO как транзакционный, у вас не будет этих проблем.

Предполагается, что сервисный уровень является транзакционным, поскольку транзакция должна охватывать несколько операций. Помещение каждой вставки/обновления в транзакцию не является лучшим сценарием.

С spring вы достигаете этого очень легко. Без него вы, возможно, снова включите логику транзакций в свой DAO - т.е. dao.beginTransaction() и dao.commitTransaction() и вместо этого используйте это из уровня сервиса.

Как я понимаю, вы полагаете, что использование EntityManager непосредственно в классах службы, вероятно, лучше, чем наличие класса оболочки DAO. Я не согласен по одной причине. Работая с классом DAO (в лучшем случае, с интерфейсом) в ваших классах обслуживания, у вас совсем нет зависимости от API JPA. Вам не нужно создавать объекты Query или подобные. Это может оказаться большим преимуществом, но вы согласитесь, что это лучшая практика. И вы можете позже переключиться на простой JDBC, обычный текст, XML или что угодно, только изменив DAO.

Это, хотя широко используется в качестве примера того, почему вы должны абстрагировать что-то в другом слое, чаще всего просто переоценивается. Но иногда тот факт, что все операции доступа к базе данных проходят через одно место, означает, что вы можете добавлять протоколирование, проверки уровня доступа и т.д. (Да, иногда DAO не является особенно подходящим способом для этого).

Итак, в конечном счете, чтобы вернуться к вашей точке - это зависит.

Ответ 3

DAO используется для проектной перспективы, а JPA - это "официальная" оболочка для функций доступа к данным. Там нет способа, которым JPA пытается убить DAO - это может сделать DAO проще в реализации, возможно, настолько просто, что DAO выглядит настолько просто, что его можно игнорировать. Но без слоя DAO преимущества дизайна больше не существуют.

Конечно, для "простых" проектов его можно игнорировать. Многие вещи могут быть "проигнорированы", если проект "прост" достаточно.