Объекты передачи данных и транзакционные методы обслуживания

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

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

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

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

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


person Community    schedule 15.04.2009    source источник


Ответы (4)


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

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

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

person David Ortiz    schedule 15.04.2009

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

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

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

person yfeldblum    schedule 15.04.2009
comment
Я считаю, что Dozer выполняет автоматическое сопоставление объектов домена Java с DTO и с ними, но я никогда не использовал его сам. - person Andrew Swan; 15.04.2009

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

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

person Brian Deterling    schedule 15.04.2009
comment
Оставить сеанс открытым кажется разумным. Сложность с веб-сервисами заключается в том, что если дерево сущностных объектов глубокое, некоторые ветви должны быть отрезаны (для последующего запроса) или заменены ссылающимися идентификаторами. Как только вы это сделаете, у вас в основном будет DTO, даже если он сформирован вне службы. - person ; 15.04.2009

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

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

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

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

person Christian Beikov    schedule 19.07.2018