开发者

jcr node detach: using JcrNode properties outside of session scope (like some kind of DTO)

Currently doing a test-app with JCR (Modeshape).

  • The abstracted flow is as follows: session.open, a repository fetches on or more nodes related to a query, session.close.

  • The resulting nodes contain properties, etc. that I need to present to the view. I currently have the naive setup of letting the view take properties from the jcrNode directly. However this开发者_如何学运维 gives an error like: "The session with an ID of 'e2881d98-56fd-4a57-9cce-1a7d087a11e8' has been closed", which makes sense.

I believe the general approach (please correct if otherwise) would be to create some sort of nodeDTO which is populated by the jcrNode when the session is still active. The view is then free to use the nodeDTO however it wants.

Now, the perfect structure for such a nodeDTO would mimic the structure of the jcrNode 1-to-1 so why not use the jcrNode as the DTO itself? This would be accomplished with something akin to hibernate detach/attach. I realize that a jcrNode (with its children) can contain lots of data, so there should likely be some parameters to determine the depth of detachment, etc.

Another approach would be to have something like the openSessionInView-pattern, although this would be mvc-framework specific.

So I can see several approaches to this, best approach first (imo):

  1. detach/attach functionality for jcrNodes
  2. good library of helper classes to create the DTOs
  3. openSessionInView

Any comments on to the 'best-practice' approach, etc. much appreciated.


Unfortunately, the JCR 2.0 specification does not define a way for the nodes to be detached from a session, so this kind of functionality would be implementation-specific.

In lieu of a JCR method, the only technique that is agnostic of a JCR implementation would be to copy the properties and child references in a very simple structure of your own creation. Yes, that structure would at a high-level be very similar to a JCR node, but it wouldn't need to have 90% of the methods defined on Node: a simple map of properties (by name), and a list (or ordered map) of child nodes. And by doing this, your code would be responsible for copying the nodes and subgraphs you're interested in, so you can define the semantics to suit your needs.

However, as the project lead for ModeShape, I do agree that detaching JCR nodes does seem like a good feature, and so I've logged it as an enhancement request in the ModeShape project. There are a lot of details to work out in terms of the proper semantics (especially relating to child or descendant nodes), so I'd invite you to watch that request and participate in the discussion on that issue.


I have been developing a JBoss Seam web application on top of Modeshape-in-JBoss. At first I too used a DTO approach, but abandoned that. Instead, it was easier to keep the JCR session open, either for the Seam conversation or the entire Servlet Session.

If you are not using Seam, then you could use a similar approach for the Servlet Request scope instead of conversation.

I am still in the initial development phase - not production - and therefore cannot claim that this is a "best practice". However so far, both seem to be viable approaches and I have had no problems with them.

To start out, I have an Application scoped Seam manager component (using @Unwrap) that creates the JCR Repository (using ServiceLoader) that is used for login().

Then for the Session:

  1. Conversation scoped JCR session: I have created a conversion scoped Seam manager component that places a JCR Session in conversation scope. The Seam component performs repository.login() upon creation and session.logout() when the component is destroyed at the end of the conversation. This is essentially the same apporoach as a conversation scoped JPA EntityManager that is normally used in a Seam app.

  2. Session scoped JCR session: The same as above, except in Seam (Servlet) session scope. This obviously results in the JCR session being open for a much longer time (potentially hours). I don't know if there are any pitfals with this, but so far this seems to be the more natural approach.

In both cases, the application code will perform a session.save() after making any updates.

However, I do agree that some kind of sessionless DTO utility API would be very useful. This becomes apparent if you are exposing JCR functionality to a client using EJB. Since EJB can only pass serializable data objects, JCR Nodes and Properties and Values cannot be passed directly. I ran into this situation while developing an Eclipse RCP application (a companion to the web app) that needs to access the same Modeshape repository running in JBoss. I ended up doing something very similar to what Randall recommended: developing simple serializable NodeDTO and PropertyDTO objects and then having some utility methods to create them from JCR Nodes and Properties. If Modeshape or JCR could provide these utilities to assist in client-server access to the repository, that would be great!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜