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

NHibernate / FluentNHibernate readonly compositeId


I'm trying to map 2 entities.

JournalEntry.cs

class JournalEntry
{
    private readonly IList<JournalEntryItem> _items;

    public JournalEntry()
    {
        _items = new List<JournalEntryItem>();
    }

    public IList<JournalEntryItem> Items
    {
        get { return _items; }
    }
}

JournalEntryItem.cs

class JournalEntryItem
{
    private readonly JournalEntry _journalEntry;
    private readonly Account _account;

    public JournalEntryItem(JournalEntry journalEntry, Account account)
    {
        _journalEntry = journalEntry;
        _account = account;
    }

    public JournalEntry JournalEntry
    {
        get { return _journalEntry; }
    }

    public Account Account
    {
        get { return _account; }
    }
}

JournalEntryItemMap.cs

class JournalEntryItemMap : ClassMap<JournalEntryItem>
{
    public JournalEntryItem()
    {
        CompositeId()
            .KeyReference(x => x.JournalEntry).Access.Field()
            .KeyReference(x => x.Account).Access.Field();

        // Tried this too, obviously won't work anyway
        // CompositeId()
        //    .KeyReference(x => x.JournalEntry).ReadOnly()
        //    .KeyReference(x => x.Account).ReadOnly();
    }
}

This mapping throws an exception :

Could not find a setter for property 'JournalEntry' in class Macsauto.Domain.Accounting.Entities.JournalEntryItem'

The only workaround I know of is to make a protected property.

Is there another workaround?

Update

Tried this but still not working:

JournalEntryItemMap.cs

class JournalEntryItemMap : ClassMap<JournalEntryItem>
{
    public JournalEntryItem()
    {
        CompositeId()
            .KeyReference(Reveal.Member<JournalEntryItem, JournalEntry>("_journalEntry")).Access.Field()
            .KeyReference(x => x.Account).Access.Field();
    }
}

Update I tried a method from FluentNHibernate wiki page, but even that produces the same error.

JournalEntryItem.cs

class JournalEntryItem
{
    // Removed the _ prefix just to make it even more similar with
    // those on FluentNHibernate wiki page
    private readonly JournalEntry journalEntry;

    public JournalEntryItem(JournalEntry journalEntry)
    {
        this.journalEntry = journalEntry;
    }

    public JournalEntry JournalEntry
    {
        get { return journalEntry; }
    }
}

JournalEntryItemMap.cs

class JournalEntryItemMap : ClassMap<JournalEntryItem>
{
    public JournalEntryItem()
    {
        CompositeId().KeyReference(x => x.JournalEntry).Access.CamelCaseField();

        // Other tried combinations, all throws same no setter error
        // CompositeId().KeyReference(x => x.JournalEntry).Access.ReadOnlyPropertyThroughCamelCaseField();
        // CompositeId().KeyReference(x => x.JournalEntry).Access.LowerCaseField();
    }
}

Now I'm getting curious, does it have to do with version issue?

I uses NHibernate 3.3.1.4000 and FluentNHibernate 1.4.0.0.

Does FluentNHibernate keep up with NHibernate? It's almost like NHibernate ignores any access type mapping I wrote in FluentNHibernate.


Solution

  • You could try using the CamelCaseField() access:

    CompositeId().KeyReference(x => x.JournalEntry).Access.CamelCaseField()
                 .KeyReference(x => x.Account).Access.CamelCaseField();
    

    Take a look at the documentation about mapping strategies.