Hi!
I'm having an issue I don't recall having had about half a year ago when trying out Voyage. In my schema, a User has an instVar referencing all the Centers he belongs to, and a Center has an instVar referencing all of its Users, so when the Voyage serializer tries to serialize a user (or a center), it goes into an infinite loop trying to find the end of the reference chain and the image clogs.
I remember saving the exact same schema a while ago without a problem, is there something new I should know about? BTW, I'm using the #bleedingEdge version, with Magritte3 and all.
Thanks! :) Bernat Romagosa. |
Bump? 2013/6/6 Bernat Romagosa <[hidden email]>
Bernat Romagosa. |
Hi,
sorry... I has been running like hell last two weeks. I posted a reply but sadly no good news... I don't know where is your error. Probably a problem in your configuration. I have in my TODO list to write a comprehensive documentation for voyage, but I'm not sure when I will have the time to finish it... I promise next weeks :) Esteban On Jun 11, 2013, at 10:41 AM, Bernat Romagosa <[hidden email]> wrote:
|
Hi Esteban! Thanks a lot, I tried your code and it's working for me, so the problem must be somewhere else. I set up a logger in VOMongoSerializer >> #serialize:description:using: and I can confirm it keeps jumping back and forth between two related objects, but I don't really know why...
#new is overriden in my model classes, could this have any impact? 2013/6/11 Esteban Lorenzano <[hidden email]>
Bernat Romagosa. |
btw the configuration of voyage is outdated in the mongotalk driver (another thing I need to update, he)
you might want to try manually updating the mongotalk packages. cheers, Esteban On Jun 11, 2013, at 1:39 PM, Bernat Romagosa <[hidden email]> wrote:
|
Hi,
I was working for a while with Mongotalk and started with Voyage today. I run in exactly the same problem as Bernat. Image non responding. I tried the star/planet example and it worked. hmpf. When I debugged into, I recognized that I did not tell Voyage at which "model bounds" to stop when creating the json. I have to explain this. I have Persons and Trips. One person can have many trips, one trip belongs to exactly one person. But my trips also have e.g. associations to Countries. I do not want Voayge to put the whole country instance in the json of the trip but only a key (e.g. #germany) for getting the country instance back when loading the trip. Currently, Voyage is trying to put all the stuff in the json, also currencies etc. I am not sure if the image is hanging because of this reason. So, my question is how to tell voyage which attributes NOT to put completely into the json but only a key. Sabine |
I found this:
http://smallworks.eu/web/blog/2013-06-14-voyage-the-adventure Chapter "Enhancing storage" But if I add the 3+1 methods to Rectangle, and save it again, the json did not change. Did I miss something? |
Hi Sabine,
Probably you do not missed anything. Probably I missed to update the voyage configuration :) can you try doing VOMongoRepository allInstancesDo: #reset. before trying again? Cheers, Esteban On Jul 18, 2013, at 6:31 PM, Sabine Knöfel <[hidden email]> wrote: > I found this: > http://smallworks.eu/web/blog/2013-06-14-voyage-the-adventure > > Chapter "Enhancing storage" > But if I add the 3+1 methods to Rectangle, and save it again, the json did > not change. > > Did I miss something? > > > > > -- > View this message in context: http://forum.world.st/Voyage-Circular-references-tp4691940p4699436.html > Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com. > |
Hi Esteban,
yes, now the Rectangle Example works after doing the reset. But saving my model still leads to a non responding image because Voyage is trying to write json for all model stuf deep deep deep and circular. Perhaps same like: http://forum.world.st/Voyage-Circular-references-td4691940.html#a4699436 I dont know anything about Magritte (yet) and I need a hint what to define in my model so that it stops creating json at certain points and creates only e.g. a Symbol. Example: My model instance of trip has a connection to an instance of country. The country should not be written in json with all its definitions. Voyage should only write e.g. #germany in the json and later, when getting the instance back from the database, I want to reassign the trip to the country. I already implemented this stuff when working witk Mongotalk the last months and it worked fine. But my question yesterday: http://forum.world.st/MongoDB-open-close-in-production-singleton-or-not-td4699322.html lead to my impression that I should use voyage. So, how can I define the "borders"? Sabine On Thu, Jul 18, 2013 at 7:45 PM, EstebanLM [via Smalltalk] <[hidden email]> wrote: > Hi Sabine, > > Probably you do not missed anything. > Probably I missed to update the voyage configuration :) > > can you try doing > > VOMongoRepository allInstancesDo: #reset. > > before trying again? > > Cheers, > Esteban > > On Jul 18, 2013, at 6:31 PM, Sabine Knöfel <[hidden email]> wrote: > >> I found this: >> http://smallworks.eu/web/blog/2013-06-14-voyage-the-adventure >> >> Chapter "Enhancing storage" >> But if I add the 3+1 methods to Rectangle, and save it again, the json did >> not change. >> >> Did I miss something? >> >> >> >> >> -- >> View this message in context: >> http://forum.world.st/Voyage-Circular-references-tp4691940p4699436.html >> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com. >> > > > > > ________________________________ > If you reply to this email, your message will be added to the discussion > below: > http://forum.world.st/Voyage-Circular-references-tp4691940p4699443.html > To unsubscribe from Voyage: Circular references, click here. > NAML |
Hi Sabine!
If you want an object to be referenced by another, and not embedded in it, you need to give that object root entity. As a root, the object will have a collection of its own, and will be referenced by other objects by id. If the object is not root, it will be embedded inside the referring object as a property.
So, to be safe, always set #isVoyageRoot to return true at class side of all objects you don't want to have embedded. In general, "big enough" objects who are referenced by different objects should be root.
In my case, I had a centre which had users which had centres. Users also had projects, and projects also had users. Big mess, I know. Besides that, all users, centres and projects had profiles. My solution was to make centres, projects and users be roots, and let only the profiles be embedded.
I hope this helped! Bernat. 2013/7/19 Sabine Knöfel <[hidden email]> Hi Esteban, Bernat Romagosa. |
Hi Sabine,
If Bernat help is not enough, I would like to have some more insight on your problem, so If you can put here a better description of your model and the problem you are having, I will have a look :) Esteban On Jul 19, 2013, at 10:42 AM, Bernat Romagosa <[hidden email]> wrote:
|
Hi Esteban,
thanks! I think the solution of Bernat will not be enough for me. I added the class methods isVoyageRoot to the root objects (like trip, country and so on). But I have instances which should never be persistent, e.g. the country I mentioned. The Country has currencies and expense rates and this is a lot of stuff...this should be only transient in the image. The transient country is referenced by persistent instances of trip. (countrie does naturally not point to trips) Trip (persistant) -> Country (transient) If I try to save a trip, voyage at some point enters >>rawReference: description: and there, it looks whether anObject (a country) isNew: isNew means the other object, the country has an _id (mongo id). The country does not have an id and for this reason, voyage tries to make it persistent although its class has isVogageRoot false. And than the system enters a point where it tries to make so many objects persistent that the image does not respond anymore. So, my question is: is it possible to define "In class trip, there is an inst var country -> voyage please save only a symbol here" and "voyage, if loading a trip, for inst var country, do shting" Sure, I could save symbols within the trips country inst var all the time and get the country it if needed, but it would be nicer if voyage coud do that for me .-) Sabine On Fri, Jul 19, 2013 at 11:52 AM, EstebanLM [via Smalltalk] <[hidden email]> wrote: > Hi Sabine, > > If Bernat help is not enough, I would like to have some more insight on your > problem, so If you can put here a better description of your model and the > problem you are having, I will have a look :) > > Esteban > > On Jul 19, 2013, at 10:42 AM, Bernat Romagosa <[hidden email]> wrote: > > Hi Sabine! > > If you want an object to be referenced by another, and not embedded in it, > you need to give that object root entity. As a root, the object will have a > collection of its own, and will be referenced by other objects by id. If the > object is not root, it will be embedded inside the referring object as a > property. > > So, to be safe, always set #isVoyageRoot to return true at class side of all > objects you don't want to have embedded. In general, "big enough" objects > who are referenced by different objects should be root. > > In my case, I had a centre which had users which had centres. Users also had > projects, and projects also had users. Big mess, I know. Besides that, all > users, centres and projects had profiles. My solution was to make centres, > projects and users be roots, and let only the profiles be embedded. > > I hope this helped! > > Bernat. > > > 2013/7/19 Sabine Knöfel <[hidden email]> >> >> Hi Esteban, >> >> yes, now the Rectangle Example works after doing the reset. >> >> But saving my model still leads to a non responding image because >> Voyage is trying to write json for all model stuf deep deep deep and >> circular. Perhaps same like: >> http://forum.world.st/Voyage-Circular-references-td4691940.html#a4699436 >> >> I dont know anything about Magritte (yet) and I need a hint what to >> define in my model so that it stops creating json at certain points >> and creates only e.g. a Symbol. >> >> Example: My model instance of trip has a connection to an instance of >> country. The country should not be written in json with all its >> definitions. Voyage should only write e.g. #germany in the json and >> later, when getting the instance back from the database, I want to >> reassign the trip to the country. >> >> I already implemented this stuff when working witk Mongotalk the last >> months and it worked fine. But my question yesterday: >> >> http://forum.world.st/MongoDB-open-close-in-production-singleton-or-not-td4699322.html >> lead to my impression that I should use voyage. >> >> So, how can I define the "borders"? >> >> Sabine >> >> On Thu, Jul 18, 2013 at 7:45 PM, EstebanLM [via Smalltalk] >> <[hidden email]> wrote: >> >> > Hi Sabine, >> > >> > Probably you do not missed anything. >> > Probably I missed to update the voyage configuration :) >> > >> > can you try doing >> > >> > VOMongoRepository allInstancesDo: #reset. >> > >> > before trying again? >> > >> > Cheers, >> > Esteban >> > >> > On Jul 18, 2013, at 6:31 PM, Sabine Knöfel <[hidden email]> wrote: >> >> > >> >> I found this: >> >> http://smallworks.eu/web/blog/2013-06-14-voyage-the-adventure >> >> >> >> Chapter "Enhancing storage" >> >> But if I add the 3+1 methods to Rectangle, and save it again, the json >> >> did >> >> not change. >> >> >> >> Did I miss something? >> >> >> >> >> >> >> >> >> >> -- >> >> View this message in context: >> >> http://forum.world.st/Voyage-Circular-references-tp4691940p4699436.html >> >> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com. >> >> >> > >> > >> > >> > >> > ________________________________ >> > If you reply to this email, your message will be added to the discussion >> > below: >> > http://forum.world.st/Voyage-Circular-references-tp4691940p4699443.html >> > To unsubscribe from Voyage: Circular references, click here. >> > NAML >> >> ________________________________ >> View this message in context: Re: Voyage: Circular references >> >> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com. > > > > > -- > Bernat Romagosa. > > > > > ________________________________ > If you reply to this email, your message will be added to the discussion > below: > http://forum.world.st/Voyage-Circular-references-tp4691940p4699516.html > To unsubscribe from Voyage: Circular references, click here. > NAML |
this is a nice case for the tutorial :)
Stef On Jul 19, 2013, at 12:56 PM, Sabine Knöfel <[hidden email]> wrote: Hi Esteban, |
:-) For me it would be very useful ;-)
But a hint here in the forum would be enough for the moment to proceed. Sabine |
In reply to this post by Sabine Manaa
Hi Sabine,
I'm really sorry, I just went on vacations when you sent this mail :( Is this problem persisting? Did you reach a solution? Can I help you with something? Esteban On Jul 19, 2013, at 12:56 PM, Sabine Knöfel <[hidden email]> wrote: Hi Esteban, |
Hi esteban, Thank you for answering. The Problem persists i was waiting for your answer and it would be great if you could answer my Last Post in the Forum (how to tell voyage the "boundary"). I am also in vacation now and back mid of next week. Sorry for the spelling i write from Mobile phone. Sabine Am 29.07.2013 15:13 schrieb "EstebanLM [via Smalltalk]" <[hidden email]>:
Hi Sabine, |
Hi Sabine,
I'm trying to understand your problem. As far as I see, you have: - A set of Countries - A set of Trips Why Country is transient? When you declare an attribute as *transient*, that means its value will not be persisted, then when you retrieve it again, you will have country = nil in your trip (which I imagine is an error). How I would solve this problem? Well... both Trip and Country has to be persistent (both #isVoyageRoot should answer true). That should be enough... Now... you probably want your list of countries to be constant inside your app (since they are basically the same 150+others new each year-some no-more-there each year). This is like an enumeration (Country = #(Argentine France Germany ...) if this is your case, what you can do is to declare a different kind of accessor (in the same way you do it for magritte + seaside): something like this: Trip class>>#mongoCountry <mongoDescription> ^ VOMongoToOneDescription new attributeName: 'country'; accessor: (MAPluggableAccessor read: [ :trip | trip country name ] write: [ :trip :value | Country countryWithName: value ]); yourself this way you can keep in the database whatever value you want (an ISO, an internet extension, etc.) I hope this solve your problem :) Esteban On Jul 29, 2013, at 7:01 PM, Sabine Knöfel <[hidden email]> wrote:
|
Hi Esteban,
thank you for the solution with the VOMongoToOneDescription. This works perfect for me. I have to come back to the circular references. I am not sure if this is a bug. I have the following model: Trip ->> Day <->> VehicleTrip One Trip has N Days. One Day has N VehicleTrips. The VehicleTrip points back to its Day. The Trip is voyageRoot. But I dont want Day or VehicleTrip to be voyageRoot, too. (In my opinion this does not make sense). If I try to save the trip, I get the endless loop. Attention, the Image freezes then. :-) How would you solve this? Also with the VOMongoToOneDescription solution? You can reproduce it with the fileout below. Regards Sabine This is the fileout: Object subclass: #Day instanceVariableNames: 'date vehicleTrips' classVariableNames: '' poolDictionaries: '' category: 'RKA24-Demo'! !Day methodsFor: 'accessing' stamp: 'sabineknoefel 8/12/2013 11:13'! date: anObject date := anObject! ! !Day methodsFor: 'accessing' stamp: 'sabineknoefel 8/12/2013 11:15'! vehicleTrips: anObject vehicleTrips := anObject! ! Object subclass: #VehicleTrip instanceVariableNames: 'day description' classVariableNames: '' poolDictionaries: '' category: 'RKA24-Demo'! !VehicleTrip methodsFor: 'accessing' stamp: 'sabineknoefel 8/12/2013 11:13'! day: anObject day := anObject! ! !VehicleTrip methodsFor: 'accessing' stamp: 'sabineknoefel 8/12/2013 11:14'! description: anObject description := anObject! ! Object subclass: #Trip instanceVariableNames: 'days description' classVariableNames: '' poolDictionaries: '' category: 'RKA24-Demo'! !Trip methodsFor: 'accessing' stamp: 'sabineknoefel 8/12/2013 11:14'! days: anObject days := anObject! ! !Trip methodsFor: 'accessing' stamp: 'sabineknoefel 8/12/2013 10:12'! description: anObject description := anObject! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! Trip class instanceVariableNames: ''! !Trip class methodsFor: 'as yet unclassified' stamp: 'sabineknoefel 8/12/2013 11:15'! demo |theTrip theDay theVehicleTrip| theTrip := Trip new description: 'Trip to Munic'. theDay := Day new date: Date today. theVehicleTrip := VehicleTrip new description: 'with car to fair'. theVehicleTrip day: theDay. theTrip days: (OrderedCollection with: theDay). theDay vehicleTrips: (OrderedCollection with: theVehicleTrip ). theTrip halt save ! ! !Trip class methodsFor: 'as yet unclassified' stamp: 'sabineknoefel 8/12/2013 09:47'! isVoyageRoot ^true! ! |theTrip theDay theVehicleTrip| theTrip := Trip new description: 'Trip to Munic'. theDay := Day new date: Date today. theVehicleTrip := VehicleTrip new description: 'with car to fair'. theVehicleTrip day: theDay. theTrip days: (OrderedCollection with: theDay). theDay vehicleTrips: (OrderedCollection with: theVehicleTrip ). theTrip inspect |
Hi Sabine,
Sadly there is no automatic solution for your problem. I managed to resolve that by hacking the mongo description this way: Trip class>> isVoyageRoot = true Day class>> isVoyageRoot = false VehicleTrip class>> isVoyageRoot = false Now, the trick is that since the document will be something like: Trip { days { Day { VehicleTrip { ... day} VehicleTrip { ... day} } } } (that's of course, pseudo coding heavily ;) ) Actually, since all VehicleTrips will be part of Day subdocument, you do not need to store them. What you really need is to have the back-reference when you reconstruct the document You can achieve that by declaring transient the #day attribute of VehicleTrip and setting the day back when you read Day from the database: VehicleTrip class>>mongoDay <mongoDescription> ^ VOMongoTransientDescription new attributeName: 'day'; yourself Day class>>mongoVehicleTrips <mongoDescription> ^VOMongoToManyDescription new attributeName: 'vehicleTrips'; accessor: (MAPluggableAccessor read: [ :day | day vehicleTrips ] write: [ :day :trips | trips do: [ :each | each day: day ]. day vehicleTrips: trips ]); yourself I think that will solve your embedded-cyclic problem. yes... it is a bit hacky, but it works perfectly :) Cheers, Esteban On Aug 12, 2013, at 11:33 AM, Sabine Knöfel <[hidden email]> wrote: > Hi Esteban, > > thank you for the solution with the VOMongoToOneDescription. > This works perfect for me. > > I have to come back to the circular references. > I am not sure if this is a bug. > > I have the following model: > > Trip ->> Day <->> VehicleTrip > > One Trip has N Days. > One Day has N VehicleTrips. > The VehicleTrip points back to its Day. > The Trip is voyageRoot. > > But I dont want Day or VehicleTrip to be voyageRoot, too. > (In my opinion this does not make sense). > > If I try to save the trip, I get the endless loop. > Attention, the Image freezes then. :-) > > How would you solve this? Also with the VOMongoToOneDescription solution? > You can reproduce it with the fileout below. > > Regards > Sabine > > This is the fileout: > > Object subclass: #Day > instanceVariableNames: 'date vehicleTrips' > classVariableNames: '' > poolDictionaries: '' > category: 'RKA24-Demo'! > > !Day methodsFor: 'accessing' stamp: 'sabineknoefel 8/12/2013 11:13'! > date: anObject > > date := anObject! ! > > !Day methodsFor: 'accessing' stamp: 'sabineknoefel 8/12/2013 11:15'! > vehicleTrips: anObject > > vehicleTrips := anObject! ! > > > Object subclass: #VehicleTrip > instanceVariableNames: 'day description' > classVariableNames: '' > poolDictionaries: '' > category: 'RKA24-Demo'! > > !VehicleTrip methodsFor: 'accessing' stamp: 'sabineknoefel 8/12/2013 11:13'! > day: anObject > > day := anObject! ! > > !VehicleTrip methodsFor: 'accessing' stamp: 'sabineknoefel 8/12/2013 11:14'! > description: anObject > > description := anObject! ! > > > Object subclass: #Trip > instanceVariableNames: 'days description' > classVariableNames: '' > poolDictionaries: '' > category: 'RKA24-Demo'! > > !Trip methodsFor: 'accessing' stamp: 'sabineknoefel 8/12/2013 11:14'! > days: anObject > > days := anObject! ! > > !Trip methodsFor: 'accessing' stamp: 'sabineknoefel 8/12/2013 10:12'! > description: anObject > > description := anObject! ! > > "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! > > Trip class > instanceVariableNames: ''! > > !Trip class methodsFor: 'as yet unclassified' stamp: 'sabineknoefel > 8/12/2013 11:15'! > demo > |theTrip theDay theVehicleTrip| > theTrip := Trip new description: 'Trip to Munic'. > theDay := Day new date: Date today. > theVehicleTrip := VehicleTrip new description: 'with car to fair'. > theVehicleTrip day: theDay. > theTrip days: (OrderedCollection with: theDay). > theDay vehicleTrips: (OrderedCollection with: theVehicleTrip ). > > theTrip halt save ! ! > > !Trip class methodsFor: 'as yet unclassified' stamp: 'sabineknoefel > 8/12/2013 09:47'! > isVoyageRoot > ^true! ! > > > > > > |theTrip theDay theVehicleTrip| > theTrip := Trip new description: 'Trip to Munic'. > theDay := Day new date: Date today. > theVehicleTrip := VehicleTrip new description: 'with car to fair'. > theVehicleTrip day: theDay. > theTrip days: (OrderedCollection with: theDay). > theDay vehicleTrips: (OrderedCollection with: theVehicleTrip ). > > theTrip inspect > > > > -- > View this message in context: http://forum.world.st/Voyage-Circular-references-tp4691940p4703303.html > Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com. > |
Hi Esteban,
thanks, this works fine now! You also answered my next question how to define an attribute as transient -> with VOMongoTransientDescription :) Your blog posts http://smallworks.com.ar/web/blog?_k=c9RiCz1d5w-0XSbp are very helpful to start. Do you have more information/documentation for voyage? Regards Sabine |
Free forum by Nabble | Edit this page |