You are using inverse=true You have to de-reference the parent from the child.
P.S. before do it, remove that ugly composite id... and perhaps rethink if the child is an entity or a component On Wed, Jul 21, 2010 at 12:22 PM, Kirsten <[email protected]> wrote: > Hi @all, > > I use NHibernate 2.1.2, have already done a lot with it. > I have spent my whole working day for deleting an item within a > persistent list. I cannot do it. > > Please review the following code and settings. Please note, that I > MUST use the given DB tables. > > Of course, this is just a normal 1:n mapping (parent:child). > > --------------------------------------------------------------------------- > > ------- > > DB Tables: > > CREATE TABLE "XHIB_CHILD" > ( "PARENT_ID" NUMBER, > "POSITION" NUMBER > ) ; > > CREATE TABLE "XHIB_PARENT" > ( "ID" NUMBER > ) ; > > ALTER TABLE "XHIB_CHILD" MODIFY ("PARENT_ID" NOT NULL ENABLE); > ALTER TABLE "XHIB_CHILD" MODIFY ("POSITION" NOT NULL ENABLE); > ALTER TABLE "XHIB_CHILD" ADD CONSTRAINT "XHIB_CHILD_PK" PRIMARY KEY > ("PARENT_ID", "POSITION") ENABLE; > > ALTER TABLE "XHIB_PARENT" MODIFY ("ID" NOT NULL ENABLE); > ALTER TABLE "XHIB_PARENT" ADD CONSTRAINT "XHIB_PARENT_PK" PRIMARY > KEY ("ID") ENABLE; > > ------- > > Classes (+Mapping) > > [Class(0, Name = "Parent", Table = "XHIB_PARENT")] > public partial class Parent > { > private int _id; > private IList<Child> _list = new List<Child>(); > [Id(0, Column = "ID", Name = "Id", TypeType = typeof(int))] > [Generator(1, Class = "sequence")] > [Param(2, Name = "sequence", Content = "S_JOB_DEFINITION")] > public virtual int Id > { > get { return _id; } > set { _id = value; } > } > [List(0, Name = "ChildList", Inverse = true, Cascade = "all- > delete-orphan")] > [Key(1)] > [Column(2, Name = "PARENT_ID", NotNull = true)] > [Index(3, Column = "POSITION")] > [OneToMany(4, Class = "Child")] > public virtual IList<Child> ChildList > { > get { return _list; } > set { _list = value; } > } > public override bool Equals(object obj) > { > if (this == obj) return true; > Parent other = obj as Parent; > if (obj == null || other == null) return false; > if (_id == other._id) > return true; > return false; > } > public override int GetHashCode() > { > int hashCode = _id; > return hashCode; > } > } > > [Class(0, Name = "Child", Table = "XHIB_CHILD")] > public partial class Child > { > private int _position; > private Parent _parent; > [CompositeId(0)] > [KeyProperty(1, Name = "Position", Column = "POSITION")] > [KeyManyToOne(2, Name = "ParentObj", Class = "Parent")] > [Column(3, Name = "PARENT_ID")] > public virtual int Position > { > get { return _position; } > set { _position = value; } > } > public virtual Parent ParentObj > { > get { return _parent; } > set { _parent = value; } > } > public override bool Equals(object obj) > { > if (this == obj) return true; > Child other = obj as Child; > if (obj == null || other == null) return false; > if (_position == other._position && _parent == > other._parent) > return true; > return false; > } > public override int GetHashCode() > { > int hashCode = _position; > if (_parent != null) > hashCode += _parent.GetHashCode() * 1000; > return hashCode; > } > } > > ------- > > NHibernate Mapping Only (probably more readable): > > <class name="Parent" table="XHIB_PARENT"> > <id name="Id" column="ID" type="Int32"> > <generator class="sequence"> > <param name="sequence">S_JOB_DEFINITION</param> > </generator> > </id> > <list name="ChildList" inverse="true" cascade="all-delete-orphan"> > <key> > <column name="PARENT_ID" not-null="true" /> > </key> > <index column="POSITION" /> > <one-to-many class="Child" /> > </list> > </class> > <class name="Child" table="XHIB_CHILD"> > <composite-id> > <key-property name="Position" column="POSITION" /> > <key-many-to-one name="ParentObj" class="Parent"> > <column name="PARENT_ID" /> > </key-many-to-one> > </composite-id> > </class> > > ------- > > NUnit Test (which fails at the end): > > [Test] > public void RemoveTest() > { > int parentIDSaved; > { > Parent myParent = new Parent(); > > // add some childs > myParent.ChildList.Add(new Child()); > myParent.ChildList.Add(new Child()); > myParent.ChildList.Add(new Child()); > myParent.ChildList[0].ParentObj = myParent; > myParent.ChildList[1].ParentObj = myParent; > myParent.ChildList[2].ParentObj = myParent; > myParent.ChildList[0].Position = 0; > myParent.ChildList[1].Position = 1; > myParent.ChildList[2].Position = 2; > > // save to DB > ISession session = > NHibernateSessionHelper.OpenSession(); > using (ITransaction trans = > session.BeginTransaction()) > { > session.Save(myParent); > trans.Commit(); > } > parentIDSaved = myParent.Id; > } > { > // load from DB > ISession session = > NHibernateSessionHelper.OpenSession(); > Parent myParent = session.Get<Parent>(parentIDSaved); > > // remove one child (not at the end!) > myParent.ChildList.RemoveAt(1); > myParent.ChildList[1].Position = 1; > > using (ITransaction trans = > session.BeginTransaction()) > { > session.SaveOrUpdate(myParent); > trans.Commit(); > } > } > { > // load from DB > ISession session = > NHibernateSessionHelper.OpenSession(); > Parent myParent = session.Get<Parent>(parentIDSaved); > > // --------- FAILS HERE ---------- > Assert.AreEqual(2, myParent.ChildList.Count); > } > } > > ------- > > Unit Test Output: > > ExplicitLotWaferDefinitionTest.RemoveTest : FailedNHibernate: select > S_JOB_DEFINITION.nextval from dual > NHibernate: SELECT child_.POSITION, child_.PARENT_ID FROM XHIB_CHILD > child_ WHERE child_.POSITION=:p0 and child_.PARENT_ID=:p1;:p0 = 0, :p1 > = 1623 > NHibernate: SELECT child_.POSITION, child_.PARENT_ID FROM XHIB_CHILD > child_ WHERE child_.POSITION=:p0 and child_.PARENT_ID=:p1;:p0 = 1, :p1 > = 1623 > NHibernate: SELECT child_.POSITION, child_.PARENT_ID FROM XHIB_CHILD > child_ WHERE child_.POSITION=:p0 and child_.PARENT_ID=:p1;:p0 = 2, :p1 > = 1623 > NHibernate: INSERT INTO XHIB_PARENT (ID) VALUES (:p0);:p0 = 1623 > NHibernate: INSERT INTO XHIB_CHILD (POSITION, PARENT_ID) VALUES > (:p0, :p1);:p0 = 0, :p1 = 1623 > NHibernate: INSERT INTO XHIB_CHILD (POSITION, PARENT_ID) VALUES > (:p0, :p1);:p0 = 1, :p1 = 1623 > NHibernate: INSERT INTO XHIB_CHILD (POSITION, PARENT_ID) VALUES > (:p0, :p1);:p0 = 2, :p1 = 1623 > NHibernate: SELECT parent0_.ID as ID36_0_ FROM XHIB_PARENT parent0_ > WHERE parent0_.ID=:p0;:p0 = 1623 > NHibernate: SELECT childlist0_.PARENT_ID as PARENT2_1_, > childlist0_.POSITION as POSITION1_, childlist0_.POSITION as > POSITION37_0_, childlist0_.PARENT_ID as PARENT2_37_0_ FROM XHIB_CHILD > childlist0_ WHERE childlist0_.PARENT_ID=:p0;:p0 = 1623 > NHibernate: SELECT parent0_.ID as ID36_0_ FROM XHIB_PARENT parent0_ > WHERE parent0_.ID=:p0;:p0 = 1623 > NHibernate: SELECT childlist0_.PARENT_ID as PARENT2_1_, > childlist0_.POSITION as POSITION1_, childlist0_.POSITION as > POSITION37_0_, childlist0_.PARENT_ID as PARENT2_37_0_ FROM XHIB_CHILD > childlist0_ WHERE childlist0_.PARENT_ID=:p0;:p0 = 1623 > > Expected: 2 > But was: 3 > > at NUnit.Framework.Assert.That(Object actual, IResolveConstraint > expression, String message, Object[] args) > at NUnit.Framework.Assert.AreEqual(Int32 expected, Int32 actual) > at > > Infineon.DataAnalysis.eSquare.Client.Forms.Tests.ExplicitLotWaferDefinitionTest.RemoveTest() > in ExplicitLotWaferDefinitionTests.cs: line 499 > > ------- > > --------------------------------------------------------------------------- > > As you can see, NHibernate has not even performed a "DELETE" > operation. > Of course, I tested the whole day and tried other approaches. But none > of them worked! Merge, SaveOrUpdateCopy, Persist, Evict, Flush, > Resetting Position, Not-Resetting Position, etc. Sometimes he performs > a delete, update, whatever. > > What I could not achieve (without many tricks and copy operations): > Just delete the middle child item and update the position of the later > ones (if automatically or not, I don't care). > > Best regards, > Kirsten > > -- > 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]<nhusers%[email protected]> > . > For more options, visit this group at > http://groups.google.com/group/nhusers?hl=en. > > -- Fabio Maulo -- 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.
