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].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to