1

目前正在使用 JCR (Modeshape) 做一个测试应用程序。

  • 抽象流程如下:session.open,存储库获取与查询相关的一个或多个节点,session.close。

  • 结果节点包含我需要呈现给视图的属性等。我目前有让视图直接从 jcrNode 获取属性的天真设置。但是,这会产生一个错误,例如:“ID 为 'e2881d98-56fd-4a57-9cce-1a7d087a11e8' 的会话已关闭”,这是有道理的。

我相信一般方法(否则请更正)是创建某种 nodeDTO,当会话仍然处于活动状态时,它由 jcrNode 填充。然后视图可以随意使用 nodeDTO。

现在,这种 nodeDTO 的完美结构将模仿 jcrNode 1 对 1 的结构,那么为什么不将 jcrNode 用作 DTO 本身呢?这将通过类似于休眠分离/附加的东西来完成。我意识到 jcrNode(及其子节点)可以包含大量数据,因此应该有一些参数来确定分离的深度等。

另一种方法是使用类似于 openSessionInView 模式的东西,尽管这将是特定于 mvc 框架的。

所以我可以看到几种方法,最好的方法优先(imo):

  1. jcrNodes 的分离/附加功能
  2. 用于创建 DTO 的良好帮助类库
  3. openSessionInView

非常感谢对“最佳实践”方法等的任何评论。

4

2 回答 2

2

不幸的是,JCR 2.0 规范没有定义从会话中分离节点的方法,因此这种功能将是特定于实现的。

代替 JCR 方法,与 JCR 实现无关的唯一技术是在您自己创建的非常简单的结构中复制属性和子引用。是的,该结构在高层次上与 JCR 节点非常相似,但它不需要在 Node 上定义 90% 的方法:一个简单的属性映射(按名称)和一个列表(或子节点的有序映射)。通过这样做,您的代码将负责复制您感兴趣的节点和子图,因此您可以定义语义以满足您的需求。

但是,作为 ModeShape 的项目负责人,我同意分离 JCR 节点确实是一个不错的功能,因此我将其作为增强请求记录在 ModeShape 项目中。在正确的语义方面有很多细节需要解决(尤其是与子节点或后代节点有关),所以我邀请您观看该请求并参与有关该问题的讨论。

于 2011-07-21T17:13:58.180 回答
0

我一直在 Modeshape-in​​-JBoss 之上开发一个 JBoss Seam Web 应用程序。起初我也使用了 DTO 方法,但放弃了。相反,保持 JCR 会话打开更容易,无论是对于 Seam 会话还是整个 Servlet 会话。

如果您不使用 Seam,那么您可以对 Servlet 请求范围使用类似的方法而不是对话。

我仍处于初始开发阶段 - 不是生产 - 因此不能声称这是“最佳实践”。然而到目前为止,这两种方法似乎都是可行的,我对它们没有任何问题。

首先,我有一个应用程序范围的 Seam 管理器组件(使用 @Unwrap),它创建用于 login() 的 JCR 存储库(使用 ServiceLoader)。

然后对于会话:

  1. 会话范围的 JCR 会话:我创建了一个转换范围的 Seam 管理器组件,它将 JCR 会话置于会话范围内。Seam 组件在创建时执行 repository.login(),在会话结束时组件被销毁时执行 session.logout()。这与通常在 Seam 应用程序中使用的对话范围的 JPA EntityManager 本质上是相同的方法。

  2. 会话范围的 JCR 会话:与上述相同,除了 Seam (Servlet) 会话范围。这显然会导致 JCR 会话打开更长的时间(可能是几个小时)。我不知道这是否有任何陷阱,但到目前为止,这似乎是更自然的方法。

在这两种情况下,应用程序代码都会在进行任何更新后执行 session.save()。

但是,我同意某种无会话 DTO 实用程序 API 会非常有用。如果您将 JCR 功能公开给使用 EJB 的客户端,这将变得很明显。由于 EJB 只能传递可序列化的数据对象,因此无法直接传递 JCR 节点和属性和值。我在开发需要访问在 JBoss 中运行的同一个 Modeshape 存储库的 Eclipse RCP 应用程序(Web 应用程序的伴侣)时遇到了这种情况。我最终做了与 Randall 推荐的非常相似的事情:开发简单的可序列化 NodeDTO 和 PropertyDTO 对象,然后使用一些实用方法从 JCR 节点和属性创建它们。如果 Modeshape 或 JCR 可以提供这些实用程序来帮助客户端-服务器访问存储库,那就太好了!

于 2011-07-22T18:01:13.803 回答