0

I need to add some node[file] to a node [folder]. but maybe some of these have the same name. like this:

attach\fileName1
attach\fileName2
attach\fileName1

I want to have an unique ID (Primary key) instead of the file name because, I use this path in another node. Is there any way to create something like auto generated ID in JCR? Or I have to manage it pragmatical?

Thanks in advance

Fazileh
  • 47
  • 1
  • 7

2 Answers2

3

JCR's standard approach for child nodes having the same name is to use same-name-siblings, or SNS (see here and here). However, their use is generally discouraged, because as the children of a node are moved, renamed, inserted, and deleted, the same-name-sibling index (and thus the path) for a given child node may change.

The JCR 2.0 API also does not define a way to automatically generate unique child node names. (JSR-333, or "JCR 2.1", is nearing final adoption and will add a way to add child nodes with unique names in an automated way. ModeShape plans to support JSR-333 in 4.0; check our roadmap for a schedule.)

So, given this, there are two ways to accomplish what you are asking, and both techniques work well in a ModeShape cluster.

Generate your own unique names

The standard nt:folder node type does not allow child nodes with same-name-siblings. After all, the nt:folder and nt:file where designed to behave like most file systems, and most of those do not allow files/folders with the same name. Therefore, when you create a node with a primary type of nt:folder, then every child must have a unique name.

One very simple way to create a unique name for a child is to use the standard java.util.UUID class. Simply generate a unique ID, and use the string form within the new child's name.

Use Same Name Siblings (SNS)

Alternatively, if you'd rather have the repository manage the uniqueness of the child node names via SNS indexes and can live with the disadvantages of SNS nodes, then simply define a custom node type that makes this possible. For example, here is a node type definition that subtypes nt:hierarchyNode (which is the supertype of both nt:folder and nt:file), and is thus similar but unrelated to nt:folder:

[acme:folder] > nt:hierarchyNode 
+ * (nt:hierarchyNode) version sns

(Your custom node type is not required to extend nt:hierarchyNode, but doing so makes it possible for nt:folder to contain nodes of type nt:file, nt:folder, and acme:folder.)

Once this node type definition is registered, simply create your folder nodes with that custom type as their primary type (or change the primary type later, which ModeShape does support).

Randall Hauch
  • 7,069
  • 31
  • 28
  • I know SNS obtain child's same name for a node, but as I said cause I want to use the node path [attach\fileName1] in another place it should not be duplicated. Therefor I use the first suggested way: Generate unique name with java.util.UUID. Thank you – Fazileh Oct 01 '13 at 05:49
  • Excuse me! I have another question? Is it possible to add a method to getting the last added node to repository, in JCR new releases? like this: getLastAddedNode() It helps to generate an ID. Thank you again. – Fazileh Oct 01 '13 at 05:57
  • 1
    No, such a method does not make sense in the context of JCR's stateful session. You can just get the last child, since child nodes are ordered by default. However, both approaches would be difficult to use under concurrent load: the last-added node name is correct only until another session adds a child node. ModeShape will instead add support for the new JSR-333 methods that add child nodes with auto-generated names that use optionally supplied hints from the user. – Randall Hauch Oct 01 '13 at 12:46
  • Thanks, How can I get last child of a node? I could not find any method! – Fazileh Oct 02 '13 at 12:21
  • You have to iterate. You can get an iterator over those nodes that match a particular pattern, or over all the nodes. – Randall Hauch Oct 02 '13 at 14:39
1

You can do this by using JcrUtils you would be able to specify your name hint for the node, i.e your "fileName" and JcrUtil will preappend a number to it resulting in something like "fileName0", bellow will do exactly what you are asking for:

JcrUtils.getOrCreateUniqueByPath(attach, "fileName", "type goes here");
zalis
  • 1,191
  • 1
  • 11
  • 20