views:

16

answers:

1

Hi,

I am trying to delete an object and cascade the delete to the child objects in a one-to-many association. I think that I have done everything correctly for this to work. However, when I run my test, NHibernate attempts to insert a null value into the foreign key column of the child table rather than deleting the items.

From my parent mapping (Carrier):

<set name="Drivers" access="field.camelcase-underscore">
  <key column="CarrierId"/>
  <one-to-many class="Vehicle"/>
</set>

From my child mapping (Vehicle):

    <many-to-one name="Carrier" class="Carrier" column="CarrierId" not-null="true"/>

My test:

    [Test]
    public void Can_delete_a_carrier_and_associated_vehicles() {
        object id;

        var carrier = new Carrier { BusinessRef = 759540, Name = "Carrier1" };
        var vehicle = new Vehicle { Carrier = carrier, BusinessRef = "FOOBAR", VehicleType = VehicleType.Trailer };

        using (var txn = session.BeginTransaction()) {
            id = session.Save(carrier);
            session.Save(vehicle);
            txn.Commit();
        }

        session.Clear();

        using (var txn = session.BeginTransaction()) {
            var fromDb = session.Get<Carrier>(id);
            Assert.IsNotNull(fromDb);
            Assert.AreEqual("FOOBAR", fromDb.Vehicles.First().BusinessRef);

            session.Delete(fromDb);
            txn.Commit();
        }
    }

The generated SQL:

INSERT INTO Carriers (...) VALUES (...); select last_insert_rowid();@p0 = 'WSH', @p1 = 759540, @p2 = False

INSERT INTO Vehicles (...) VALUES (...); select last_insert_rowid();@p0 = 2, @p1 = 'FOOBAR', @p2 = 4

SELECT carrier0_.Id, ... FROM Carriers carrier0_ WHERE carrier0_.Id=@p0;@p0 = 4 SELECT vehicles0_.CarrierId as CarrierId1_, ... FROM Vehicles vehicles0_ WHERE vehicles0_.CarrierId=@p0;@p0 = 4

UPDATE Vehicles SET CarrierId = null WHERE CarrierId = @p0;@p0 = 4

It's the line in bold that is causing the test to fail because I have a not null constraint on carrier (see vehicle mapping).

This is what I don't understand, if I have a not-null constraint, why does NHibernate try and insert null into the column.

So what do I need to do to ensure that deleting a carrier, deletes all vehicles?

Thanks, Ben

A: 

After all this, the problem ended up being a typo in one of the other sets defined on the parent object. It was only through trying a few more specific tests that I found I was trying to cast a collection to the wrong type - doh!

So basically, if you use the mapping above then the deletes will cascade (providing you don't make silly typos :))

Ben