On Thu, Mar 7, 2013 at 9:26 AM, Vincent Massol <[email protected]> wrote: > some amendments below. > > On Mar 7, 2013, at 9:08 AM, Vincent Massol <[email protected]> wrote: > >> >> On Mar 6, 2013, at 9:31 PM, Denis Gervalle <[email protected]> wrote: >> >>> Hi Vincent, >>> >>> >>> On Wed, Mar 6, 2013 at 4:48 PM, Vincent Massol <[email protected]> wrote: >>> >>>> >>>> On Mar 6, 2013, at 1:02 PM, Denis Gervalle <[email protected]> wrote: >>>> >>>>> Hi Vincent, >>>>> >>>>> On Wed, Mar 6, 2013 at 11:36 AM, Vincent Massol <[email protected]> >>>> 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. >> >> No I haven't changed that. I'm proposing to have both ways. Either by name >> or by class ref+index. Same as currently. >> >>>>>> 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. >> >> Either name or class ref + index. >> >> In the majority of use cases people are not going to use names and we still >> need to be able to create a reference to an object easily and class ref + >> index is the best solution I know of for that. >> >>>> 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. >> >> Yes the concept of ref did not exist but the old apis are doing the same, >> i.e. finding objects by class ref + number. >> >>>> 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. >> >> yup >> >>>> 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 ! >> >> errr? Whether it's the first one or the Nth, if it's deleted then it's no >> longer there obviously :) >> >> Same, if you delete a doc and there's a ref to it, you'll get a non existing >> document… nothing special here... >> >>>>> , 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. >> >> AFAIK we do have an order: >> >> private Map<DocumentReference, List<BaseObject>> xObjects = new >> TreeMap<DocumentReference, List<BaseObject>>(); >> >> This means that for each class ref, there's an ordered list. >> >>>> 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. >> >> It's almost as "solid" (or as "weak") as names for documents. Those docs can >> be renamed and your ref is gone! >> >> As soon as you use names and not ids in references you have "weak" >> referencing, be it for objects or any other entity. That's not a problem. It >> has the advantages that refs can be constructed. >> >> The only other solution I can think of (which wouldn't work with the current >> model and thus we would need to modify the current model to make it work >> before we can implement the new model api with the old model impl) would be >> to **force** always having a name for Objects when they are created and >> when the user doesn't specify the name it's computed automatically using a >> default scheme. For example: <class ref wiki>:<class ref space>.<class ref >> page>[number] where [number] isn't specified for the first xobject but only >> for the next ones. >> >> For example for a class ref of (wiki = my:wiki, space = my.space, page = >> mypage) we would have "my:xwiki:my.space.mypage" for the first object and >> "my:xwiki:my.space.mypage[1]" for the second one, etc. > > Correction: remove the wiki part. > >> Note that it wouldn't be a serialized ref since we need to make it as easy >> as possible to create it using string concatenation. It should never be used >> as a serialized class ref and not used to find the class ref. It's just a >> string. >> >> Moving the object around would keep this name (unless the user manually >> changes it). And renaming the xclass document would also not change this >> name. >> >> So here's what we would need to write to get the avatar property for a user: >> >> DocumentReference userDocumentReference = ... >> ObjectReference userObjectReference = new >> ObjectReference("XWiki.XWikiUsers", userDocumentReference); >> ObjectPropertyReference avatarReference = new >> ObjectPropertyReference("avatar", userObjectReference); >> >> String fileName = this.entityManager.getEntity(avatarReference).getValue(); >> >> Again, if we want to go this way we need to modify the oldcore to add >> internal support for names to XObjects. This means modifying the DB schema, >> not a very small change... >> >> Which is why I think that using class ref + index, *in addition to name* is >> probably better for now. >> >> WDYT? >> >> see more below >> >>>> 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 ? >> >> It's not a step backward. We still have the name while at the same time >> making it possible to also reference objects by a construction (class ref + >> index). BTW I don't consider class ref + index a bad thing. IMO it was >> pretty clever. Doing a new model doesn't mean throwing out all good ideas >> that existed in the old model :) >> >>>> We don't even know if it'll ever happen actually… >>>> >>> >>> This really afraid me, no more ambition to get it right ? >> >> No, you don't get it at all... >> >> As a user I don't **care at all** about object names in 99% of the cases. I >> don't want to name them as a user. That's a pain and a constraint uses >> shouldn't care about. >> >> Again we don't do that now and it works very well. >> >>>>>> 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. >> >> They won't be the same reference, which is ok. You can have several refs >> leading to the same entity. There's no issue about that. >> >>>>> 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 ? >> >> But it's not bad at all. It's very good! Forcing users to create a name for >> all objects they create would be a very bad solution… Autogenerating the >> name would be better of course but think about it twice because there's a >> huge cost to doing that in the old model as I've explained above. >> >> What I wanted to do here was to make progress since I had 2-3 days to work >> on the new model again. >> >> I see it's not easy and as a consequence we're not going to be able to >> progress. It's just sad. I had the energy to code this quickly, modify >> UserAvatarMacro to use the new model API and commit all that in master for >> 5.0M2… I don't have it anymore, nor do I have the time now (I had only 2 >> days and they're now gone… :(…). It'll have to be someone else doing it.. or >> wait till I get 10 free days in 1 year time to implement object naming in >> the current model with all the breakages this would cause… >> >> I had a good solution that was working both with the old model (class ref + >> index - or numbers, whatever would work) and the new model (names when >> they're implemented) and you're throwing it out… too bad… > > BTW I'm not saying that you're not justified in your answers. It's actually > quite good that you're taking the time to reply and brainstorm about it :) > > I just don't have much time to work on the new model and I'm frustrated that > I couldn't make progress as I would have liked in the little time I had > available. Starting next week it's going to be devoxx preparation and others > things, and I won't be able to work anymore on the new model for some time… > could be long... > > Looking at xwiki.hbm.xml I see that we have name, className and number so > maybe there's a solution to reuse the name property after all and not have to > change the schema.
This name field you are talking about is the document reference where this object is stored, not the object name. > > Thanks > -Vincent > > > _______________________________________________ > devs mailing list > [email protected] > http://lists.xwiki.org/mailman/listinfo/devs -- Thomas Mortagne _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs

