![]() |
![]() |
|
| Index | Recent Threads | Unanswered Threads | Who's Online | User List | Help |
|
|
| No member browsing this thread |
|
Thread Status: Active Total posts in this thread: 9
|
|
| Author |
|
|
Novice Joined: Jun 16, 2009 Post Count: 24 Status: Offline |
Hi This is my situation: I have an Address object that I persist/retrieve from the DB. It contains a City object, reperesenting the city on which that address is. City contains State, and State contains Country object (a long N-1 chain). When I'm creating a new address from user input, the user selected its city from a combo box which I populated from DB, then I'll have the city's ID. When I try to persist the new address, the most I can do is put a City object on it, containing only the city ID. The problem is that persisting this will erase the City record for that ID on the DB, because other fields like Name and State will be null. I want simply to set the foreign id on the Address object, nothing else. I believe there is some good solution for this... my intention is not updating the City object, and retrieving it to put it back on the address object before being persisted sounds very stupid and a performance nightmare. What's the proper way to do this? Thanks! Note: I'm using application identity. |
||
|
|
Expert Joined: Nov 16, 2005 Post Count: 844 Status: Offline |
You should post what you exactly do to create a new address. Anyway, doing a getObjectById for the City and setting the result object as a member of the newly created Address is the right way to achieve what you want. Guido ---------------------------------------- Guido Anzuoni http://www.objectmagic.org |
||
|
|
Novice Joined: Jun 16, 2009 Post Count: 24 Status: Offline |
Hi, thanks for your reply, Guido This is what my code does (only the relevant parts): //get all cities in some stateWith the IDs and names, I create a combo box (<select>) for the user. When creating the address, I use this: address.setCity(new City(cityId));This code erases the 'city' row for that city. I thought of using getObjectById, but I didn't believe that's the best way to archive this... it is an unnecessary query. Other option is to keep the detahced city objects somewhere (the session, maybe) to be used when I persist this data, but it still sounds awful, consuming memory to keep such data (which can possibly be very large... 2000 cities for 30 states at once, for example). Both solutions scare me, by extra DB access and extra memory consumption. What can I do in here? Just to remind... I use application identity... could database identity make this solution somehow better? Thanks again! Edit: another thought... if I getObjectById, what would happend if I use no fetch groups or expand default-fetch-group? My City object will not have its parent State object. Will persisting this object erase its FK to State? I haven't tested this... its just because I can't be forced to fetch the whole hierarchy. This would be impossible to handle when dealing with longer hierarchies (say manufacturer-clients-orders-items-components-ids...) ---------------------------------------- [Edit 1 times, last edit by lfs at Jun 30, 2009 12:12:33 PM] |
||
|
|
Expert Joined: Nov 16, 2005 Post Count: 844 Status: Offline |
I'm sorry, but what your code does is not what I have suggested. This new City(cityId)is not the same as pm.getObjectById(id_of_the_city)where id_of_the_city is obtained with pm.getObjectId(city)Guido ---------------------------------------- Guido Anzuoni http://www.objectmagic.org |
||
|
|
Novice Joined: Jun 16, 2009 Post Count: 24 Status: Offline |
It does not. That's my original code, the one that erases city rows... you said to post what I was doing to create addresses. I haven't implemented your code, yet I thought it worked like you posted. In my case, I'd not need 'getObjectId', because I use app identity (if I'm not mistaken, that's only needed for database identity). Between your solution and saving detached City objects somewhere to reuse them, I'd use yours, because cache hopefully would do the job quicker and cleaner, but it still is a query and cache may fail. There isn't really any other option do do this? I don't like the way it looks, and I fear my app will crumble as soon as it goes into prod and lots of users hit it per second. Thanks for your time ---------------------------------------- [Edit 1 times, last edit by lfs at Jun 30, 2009 2:45:09 PM] |
||
|
|
Expert Joined: Nov 16, 2005 Post Count: 844 Status: Offline |
It does not. That's my original code, the one that erases city rows... you said to post what I was doing to create addresses. I haven't implemented your code, yet I thought it worked like you posted. In my case, I'd not need 'getObjectId', because I use app identity (if I'm not mistaken, that's only needed for database identity). Not so sure, but I would manage you city selection list with an association between the displayed name and the result of getObjectId(city).toString(); Then, when it is time to associate the selected city to the address do: Object city_oid = pm. newObjectIdInstance(City.class, stringfied_id); City city = pm.getObjectById(city_oid); Between your solution and saving detached City objects somewhere to reuse them, I'd use yours, because cache hopefully would do the job quicker and cleaner, but it still is a query and cache may fail. There isn't really any other option do do this? I don't like the way it looks, and I fear my app will crumble as soon as it goes into prod and lots of users hit it per second. Thanks for your time I think that detachment is not a good solution for your case. (how could you prevent 2 concurrent threads from referencing the same detached object ?). Detachment is for modifying objects out of transactions and then applying changes in another PM. Guido ---------------------------------------- Guido Anzuoni http://www.objectmagic.org |
||
|
|
Novice Joined: Jun 16, 2009 Post Count: 24 Status: Offline |
Not so sure, but I would manage you city selection list with an association between the displayed name and the result of getObjectId(city).toString(); Then, when it is time to associate the selected city to the address do: Object city_oid = pm. newObjectIdInstance(City.class, stringfied_id); City city = pm.getObjectById(city_oid); Ok, I might test it... let's see if the given ID is different from my id field inside City. It would be a fitting candidate anyway. I think that detachment is not a good solution for your case. (how could you prevent 2 concurrent threads from referencing the same detached object ?). Detachment is for modifying objects out of transactions and then applying changes in another PM. I can't prevent that. That's another reason why saving these objects does not sound good. But getting the City object to put it back right away on the Address object is almost the same thing, except that it will not leave the transaction and will not be marked 'dirty', remaining unchanged and not updating the DB. I see this is a way to solve the issue, but I still "refuse to believe" this is the best one. Sorry for being stubborn, I just want to learn the best JDO has to offer. Any other way around this? Without extra queries? |
||
|
|
Expert Joined: Nov 16, 2005 Post Count: 844 Status: Offline |
Not so sure, but I would manage you city selection list with an association between the displayed name and the result of getObjectId(city).toString(); Then, when it is time to associate the selected city to the address do: Object city_oid = pm. newObjectIdInstance(City.class, stringfied_id); City city = pm.getObjectById(city_oid); Ok, I might test it... let's see if the given ID is different from my id field inside City. It would be a fitting candidate anyway. I think that detachment is not a good solution for your case. (how could you prevent 2 concurrent threads from referencing the same detached object ?). Detachment is for modifying objects out of transactions and then applying changes in another PM. I can't prevent that. That's another reason why saving these objects does not sound good. But getting the City object to put it back right away on the Address object is almost the same thing, No, at all. Every thread will get the selected city object in its own PM (PM-per-request or PM-per-session it's the same). You wont have any concurrency issue. except that it will not leave the transaction and will not be marked 'dirty', remaining unchanged and not updating the DB. I see this is a way to solve the issue, but I still "refuse to believe" this is the best one. Sorry for being stubborn, I just want to learn the best JDO has to offer. Any other way around this? Without extra queries? IMHO this is the way to go (best ?). Please check JDO spec and javadoc for getObjectById and you will find out that there is the possibility to avoid extra query. Guido ---------------------------------------- Guido Anzuoni http://www.objectmagic.org |
||
|
|
Novice Joined: Jun 16, 2009 Post Count: 24 Status: Offline |
Ok, I guess that settles the issue. Thanks for your patience and your advice, Guido. ![]() |
||
|
|
|
|
|
Current timezone is GMT Sep 2, 2010 8:56:19 PM |