Вопрос

Есть ли какой-нибудь действительно практичный способ избежать использования DTO при передаче данных через методы транзакционной службы, поддерживаемые Hibernate?Другими словами, являются ли DTO единственным нехакерским решением, позволяющим избежать проблем с ленивой инициализацией?

Я думаю, что есть две популярные альтернативы DTO и причины, по которым они мне не очень нравятся:

  1. Открыть сеанс в шаблоне просмотра.Это мне не нравится, поскольку я хотел бы, чтобы методы обслуживания были действительно транзакционными (т.сеанс Hibernate фиксируется и закрывается при выходе из метода).Это главным образом потому, что мне бы не хотелось беспокоиться о транзакциях, если мне, например, понадобится позже опубликовать службу как веб-службу.

  2. Передача объектов домена/бизнеса через методы службы вместо DTO и быстрое получение необходимых атрибутов/свойств.Это несколько лучше.Однако в нетривиальной иерархии объектов предметной области со сложными отношениями сущностей нетерпеливая выборка должна где-то остановиться.И когда это произойдет, я не понимаю, как это не превратится очень быстро в полноценный хакатон, повсюду заменяющий сущности ссылающимися идентификаторами.

Я что-то упускаю или DTO на самом деле единственный надежный подход с точки зрения ремонтопригодности?

Это было полезно?

Решение

Единственный способ по-настоящему использовать сквозные сущности — это использовать что-то более сложное, чем OpenSessionInView.По моему опыту, вам придется управлять сеансом гибернации вручную на уровне приложения.OpenSessionInView предоставит вам один и тот же сеанс только для одного запроса.После этого вам нужно будет постоянно повторно подключаться к текущему сеансу.Взгляните на Seam и диалоги или реализуйте собственное управление сеансами Hibernate.В настоящее время мы вручную управляем нашими сеансами в зависимости от того, когда запускается и завершается мастер, и используем Spring AOP для своевременного подключения сеансов к нужным потокам (сеансы не являются потокобезопасными и не очень хорошо сочетаются с AJAX).

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

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

Другие советы

Репозитории, службы и контроллеры должны быть местами, связанными с ядром вашего приложения (сеанс Hibernate, безусловно, можно использовать как весь уровень вашего репозитория, если хотите).

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

Чтобы облегчить вашу жизнь, могут существовать библиотеки или платформы, которые могут автоматически сопоставлять объекты модели предметной области с объектами модели представления и обратно.В .NET существует платформа с открытым исходным кодом AutoMapper, которая в настоящее время находится в разработке;Я не уверен, что есть для Java.

Если вы ослабите требование о закрытии сеанса, вы все равно сможете использовать открытый сеанс и просто зафиксировать все в своих сервисных транзакциях.Сеанс по-прежнему будет доступен для отложенной выборки, но все ваши транзакции будут завершены.Но если вы собираетесь переключиться на веб-сервис, вам все равно придется загружать все ваши объекты.DTO просто заставляют вас сознательно загружаться и предотвращают случайную ленивость.

Итак, суть в том, что если вы будете осторожны, вы можете пропустить DTO в обеих средах, но я бы, вероятно, придерживался открытого сеанса и беспокоился о веб-сервисах, когда они действительно станут требованием.

Мне нравится идея DTO, но я всегда чувствовал, что они не очень хорошо принимаются или нравятся другим разработчикам, поскольку правильная реализация этого подхода вплоть до базы данных обычно требует больших усилий.Вот почему я создал Представления сущностей Blaze-Persistence которые позволяют моделировать DTO как интерфейсы, которые эффективно сопоставляются с моделью объектов JPA.Вы можете применить представление сущности к запросу, и запрос будет адаптирован таким образом, что он будет получать только действительно необходимое состояние, а не все состояния и отображать их в Java.

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

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

Вам наверняка понравится Сообщение блога по этому поводу я писал некоторое время назад.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top