Hi Vincent,
On Wed, Mar 6, 2013 at 4:48 PM, Vincent Massol <vincent(a)massol.net> wrote:
On Mar 6, 2013, at 1:02 PM, Denis Gervalle <dgl(a)softec.lu> wrote:
Hi Vincent,
On Wed, Mar 6, 2013 at 11:36 AM, Vincent Massol <vincent(a)massol.net>
wrote:
Resending since I've made mistakes (it's
only about ObjectReference, not
Properties), sorry about that. Here's the new version:
------------
Hi devs,
ATM in the model module there's no ability to reference an xobject other
than by using a free form name.
We made this on purpose.
I know, I worked on this… but it doesn't make it right… :)
So from this and what I read below, I understand you have suddenly decide
to revert the new model back to the old way of addressing objects and stop
using named objects. This is a major change that should be discussed first
and does not have my support right now.
The
problem is that this is not really usable. This is why we introduced
the BaseObjectReference in oldcore.
We have introduce the BaseObjectReference in oldcore simply to easily
support the current storage implementation. At that time, we had a
discussion about using the object number (not to be confuse with the
index)
or the object UUID. And, since the object UUID
was suspicious in some
edge
case, you convince me to use the object number to
create the free form
name
of these old objects (I should have resist more
since I still do not have
evidence of these edge case).
What? That defeats one of the main goal of references which is that you
can directly address an entity without having retrieved it first!
True for the old object storage, but was a better a way to avoid what you
seems to advocate now !
The reason entities have names is to be able to easily
reference them.
Ah, you are right, object should have name to be addressable properly.
Using a UUID makes it impossible to reference
something without getting it
first...
Was only about a temporary compatibility solution for old objects,
obviously not a good way to be able to create reference from scratch, but a
good way to get stable reference from objects.
If to reference an Object I have to load the Document
first, then in
practice it means we don't need Object references and they shouldn't be
considered entities.
I disagree, you do not always have to load the document to know an object
UUID. You may retrieve the UUID of object by searching the database. This
is the only way I have found until now to strongly link object together
when multiple objects are stored in the same document. However, most of the
time, I avoid this by creating only a single object of a given class per
documents when I want to reference them elsewhere. So I may use the
document itself for reference.
For any entity, you should be able to construct a
direct reference to it
without needing to load anything else.
This is precisely why we need name for referencing our objects.
In the 7-8 years of XWiki we've used Class
reference and numbers/position
to reference xobjects and it has worked quite well IMO.
I use it since as long as you, and I have mostly worked without any
reference to objects since these were missing. I mean I have usually not
accessed object unless I have them at hand, since the only correct way to
get them was exactly what you explain just above. I do not remember having
really retain object number to reference them at any moment except for a
few line of code. I have surely never based anything on "this is the third
object of that class in that document" since this is not really stable in
the current model.
In most cases you have only 1 xobject of a type and
it's very nice to be
able to say: here's a reference to the first object of type N in document P.
I said that I agree with this special case, which is really different IMO
than accessing the nth object of document. We had for this special case
helper function in XWiki since a long time and these revealed to be helpful.
Exposing an internal id of a document as reference is
a no go for me since
it cannot be constructed without retrieving the entity first.
That is not my purpose, it was only my temporary solution waiting for truly
named objects, it have been decided to use object numbers (not index !),
but this has nothing to do with the current discussion anyway. Maybe this
decision influence you however.
However this is major PITA since we can't have
clean code that create an
object reference and that doesn't depend on oldcore.
Creating a reference to the third object of a given class in a document
(or
object number 3, or even the third object of a
document) has absolutely
no
meaning unless you have already that object at
hand
Why doesn't it have a meaning? If in my app, my spec says:
- each doc has 3 objects of type P and the first one means this, the
second one that and the 3rd one that other thing,
then the 3rd one has a meaning.
And when any object get deleted, your meaning vanished. Great design of
course !
, and so you
already
have a source for its reference (solved not nicely by the
BaseObjectReference actually, but this was another story).
I'd like to propose the following:
* Modify ObjectReference to add 2 named parameters: Class reference and
position
Since position is really fragile without any real meaning,
having a
reference using a position will be a source for spurious issues, I am
definitely -1 for any positional reference.
* Make the name optional in EntityReference
This sounds like a sign of bad design to me... what is a entity without a
name in general ?
It means it's a reference to an entity by a mean other than a name :)
The mean is bad, the position may change each time object are added or
deleted. And I do not think we have real positioning in the current model,
which means you cannot really ensure object order at any time.
We need to decide but we could very well decide that some entities don't
have a name and that they can be found/addressed by some other means (as in
the case of Object references when locating them through class reference
and position).
We may, but we need strong reason to introduce that IMO. And other means
should be solid, position is not.
More below
This
means that when we use an EntityReferenceResolver to resolve
"wiki:space.page^wiki2:space2.page2" we get an ObjetReference with:
* name = null
* param1: name = "classReference", value = EntityReference
* param2: name = "objectPosition", value = 0
Rationale:
* This is exactly what we already do for Locale (and what we'll do for
Version too probably) so it's logical to do it for Object References too
I agree with your sample and your rationale, there is a need to create a
reference to the first (and probably the only for such use case) object
of
a given class in a given document without having
to compose weird names
or
positional references. This has definitely a
meaning, much more than the
second or any numbered objects... And this object is not always "[0]" in
base reference syntax !
ah good, was trying to despair :)
If the first one has a meaning, then 2nd or 3rd can also have a meaning,
see my example above. Obviously the majority of use cases will be the first
one but that doesn't mean the other positions are not needed.
0 = first not null xobject
1 = second not null xobject
...
When you use the first one, and have only one, you may ensure you get the
right one whatever the creation/deletion of object happened. This is not
true for the other one, and we do not have anything for that.
The reason I am -1 for using position, is mainly because position may
change overtime for the same object, so this is a really fragile reference,
and obviously this is not good design at all for maintaining a reference.
Position is perfect during a small piece of code, and bad to be stored as a
reference.
However, resolving
"wiki:space.page^wiki2:space2.page2" to that object is
not valid, since you do not really know what you are doing here, are you
speaking about the first object of a given class or an object named "
wiki2:space2.page2" ?
Exactly. Which is why in my proposal we would have to agree that the
current notation (thomas calls it syntax) only describes class reference
and NOT a name (name = null). If we ever want to also be able to write a
string and specify a name in it then we would need to invent a syntax, in
the same manner that we currently have no syntax to express a locale in a
document reference when expressed as a string.
I see it the other way round.
So if we need
to resolve a string into the first (or,
even if I am against, any) object of a given class, we need another
syntax
at least (BaseObjectReference had already cause
some poor stuff in
LocalUidReferenceSerializer where we had to remove wiki in a very bad way
currently).
Using a name is very very far in the future so we don't need to invent a
syntax for that now IMO.
If it is, what is the purpose of renewing the model ? Why do you prefer to
step backward instead of going forward to solve our initial issue ?
We don't even know if it'll ever happen
actually…
This really afraid me, no more ambition to get it right ?
Consequences:
* We need to modify the Seralizers/Resolvers accordingly
According we have a new syntax for your kind of object reference, we may
do
so. I resolver/serializer (as well as setter of
class reference) I
suggest
like Thomas that we support relative reference to
classes based on the
containing document, both simplifying creation and avoiding
useless repetition.
That seems good for now, even though in some far future we may want to
have a class defined in a wiki and an xobject located in another subwiki…
or not… ;)
Not repeating useless information does not mean we should not support
absolute reference as well. Thinking about it twice, I agrre with you that
this is more subtle than it look, since copying a document may be greatly
influence by this. We should discuss that further once we agree on the rest.
* We need
to modify EntityReference to support a null name
Do we really need that, or the name would simply reflect our special
syntax
?
It would be slightly misleading to use the serialized class ref as the
name IMO but why not... One danger is in code that will use it instead of
using the well-known parameters for class ref and position.
You cannot always prevent bad coding practice, and you may also think about
the easy way some may want to use in velocity for example even if this is
not optimal.
* We
deprecate BaseObjectReference
Does it really true ? It does not have the same meaning (even for your
initial proposal) since number and position are not the same and the
BaseObjectReference is a special reference, not a general object
reference,
since it does not have a real free form name.
Deprecating means we had to
replace them everywhere, and I am not sure it is easy to use index in
place
of number in some places, like storage where we
use reference for IDs.
Maybe, in any case what I meant is that we'll need to make our code use
the new way and not use BaseObjectReference as much as possible.
*
Probably some other stuff to modify like modifying event listeners
listening on objects since it's now going to be much easier, etc
WDYT?
So, to resume, I understand the need to have a way to create reference to
the first object of given class in a document. Even if using an object
reference with, let say a special syntax, will introduce some bad
consequences on the implementation of equals
equals/hashcode shoudl already work since they already take into account
parameters.
But comparing two references to the same object, one using the name of the
object (once we have it of course) and the other the classname will not
compare to be equal while these are. We have the exact same situation for
locale or version.
and related methods on entity
reference (like those we have for locale or version), we should probably
consider it (Note that it will also affect property reference).
I am definitely -1 for any positional reference which are meaningless.
I think this is a pity and you're closing the door to lots of use cases
and you're going to make them really hard and not performant to implement
as a consequence.
I am not closing anything, I am just not agreeing to create a solution that
will encourage bad design.
As a user, if I **want** to access the 3rd xobject because it has a meaning
for my app, I'm not going to be able to do so.
As a user I want to access the right object, I do not want to care about
its place, I just need to be able to name it properly. Your use case is
simply wrong and induced by the current design.
I'm going to need to load the doc and do some
queries to iterate over
xobject and count to 3… (which obviously is both painful and not
performant).
And is need it anyway to access that object, it is you or the API, but it
will be done at some point.
BTW your counter-suggestion to drop the position means
you're going to
break everything that already exists since it's currently possible to
reference an object with class and number. It means inventing a new syntax,
which is always painful to do.
Have I said you cannot use the BaseObjectReference ?
You may do so, but you are stick with the oldcore and the old and bad way
of working with object.
Again, why not using our energy to find a nice way to reach the named
object solution instead of defending a bad design we suffer from since
really too long ?
Thanks
-Vincent
_______________________________________________
devs mailing list
devs(a)xwiki.org
http://lists.xwiki.org/mailman/listinfo/devs
--
Denis Gervalle
SOFTEC sa - CEO
eGuilde sarl - CTO