views:

20

answers:

1

I'm trying to get Fluent NHibernate to map a collection for me. My class definitions are as follows:

public abstract class Team 
{
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
}

public class ClientTeam : Team
{
    public virtual IEnumerable<Client> Clients { get; set; }
}

public class Client
{
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Identifiers { get; set; }
}

My mappings:

public class TeamMap : ClassMap<Team>
{
    public TeamMap()
    {
        Table("Team");
        Id(x => x.Id).GeneratedBy.Assigned();
        Map(t => t.TeamName);
    }
}

public class ClientTeamMap : SubclassMap<ClientTeam>
{
    public ClientTeamMap()
    {
        HasMany(t => t.Clients);
    }
}

public class ClientMap : ClassMap<Client>
{
    public ClientMap()
    {
        Table("Client");
        Id(c => c.Id);
        Map(c => c.Name);
        Map(c => c.Identifiers);
    }
}

I've built a unit test that instantiates a team and then attempts to persist it (the test base has dependency configuration, etc. in it):

public class TeamMapTester : DataTestBase
{
    [Test]
    public void Should_persist_and_reload_team()
    {
        var team = new ClientTeamDetail
        {
            Id = Guid.NewGuid(),
            TeamName = "Team Rocket",
            Clients = new[] 
            {
                new ClientDetail {ClientName = "Client1", ClientIdentifiers = "1,2,3"}
            }
        };

        using (ISession session = GetSession())
        {
            session.SaveOrUpdate(team);
            session.Flush();
        }

        AssertObjectWasPersisted(team);
    }
}

When I run the test, I get this error:

SetUp : FluentNHibernate.Cfg.FluentConfigurationException : An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.

  • Database was not configured through Database method.

----> NHibernate.MappingException: Could not compile the mapping document: (XmlDocument)
----> NHibernate.PropertyNotFoundException : Could not find field '_clients' in class 'ClientTeam'`

I've looked through the NHibernate documentation and done some google searching, but I can't find anything that appears to address this issue. The documentation for Fluent NHibernate's Referencing methods explicitly uses auto properties, so I'm sure that's not the issue.

Why might NHibernate think that _clients is the field it should map in this case?

A: 

And the reason turns out to be: Conventions.

The Fluent mappings were set up to try to enforce read-only collection properties, by requiring a backing field. The ICollectionConvention in question:

public class CollectionAccessConvention : ICollectionConvention
{
    public void Apply(ICollectionInstance instance)
    {
        instance.Fetch.Join();
        instance.Not.LazyLoad();
        instance.Access.CamelCaseField(CamelCasePrefix.Underscore);
    }
}

which requires that collection backing fields be camelCased and start with an underscore.

arootbeer