city.Municipality = mun. right now city has a null Municipality which is why it's attempting to insert a null.
somethings to consider. 1. encapsulate all reads and writes within a transaction. right now your code works because Sql Server Identity actually breaks the conceptual design of NH. If you were to use a client POID like guid or hilo this wouldn't work. 2. you should never need to call session.Flush(). 3. can define the schema and table name separately in the mapping 4. You can set the namespace and assembly in the root node, so your mapping files are cleaner <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Common" namespace="Sample.Common.Kernel"> <class name="CityPoco" table="City" schema="Kernel"> ... 5. in this scenario you do not need to call saveorupdate. you are associating the city with the Municipality. NH will detect this and automatically save the city when the transaction is committed (session flushed). 6. I would also recommend encapsulating collections and publicly exposing them via IEnumerable<>. 7. naming your objects after there type is noise you don't need. I would drop "Poco" from the name of the objects. 8. you must override Equals and GetHashCode for NH to properly manage object uniqueness. On Nov 10, 1:44 pm, Kasper Nielsen <[email protected]> wrote: > Hi nhusers, > > Just started to play around with nhibernate 2.1.2. Having some trouble > implementing a one-to-many relationship though. Here is what i do: > > 1. I have got two tables with a foreign key constraint: > > Municipality (ID, Name) > City (ID, MunicipalityID, Name) > > 2. I have defined my corresponding objects like this: > > public class CityPoco > { > public virtual long ID { get; set; } > public virtual string Name { get; set; } > > public virtual MunicipalityPoco Municipality { get; set; } > } > > and > > public class MunicipalityPoco > { > public virtual long ID { get; set; } > public virtual string Name { get; set; } > > public virtual IList<CityPoco> Cities { get; set; } > } > > 3. Then i have defined my mapping like this: > > <?xml version="1.0" encoding="utf-8" ?> > <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> > <class name="Sample.Common.Kernel.CityPoco, Common" > table="[Kernel.City]"> > <id name="ID"> > <generator class="identity"/> > </id> > <property name="Name" type="String"/> > <many-to-one name="Municipality" column="MunicipalityID" > class="Sample.Common.Kernel.MunicipalityPoco, Common" /> > </class> > </hibernate-mapping> > > and > > <?xml version="1.0" encoding="utf-8" ?> > <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> > <class name="Sample.Common.Kernel.MunicipalityPoco, Common" > table="[Kernel.Municipality]"> > <id name="ID"> > <generator class="identity"/> > </id> > <property name="Name" type="String"/> > <bag name="Cities" table="[Kernel.City]" cascade="all" > inverse="true"> > <key column="MunicipalityID" not-null="true"></key> > <one-to-many class="Sample.Common.Kernel.CityPoco, > Common"></one-to-many> > </bag> > </class> > </hibernate-mapping> > > 4. Finally, i would like to add a new city to an existing municipality > like this: > > ISession session = SessionFactory.GetSession(); > MunicipalityPoco mun = > session.Load<MunicipalityPoco>((long)2); > > CityPoco city = new CityPoco(); > city.Name = "New city"; > > mun.Cities.Add(city); > session.SaveOrUpdate(mun); > session.Flush(); > > In the last line (when the actualy SQL Query is executed), it throws > an error complaining that i cannot insert NULL into "MunicipalityID" > in the "City" table. Now i wonder: why doesn't it set the > MunicipalityID to the actual ID of the Municipality instead of trying > to insert NULL? > > Help is very much appreciated :-) > > Thanks in advance. > > Kasper -- 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.
