Question

I'm trying to implement the Strategy Pattern with Fluent Nhibernate, inspired by this blog post

public abstract class Strategy
{
    protected Strategy() { }
    protected Strategy(Guid id) { this.Id = id; }
    public virtual Guid Id { get; set; }
    public abstract void SomeMethod();
}

public class MyStrategy : Strategy
{
    public MyStrategy() : base(new Guid("F1CF041B ...")) { }
    public override void SomeMethod() { }
}

public class StrategyMap : ClassMap<Strategy>
{
    public StrategyMap()
    {
        this.Id(x => x.Id).GeneratedBy.Assigned();
        this.DiscriminateSubClassesOnColumn("Id");
    }
}

public class MyStrategyMap : SubclassMap<MyStrategy>
{
    public MyStrategyMap()
    {
        this.DiscriminatorValue("F1CF041B ...");
    }
}

But when I run the following test (where this.Session is from a in-memory-database):

[TestMethod]
public void CanGetMyStrategy()
{
    // Arrange
    using (var transaction = this.Session.BeginTransaction())
    {
        this.Session.Save(new MyStrategy());
        transaction.Commit();
        this.Session.Clear();
    }

    // Act
    var strategies = this.Session.Query<Strategy>();

    // Assert
    Assert.IsNotNull(strategies.FirstOrDefault());
}

The following exception is thrown:

NHibernate.WrongClassException: 
  Object with id: f1cf041b ... 
  was not of the specified subclass: Namespace.Strategy 
  (Discriminator was: 'f1cf041b ...')

Any help debugging this issue would be appreciated as I can't figure out why this doesn't work.


Unsatifactory solution

I can get the code to work by not discriminating on the Id column (and so creating another column to discriminate on), but I find this unsatisfactory as it means duplicating data.


Why Guid?

The reasoning behind this is that new Strategys will be able to be created via a plugin architecture (providing an implementation of Strategy and SubclassMap<[strategy-name]> which get read at application load), and as such I need to use Guids so there aren't conflicts with Ids.

Was it helpful?

Solution

Seems that in Strategy class you are using Id of type Guid but in mapper class string instead of Guid is used.

I changed map class as described below, and exception ceased to appear

public class MyStrategyMap : SubclassMap<MyStrategy>
{
    public MyStrategyMap()
    {
        this.DiscriminatorValue(new Guid("F1CF041B ..."));
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top