jcr node detach: использование свойств JcrNode за пределами сеанса (например, какой-то DTO)

В настоящее время делаю тестовое приложение с JCR (Modeshape).

  • Абстрагированный поток выглядит следующим образом: session.open, репозиторий извлекает данные из одного или нескольких узлов, связанных с запросом, session.close.

  • Результирующие узлы содержат свойства и т. д., которые мне нужно представить в представлении. В настоящее время у меня есть наивная установка, позволяющая представлению напрямую брать свойства из jcrNode. Однако это дает ошибку, например: «Сеанс с идентификатором« e2881d98-56fd-4a57-9cce-1a7d087a11e8 »был закрыт», что имеет смысл.

Я считаю, что общий подход (пожалуйста, исправьте, если это не так) будет заключаться в создании своего рода nodeDTO, который заполняется jcrNode, когда сеанс все еще активен. После этого представление может свободно использовать nodeDTO по своему усмотрению.

Теперь идеальная структура для такого nodeDTO будет имитировать структуру jcrNode 1-to-1, так почему бы не использовать jcrNode как сам DTO? Это можно было бы выполнить с помощью чего-то вроде спящего режима отсоединения/присоединения. Я понимаю, что jcrNode (с его дочерними элементами) может содержать много данных, поэтому, вероятно, должны быть некоторые параметры для определения глубины отсоединения и т. д.

Другой подход состоял бы в том, чтобы иметь что-то вроде шаблона openSessionInView, хотя это было бы специфично для mvc-framework.

Итак, я вижу несколько подходов к этому, сначала лучший подход (imo):

  1. функциональность отсоединения/присоединения для jcrNodes
  2. хорошая библиотека вспомогательных классов для создания DTO
  3. опенсессионинвиев

Любые комментарии к подходу «наилучшей практики» и т. д. приветствуются.


person Geert-Jan    schedule 21.07.2011    source источник


Ответы (2)


К сожалению, спецификация JCR 2.0 не определяет способ отключения узлов от сеанса, поэтому такая функциональность зависит от реализации.

Вместо метода JCR единственным методом, который не зависит от реализации JCR, будет копирование свойств и дочерних ссылок в очень простую структуру, созданную вами. Да, эта структура на высоком уровне будет очень похожа на узел JCR, но ей не нужно будет иметь 90% методов, определенных в узле: простая карта свойств (по имени) и список (или упорядоченная карта) дочерних узлов. При этом ваш код будет отвечать за копирование интересующих вас узлов и подграфов, поэтому вы сможете определить семантику в соответствии со своими потребностями.

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

person Randall Hauch    schedule 21.07.2011
comment
Спасибо за понимание, Рэндалл. Я буду использовать dto-подход, основанный на моей собственной реализации. Я обязательно посмотрю зарегистрированную проблему. - person Geert-Jan; 21.07.2011

Я разрабатываю веб-приложение JBoss Seam поверх Modeshape-in-JBoss. Сначала я тоже использовал подход DTO, но отказался от него. Вместо этого было проще держать сеанс JCR открытым либо для диалога Seam, либо для всего сеанса сервлета.

Если вы не используете Seam, вы можете использовать аналогичный подход для области запроса сервлета вместо диалога.

Я все еще нахожусь на начальной стадии разработки, а не в производстве, и поэтому не могу утверждать, что это «лучшая практика». Однако до сих пор оба подхода кажутся жизнеспособными, и у меня не было с ними проблем.

Для начала у меня есть компонент диспетчера швов в области приложения (с использованием @Unwrap), который создает репозиторий JCR (с использованием ServiceLoader), который используется для входа в систему().

Затем для сеанса:

  1. Сеанс JCR с областью беседы: я создал компонент диспетчера швов с областью преобразования, который помещает сессию JCR в область беседы. Компонент Seam выполняет функцию relay.login() при создании и session.logout() при уничтожении компонента в конце диалога. По сути, это тот же подход, что и JPA EntityManager в области диалога, который обычно используется в приложении Seam.

  2. Сеанс JCR в области сеанса: То же, что и выше, за исключением области сеанса Seam (Servlet). Это, очевидно, приводит к тому, что сеанс JCR остается открытым в течение гораздо более длительного времени (возможно, часов). Не знаю, есть ли при этом какие-то подводные камни, но пока это кажется более естественным подходом.

В обоих случаях код приложения будет выполнять session.save() после внесения любых обновлений.

Тем не менее, я согласен с тем, что какой-то API утилиты DTO без сеанса был бы очень полезен. Это становится очевидным, если вы предоставляете функциональность JCR клиенту с помощью EJB. Поскольку EJB может передавать только сериализуемые объекты данных, узлы, свойства и значения JCR нельзя передавать напрямую. Я столкнулся с этой ситуацией при разработке RCP-приложения Eclipse (дополнение к веб-приложению), которому требуется доступ к тому же репозиторию Modeshape, работающему в JBoss. В итоге я сделал что-то очень похожее на то, что рекомендовал Рэндалл: разработал простые сериализуемые объекты NodeDTO и PropertyDTO, а затем использовал несколько служебных методов для их создания из узлов и свойств JCR. Если бы Modeshape или JCR могли предоставить эти утилиты для помощи в клиент-серверном доступе к репозиторию, это было бы здорово!

person Montane    schedule 22.07.2011
comment
Спасибо, звучит интересно. Ваш подход - это то, что я имею в виду под «openSessionInView в моем исходном сообщении», то есть: сеанс JCR с областью действия. Я чувствую себя немного (излишне?) неудобным с этим подходом. Как бы вы обрабатывали JCR-узлы между формами-постами, перенаправление после поста, ajax-запросы и т. д. Конечно, вы можете спланировать это, но это быстро становится довольно сложным (некоторые даже доходят до вызова анти-шаблона, хотя я не считаю себя принадлежащим к этому лагерю :). - person Geert-Jan; 23.07.2011
comment
На данный момент я решил использовать простые NodeDTO и PopertyDTO, которые я сериализую/десериализую в временный кеш, когда он мне нужен между запросами. Я согласен с вами, что иметь проверенную в бою библиотеку было бы здорово! - person Geert-Jan; 23.07.2011
comment
Какова будет желаемая семантика отсоединения дочерних узлов. Будет ли отсоединенный узел содержать только свойства и дочерние указатели (например, путь + идентификаторы), или вы ожидаете, что отсоединение узла автоматически отсоединит его дочерние элементы? И если да, то указана ли глубина отрыва? - person Randall Hauch; 16.08.2011