Thanks all, I have a much better understanding of how things work now. I have a solution that works and doesn't require any load/get of entities:
var user = session.Get<User>(userID); user.Country = new Country(); user.Country.ID = 2; I think NHibernate should not validate the child object if cascade="none" is set. On Nov 3, 4:05 pm, "Anne Epstein" <[EMAIL PROTECTED]> wrote: > Just to clarify what Will said, (sorry if this is familiar to you > already, Jonty) : > > NHibernate works with entities. If you want to switch out what > country your "user" is referencing, you should attach a different > "country" object by retrieving it via NHibernate, (probably with the > id), assign to the user, and re-save your user. > > The key thing to know, and the solution to your question is that if > you retrieve the new country via the "Load" method, is that NHibernate > won't bother actually going to the database to get your country > object-it'll just make a proxy of the country object based on your id > and give that back to you. Save the user, and you'll have your > persisted reference to the new country without *ever* having gotten > your country object from the db. Now if you do call something on your > country object that requires country's data, NHibernate will invisibly > get the real object for you and you'll get the db hit-but not until > you make that call against country's extra data. > > The catch is that if you retrieve the country with an id that isn't in > your database, NHibernate will still happily give you a proxy-but if > you try to use one of the properties from the database, NHibernate > will throw up on attempting to retrieve a row that doesn't exist... or > if you never use the proxy except for assignment and then save that > user, you could end up with a bad country id in the user table (unless > you have a foreign key constraint, then you'll get an error on > insert). > > To avoid these problems, you can use Get instead of Load. Then you'll > retrieve the row from the database upfront-you'll KNOW that object is > good (or get a null). But then you have your "useless" call, which is > what you're trying to avoid. So, if you KNOW your id is valid, use > Load to save the extra db hit, otherwise, consider Get. > > On Mon, Nov 3, 2008 at 7:42 AM, Will Shaver <[EMAIL PROTECTED]> wrote: > > If you use Load it won't hit the database until it actually needs it. Does > > that not work in this situation? > > > On Mon, Nov 3, 2008 at 4:00 AM, paulh <[EMAIL PROTECTED]> wrote: > > >> Jonty > > >> Could you give us some more information, e.g. what your domain model is > >> and what the mapping looks like - without that it is very difficult to give > >> a sensible answer > > >> Paul > > >> ________________________________ > >> From: Jonty <[EMAIL PROTECTED]> > >> Sent: 03 November 2008 10:16 > >> To: nhusers <[email protected]> > >> Subject: [nhusers] Re: Updating many-to-one relationship references > > >> Has anyone got any ideas for this? It must be a common scenario. > > >> On Oct 31, 12:49 pm, Jonty wrote: > >> > We would like to update many-to-one relationships by simply altering > >> > the ID of the object, but NHibernate throws an error: "identifier of > >> > an instance of Country was altered from 7 to 8". > > >> > What is the normal pattern for updating many-to-one relationships? Is > >> > it: > > >> > var user = session.Get(userID); > >> > user.Country = > >> > session.Get(Convert.ToInt32(Request.Form["Country_ID"])); > >> > user.Manager = > >> > session.Get(Convert.ToInt32(Request.Form["Manager_ID"])); > >> > user.State = session.Get(Convert.ToInt32(Request.Form["State > >> > _ID"])); > >> > user.Region = session.Get(Convert.ToInt32(Request.Form["State > >> > _ID"])); > > >> > Do we really need to make an extra database call for every child > >> > object (event though those objects aren't being updated)? In our app > >> > at the moment the ID's of the many-to-one objects are updated from the > >> > Request.Form values via automatic deserialization: > > >> > var ds = new NameValueDeserializer(); > >> > var entity = session.Get(entityID); > >> > ds.Deserialize(entity, form); > >> > session.Update(entity); > > >> > So this works generically for all entities. Having to specifically > >> > load up child objects to save the entity would be an unnecessary > >> > coding overhead (as well as making extra database calls). > > >> > Is there no way round this in configuration, mappings, interceptors, > >> > etc? Does anyone know why Hibernate has taken this design decision? At > >> > the moment we have a work around which involves using a component > >> > wherever we would normally have a many-to-one. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "nhusers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/nhusers?hl=en -~----------~----~----~----~------~----~------~--~---
