tags:

views:

43

answers:

2

Hi, I know there are many threads about this around, but I've been trying everything I could see for a while now but still no luck.

I have an Item object, which contains a collection of itemdocument. Using nhibernate to link to the database, I can easily add to my collection of itemdocument, update items in it, etc, but whatever I do, I cannot delete.

I load the item from the same session I try to delete it from. I even added the session as a property of the item object, and use that property to save it, just in case.

If I use a Session.Delete() on an itemdocument in the collection, and then I re-save the item object (without removing the itemdocument from the collection), it actually creates a new object, which is to be expected. So that tells me my Save are working.

I hope this all makes sense, I'm getting a bit frustrated and might not be as clear as I want...

See my mappings for the item object:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="namespace.Business.BusinessEntity">

  <class name="Item, namespace" table="[dbo].[Item]">

    <id name="ItemId" column="ItemId" type="Int32" unsaved-value="0">
      <generator class="identity" />
    </id>       

    <property name="ItemCode" column="ItemCode" type="String" length="50" />
    <property name="InternalDescription" column="InternalDescription" type="String" length="254" />
    <property name="IsEnabled" column="IsEnabled" type="Boolean" />
    <property name="Size" column="Size" type="String" length="50" />      

    <set name="Pictures" cascade="all-delete-orphan" inverse="true" >
      <key column="ItemId" not-null="true"/>
      <one-to-many class="ItemDocument" />
    </set>

  </class>
</hibernate-mapping>

Mapping for the Itemdocument object:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="namespace.Business.BusinessEntity">

  <class name="ItemDocument, namespace" table="[dbo].[ItemDocument]">

    <id name="ItemDocumentId" column="ItemDocumentId" type="Int32">
      <generator class="identity" />
    </id>       

    <property name="Order" column="[Order]" type="Int32"  />

    <many-to-one name="Item" class="Item" column="ItemId" not-null="true" />
    <many-to-one name="Document" class="Document" column="DocumentId"  cascade="save-update" not-null="true"/>

  </class>
</hibernate-mapping>

Code for the delete:

//This does nothing
item.Pictures.Remove(item.Pictures.ElementAt(0));
session.SaveOrUpdate(item);

//This neither
session.Delete(item.Pictures.ElementAt(0));
item.Pictures.Remove(item.Pictures.ElementAt(0));
session.SaveOrUpdate(item);
A: 

Have you tried to delete the collection item and then re-obtain the item? as in get the reference of the item you wish to delete, delete it, and then use hql to re-get the updated object?

Mark
I'm not sure I'm following you, do you have an example?
David
+3  A: 

Maybe it's just partial code, but there's no call to session.Flush(). Nothing is persisted to the database until Flush is called (for the default FlushMode of Auto). Try this:

item.Pictures.Remove(item.Pictures.ElementAt(0));
session.Flush();

You only need to call SaveOrUpdate if item is a transient object. Assuming that you already retrieved item using NHibernate then its persistent. Chapter 9 in the documentation has the details.

Edit: Pictures is the inverse side, so you have to set the reference to null on the "many" side of the collection:

var pictureToRemove = item.Pictures.ElementAt(0);
pictureToRemove.Item = null;
item.Pictures.Remove(pictureToRemove);
session.Flush();
Jamie Ide
If I do this:item.Pictures.ElementAt(0).Order = 9;session.Flush();It runs the update against the Database (same if I do SaveOrUpdate()).If I do the same as you put above, nothing happens. It's the same for all of my collections, there is something I'm not getting here...
David
Still doesn't do anything on the SQL Server side.If I try to do Session.Delete(pictureToRemove);IT fires an error saying a not-null property has been set to null.
David