Bunnynut
Bunnynut

Reputation: 1328

NHibernate MappingException: persistent class TodoLog not found

I have two classes Todo and TodoLog that I have created mapping for and some unittests for their respective constructors. When I run these tests I receive the error Could not load type TodoLog. Possible cause no assembly name specified with the innerexception MappingException: persistent class TodoLog not found. The error always refers to TodoLog even when I run the test for the Todo constructor. The mapping for both classes are rather straightforward.

Mapping for Todo:

[Class(NameType = typeof()Todo, Table = "Todo")]
public class Todo
{
    [Id(-2, Name = "Id")]
    [Generator(-1, Class = "native")]
    public virtual long Id { get; set; }

    [Property]
    public virtual string Title { get; set; }

    [Property]
    public virtual Guid TodoGuid { get; set; }

    private IList<TodoLog> logs = new List<TodoLog>();
    [Bag(0, Name = "Logs", Table = "TodoLog", Inverse = true)]
    [Key(1, Column = "Todo")]
    [OneToMany(2, ClassType = typeof(TodoLog)]
    public virtual IEnumerable<TodoLog> Logs
    {
        get => logs;
        protected set => log = (IList<TodoLog>)value;
    }
}

Mapping for TodoLog

[Class(NameType = typeof(TodoLog), Name = "TodoLog")]
public class TodoLog
{
    [Id(-2, Name = "Id")]
    [Generator(-1, Class = "native")]
    public virtual long Id { get; set; }

    [ManyToOne]
    public virtual Todo Todo { get; set; }

    [Property]
    public virtual Enums.TodoAction Action { get; set; }

    [ManyToOne]
    public virtual User ExecutedBy { get; set; }

    [Property]
    public virtual DateTime ExectutedOn { get; set; }
}

======== EDIT ========

When I put all the code of TodoLog in comment the tests run fine but as soon as I add the Class-attribute to TodoLog I receive the same error as before. Removing TodoLog completely and adding a different class TodoTest results in the same error for TodoTest. I have also used .Net Reflector to check wether that class compiled correctly but everything seems fine there.

When debugging the code when I run the test the error occurs loading the assembly which contains TodoLog:

foreach(var a in projectsAssemblies)
{
    Configuration.AddInputStream(HbmSerializer.Default.Serialize(a));
}

When viewing the property ExportedTypes of the assembly which contains TodoLog the TodoLog class is in that list.

Upvotes: 1

Views: 691

Answers (1)

Radim K&#246;hler
Radim K&#246;hler

Reputation: 123901

The issue, I'd say, would be in the doubled NAME mapping:

[Class(NameType = typeof(TodoLog), Name = "TodoLog")]

We should use either

  1. NameType or
  2. Name

Because as we can see in the (source) - NameType is at the end filling the Name:

    public virtual string Name
    {
        get
        {
            return this._name;
        }
        set
        {
            this._name = value;
        }
    }
    
    /// <summary> </summary>
    public virtual System.Type NameType
    {
        get
        {
            return System.Type.GetType( this.Name );
        }
        set
        {
            if(value.Assembly == typeof(int).Assembly)
                this.Name = value.FullName.Substring(7);
            else
                this.Name = HbmWriterHelper.GetNameWithAssembly(value);
        }
    }

So, where is the problem?

While in the Log mapping we use just NameType

[Class(NameType = typeof()Todo, Table = "Todo")]

the value of the Name is correct... meaning, with full name

Name = "MyNamespace.TodoLog, MyAssembly"

while int TodoLog ..

Name = "TodoLog"

And that is the source of the exception:

Could not load type TodoLog.

MappingException: persistent class TodoLog not found

Because we need MyNamespace.TodoLog, MyAssembly

NOTE: mostlikely the Name should have been Table [Class(NameType = typeof(TodoLog), Table = "TodoLog")]

Upvotes: 1

Related Questions