27

So everything is working well with the basic discriminator mapping. I can interact directly with entities A and B without any problems.

public class BaseType {}
public class EntityA : BaseType {}
public class EntityB : BaseType {}

This maps without drama in the BaseType mapping as

DiscriminateSubClassesOnColumn<string>("Type")
               .SubClass<BaseType>("A", m => { })
               .SubClass<BaseType>("B", m => { });

The problem occurs when: in an aggregate we want to map collections to each subclass

Using mapping like below

public class AggregateMap: BaseMap<Aggregate>
{
        public AggregateMap()
        {
                HasMany<EntityA>(x => x.ACollection).AsSet().Cascade.All();
                HasMany<EntityB>(x => x.BCollection).AsSet().Cascade.All();            
        }
}

These obviously arent full mappings but are the minimum amount to descibe what I am attempting. Items added to ACollection and BCollection are persisted correctly through the cascading when Aggregate is saved. However, when aggregate is retrieved there is confusion on the type discrimination.

I have run through so many different possible solutions I no longer know what didn't work. I feel that I shouldn't have to provide a where clause on the collections but things just aren't working for me.

Any clues would be appreciated.

Matteo B.
  • 3,906
  • 2
  • 29
  • 43
berko
  • 2,935
  • 4
  • 26
  • 31
  • By "confusion on the type discrimination", do you mean that both sets are returning all the types? Regardless of their discriminator? – James Gregory Jun 12 '09 at 07:44
  • I have left work now so can't remember the exact error. Something like 'Could not load entity of type EntityA because it does not match specified EntityB'. We hacked in a Where clause using a string on the HasMany mapping and that is filtering manually via the discriminator column. I just thought the the type would 'flow through' and the where decision would be performed automatically. – berko Jun 12 '09 at 07:58
  • And yes, to answer your question directly... I think it is attempting to load all of the types regardless of the discriminator. – berko Jun 12 '09 at 08:00
  • 1
    Have you managed to find a solution to this? We have had the exact same problem and the only work around we have found was to add a where clause to the mapping as you touched on. e.g. HasMany(x => x.ACollection).Where("[Type] = 'TypeA'").AsSet().Cascade.All(); Having to use a magic string like this seems less than ideal. – s1mm0t May 07 '10 at 19:53
  • I can also confirm this issue. Has anyone found a solution? – mxmissile Oct 14 '10 at 13:26
  • Do you know how to solve this with NHibernate HBM XML? If not, perhaps you can ask on the NHibernate users group? Either way, it would be fruitful if you could export your AutoPersistenceModel to HBM XML (`WriteMappingsTo()`) so they could be inspected. Perhaps FNH somehow is mapping both collections with the same type; if so, it's a bug in FNH. – Asbjørn Ulsberg Oct 27 '10 at 20:58
  • It seems to be **any** mapping. – Rail Oct 22 '10 at 08:55

1 Answers1

1

You mapping looks odd, in particular I think it should look more like this

DiscriminateSubClassesOnColumn<string>("Type")
               .SubClass<EntityA>("A", m => { })
               .SubClass<EntityB>("B", m => { });

Having said that it seems that method is depreciated and you should instead define the following (taken from Automapping Subclasses:

public class ParentMap : ClassMap<Parent>
{
  public ParentMap()
  {
    Id(x => x.Id);
    Map(x => x.Name);

    DiscriminateSubClassesOnColumn("type");
  }
}

public class ChildMap : SubclassMap<Child>
{
  public ChildMap()
  {
    Map(x => x.AnotherProperty);
  }
} 

Not sure this will fix it though, I am yet to encounter your scenario.

Edit: The issue is also raised here, sounding more like a bug to me

Iain
  • 10,814
  • 3
  • 36
  • 31