Search code examples
c#sqlnhibernatefluent-nhibernatefluent-nhibernate-mapping

Getting duplicates when testing "one-to-many" relationship?


I'm running into some issues testing Fluent NHibernate's persistence. I'm not sure if this is simply poor understanding on my part or improper expectations of the test. If so, does anyone have any advice on how best to set up a Unit Test for this part of the DAL?

I have a pair of classes Client and Facility with a one-to-many relationship:

One: Client can have Many Facility

Using this FluentNHibernate's mapping structure, I'd expected they should look like this:

public class ClientMapping : DataMapping<Client>
{
    public ClientMapping()
    {
        HasMany(client => client.Facilities)
            .Inverse()
            .Cascade
            .All();
    }
}

public class FacilityMapping : DataMapping<Facility>
{
    public FacilityMapping()
    {
        References(fac => fac.Owner);
    }
}

I followed FNH's advice on creating tests such as below but when running it- I get a Client table with 2 Clients and a Facility table with two different Ids, even though I'm passing in a single object.

    [Test]
    public void CanCorrectlyCreateFacilityTable()
    {
        _client = new Client {Name = "Preston"};

        new PersistenceSpecification<Facility>(session, new DataEqualityComparer())
            .CheckProperty(f => f.Id, 1)
            .CheckProperty(f => f.Name, _facility1.Name)
            .CheckReference(f => f.Owner, _client)
            .VerifyTheMappings();

        new PersistenceSpecification<Facility>(session, new DataEqualityComparer())
            .CheckProperty(f => f.Id, 2)
            .CheckProperty(f => f.Name, _facility2.Name)
            .CheckReference(f => f.Owner, _client)
            .VerifyTheMappings();

    }

Client Table

Facility Table

Closest q/a I've found is those below but even when running the Client test first, I seem to get the same result (likely because the database state resets itself for each test):

Cascade persist creates duplicate rows? Hibernate - one to Many relationship


Solution

  • It turns out my expectations were incorrect. The Persistence Specification test simply tests where data hits the database - hence, it'll send new items each time it's run.

    To test whether the mappings are cascading data correctly I needed to write a test like below:

        [Test]
        public void CanSaveAndLoadFacilityMapping()
        {
            object id;
            object id2;
    
            using (var trans = _session.BeginTransaction())
            {
                id = _session.Save(_facility1);
                id2 = _session.Save(_facility2);
    
                trans.Commit();
            }
    
            _session.Clear();
    
            using (var trans = _session.BeginTransaction())
            {
                var facility = _session.Get<Facility>(id);
                var facility2 = _session.Get<Facility>(id2);
    
                Assert.AreEqual(facility.Name, _facility1.Name);
                Assert.AreEqual(facility.Owner.Name, _client.Name);
                Assert.AreEqual(facility2.Owner.Name, _client.Name);
                Assert.AreEqual(facility.Owner.Id, facility2.Owner.Id);
    
                trans.Dispose();
            }
        }