[
https://jira.jboss.org/jira/browse/DNA-374?page=com.atlassian.jira.plugin...
]
Randall Hauch commented on DNA-374:
-----------------------------------
There are two things that conspire to cause this problem. The first is that JCR
distinguishes between single-valued and multi-valued properties and does not allow a
single-valued property to be changed with the multi-valued methods (e.g., the
Property.setValues(...) methods or the Node.setProperty(...) that takes multiple values) -
or vice versa. The multiplicity of a property has a huge impact on which API methods may
be used.
The second is that the DNA graph layer does not have this distinction. The DNA graph API
is significantly smaller and easier to use without having this distinction, and it allows
any property to be set to any values. After all, the DNA graph API was designed as a
lower-level and more simplistic graph model that didn't come with a lot of overhead or
baggage.
Therefore, since the DNA graph layer doesn't maintain this distinction, the JCR
implementation currently determines when a node is read in the most applicable property
definition for each property. Many times there is only one applicable property
definition. For example, if the property has no values or has more than one value, then
it is obvious that a multi-valued property definition must be chosen. (The property types
may also affect which property definition is selected.)
However, there are times when multiple property definitions apply. One frequent case is
"nt:unstructured", which has both a single-valued residual property definition
and a multi-valued residual property definition. Multiple applicable property definitions
complicate the determination and selection of an appropriate property definition, and
sometimes results in a property definition being selected (when a node is read in) that
may not match the definition that was used to create the property.
This is the case when a property is created to be multi-valued (via using JCR's
setters for multiple values) but only has one single value, and both a single-valued and
multi-valued property definition are available. When the parent node is saved, the
property definition is not saved, and when reading the node back in our JCR implementation
(specifically SessionCache) reads this property and attempts to determine the most
appropriate property definition. Because there is one value and single- and multi-valued
property definitions, SessionCache does not know which property definition to choose.
Currently, the single-valued property definition is used when the property has only one
value.
Note that we'd have the same problem even if we'd change SessionCache to pick the
multi-valued property definition, and the client created a single-valued property. In
this case, our implementation would read the graph and assign the multi-valued property
definition. Therefore, it is not sufficient to change how SessionCache determines the
most appropriate property definition. The problem is that we're losing information
that is not persisted in the graph and that cannot always be recovered accurately.
There are a few options:
1) Change the DNA graph layer to distinguish between single-valued and multi-valued
properties. This would be a big change to the graph API and connectors, because it adds a
lot of subtle semantics. Plus, it may snowball to needing property types and therefore
node types. Since the DNA graph layer was intended to be a lower-level and more generic
graph model, adding all this complexity can hopefully be avoided.
2) Change the DNA graph layer to support "metadata" on each property, but to not
define in the graph layer what this metadata might be. For example, the JCR layer could
use this metadata to say whether the property is single-valued or multi-valued. This
approach is far less intrusive, but it does add a "meta-level" to the existing
graph model, and this "meta-level" would not be handled the same by the
connectors or the graph API as the existing nodes and properties. Essentially we'd be
duplicating some of the functionality by allowing properties to have
"meta-properties".
3) Do not change the DNA graph layer at all, but change the JCR implementation to use
other properties on the node to store this additional information. We're already doing
that with "dna:nodeDefinition", which stores the name of the child node
definition in the parent's node type (primary or mixins) that was used to create the
node. This "dna:nodeDefinition" property is defined on DNA's node type for
"nt:base" (actually, a mixin that "nt:base" extends), and is marked as
"protected" meaning clients may not set that property through the JCR API. But
we're also hiding that property by not including it in the set of properties exposed
by the JCR API. So this option just extends this already-used approach to be used to
capture enough information to be able to properly determine the property definition for
each property.
So, option #3 appears to be the most appealing. The only question is: what information
should be stored? Should we store the ID of the property definition for each property?
Or can we store only the names of the multi-valued properties that have exactly one value?
Or, maybe we store only the names of the multi-valued properties that have exactly one
value and that have a single-valued property definition?
I don't think it's worth storing the ID of the property definitions for all
properties. That's just overkill, and in many situations it is not required. But at
the other extreme, a change in the node types might mean that we cannot always recover a
property definition if we only store the names of the multi-valued properties with one
value that use a multi-valued property definition that also have a similarly-named
single-valued property definition.
Therefore, I think the correct approach is to store the names of the multi-valued
properties that have a single value. This information, coupled with the existing value(s)
for each property, can then allow us to always figure out when should a property should be
treated as a single-valued property or a multi-valued property.
Multiplicity of some properties may change when saved and reloaded
from the graph
---------------------------------------------------------------------------------
Key: DNA-374
URL:
https://jira.jboss.org/jira/browse/DNA-374
Project: DNA
Issue Type: Bug
Components: JCR
Reporter: Randall Hauch
Assignee: Randall Hauch
Fix For: 0.4
This problem arises when a client uses the multi-valued setter methods in the JCR API to
create on a node a new property with a single value, to save the node, and then to
continue working with the property (again, using the multi-valued setter or getter
methods). When the property is created, an appropriate multi-valued property definition
will be chosen from those available on the node's primary type (and mixin types, if
there are any). However, after the save, the property may node have a single-valued
property definition. And since JCR does not allow a single-valued property to be changed
via the multi-valued setters, the result is an exception when the client attempts to set
the property using the multi-valued setters.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira