Ok, I've replaced <key-property name="ShippingMethod" column="shipping_method" /> with <key-many-to-one name="ShippingMethod" class="Shipping" column="shipping_method" /> and set reverse="true" and cascade="all-delete-orphan" on the bad. With cascade="all" element cannot be removed. I don't really understand in which cases we have to use cascade="all" rather than cascade="all-delete-orphan"... anyway it works like a charm like that. Could you also tell me why nhibernate needs the <version /> property when dealing with composite-id ?
Thank you very much for your help. On 11 oct, 23:58, Anne Epstein <[email protected]> wrote: > Hi again, it's worth noting that if you have the ability to change up your > db, you might want to look at using a surrogate key with an idbag, they're > more efficient, and have fewer gotchas than composite ids. > > I noticed a bit more upon a second look: your bags in Shipping and Days > don't have inverse="true" .. but you probably want to have that-the default > behavior is inverse=false, and that means your shipping_method and day > columns in your primary key needs to be nullable, as the implication is that > DeliveryDay doesn't require shipping_method or days to be meaningful. in the > inverse="false" scenario you're running under that's how things are. As your > PK is made up of these two things, they are most definitely NOT optional, > ever. (If either should be optional, take them off your PK) > inverse=false works like this: NH will insert child object w/ parent id of > null, insert parent object, update child object with relationship. in the > case of deleting the child from the bag, you're talking the reverse, which > in thise case removes part of your primary key before your delete. note that > with inverse=true you're going to need to explicitly manage this > relationship on the DeliveryDay object end (ie your DeliveryDay.Day and > DeliveryDay.ShippingMethod. you can coordinate both directions by having an > add method (this is often on the class with the bag end) like this method in > ShippingMethod: > > AddDeliveryDay(DeliveryDay d) { > d.ShippingMethod = this; > _deliveryDays.Add(d); > > } > > Hopefully that gets you closer, good luck! > > On Sun, Oct 11, 2009 at 4:00 PM, mathmax <[email protected]>wrote: > > > > > Thank you for your answer. > > I've added this property in the class and the mapping file and its > > corresponding field in the table, but I still get this error when > > deleting an item: > > could not delete collection rows: > > [DeliveryDays.Shipping.Days#france_by_tnt_express][SQL: UPDATE > > delivery_days SET shipping_method = null WHERE shipping_method = ?p0 > > AND shipping_method = ?p1 AND Day = ?p2]" > > Should I use unsaved-value="any" ?Should I use cascade="all" ? > > I'm saving using session.Flush() (not SaveOrUpdate) because I want to > > save all my entities. > > This is very strange because the SQL sent is an UPDATE and not a > > DELETE... > > Am I doing something wrong ? > > > Best regards, > > > mathmax > > > On 11 oct, 17:55, Anne Epstein <[email protected]> wrote: > > > Composite keys are finicky. One key annoyance with them is that unless > > you > > > givroperly.e them a little help, composite-key entities can't properly > > use > > > SaveOrUpdate, and can't be used with cascading properly. > > > > Two fixes. you can implement an IInterceptor, or you can add a <version> > > > property. I haven't done the first, but I can say from experience the > > > second is simple enough. Just a few things you need to do: > > > > 1) add a property to your class-just like any of your other properties in > > > your class... unless you do choose to use access="field..." in this case, > > > let's name your property LastModifiedOn. this new field is for > > NHibernate, > > > not for you, so you can look, but don't mess with it yourself. (you may > > > want to use access="field...." option so you man map directly to the > > private > > > field and you don't have to expose this outside your class-you'll need to > > go > > > to the NH docs and pick your naming strategy)- > > > > 2) add property to your mapping: > > > <version name="LastModifiedOn" type="timestamp" column="LastModifiedOn" > > > /> > > > > 3) Don't forget to add the new field to the table! Note that if you add a > > > version column to an existing table, you're going to have to prepopulate > > the > > > existing rows for your your new column with an initial datetime or you'll > > > get errors-any date at all, so long as it's in the past. 1/1/2009 > > 12:00:00 > > > is as good a value as any.... > > > > On Sun, Oct 11, 2009 at 1:45 AM, mathmax <[email protected] > > >wrote: > > > > > Hello, > > > > > I try to delete an item of a collection inside a transaction. When I > > > > flush the session I get this error because the class of the child > > > > items is mapped with a composite Id. > > > > > the mapping file look like this: > > > > > <class name="Shipping" table="shipping_methods" lazy="false"> > > > > <id name="Id" column="id"> > > > > <generator class="assigned" /> > > > > </id> > > > > ... > > > > <bag name="Days" table="delivery_days" lazy="false" cascade="all- > > > > delete-orphan"> > > > > <key column="shipping_method"/> > > > > <one-to-many class="DeliveryDay" /> > > > > </bag> > > > > > </class> > > > > > <class name="DeliveryDay" table="delivery_days" lazy="false"> > > > > <!--http://journalofasoftwaredev.wordpress.com/2008/04/19/ > > > > nhibernate-exception-unexpected-row-count-0-expected-1/--< > >http://journalofasoftwaredev.wordpress.com/2008/04/19/%0Anhibernate-e...> > > > > > <composite-id unsaved-value="any"> > > > > <key-property name="ShippingMethod" column="shipping_method" /> > > > > <key-property name="Day" /> > > > > </composite-id> > > > > ... > > > > </class> > > > > > I try with and without unsaved-value="any" on the composite-id tag > > > > cascade="all-delete-orphan", cascade="all" and no cascade attribute on > > > > the bag tag. > > > > But I always get an error. > > > > Depending on the cascade and unsaved-value attribute I get different > > > > error messages. > > > > With this mapping file I get this error : {"Unexpected row count: 0; > > > > expected: 1"} > > > > and it seems that the SQL sent to the database is an UPDATE statement > > > > instead of a DELETE statement... very strange. > > > > I also get sometimes this error when I try to add more than on item to > > > > the collection : {"a different object with the same identifier value > > > > was already associated with the session: DeliveryDays.DeliveryDay, of > > > > entity: DeliveryDays.DeliveryDay"} > > > > > Does anyone know what I am doing wrong with composite-key ? > > > > > regards, > > > > > mathmax > > --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
