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.