Marcel Höll Marcel Höll - 4 months ago 30
C# Question

Type conversion exception while using NHibernate

I've got the following persistence class with the corresponding XML mapping file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataAccessLayer.Poco
{
public class User
{
private int id;
private int positionId;
private int companyId;
private int roleId;
private int languageId;
private string firstname;
private string firstnameUpperCase;
private string lastname;
private string initials;
private string pseudonyms;
private string mail;
private string phone;
private string mobile;
private bool managementFlag;
private bool activityFlag;
private string information;
private string image;
private string path;

public User()
{

}

public virtual int Id
{
get { return id; }
set { id = value; Console.WriteLine("setter Id");}
}

public virtual int PositionId
{
get { return positionId; }
set { positionId = value; Console.WriteLine("setter PositionId"); }
}

public virtual int CompanyId
{
get { return companyId; }
set { companyId = value; Console.WriteLine("setter CompanyId"); }
}

public virtual int RoleId
{
get { return roleId; }
set { roleId = value; Console.WriteLine("setter RoleId"); }
}

public virtual int LanguageId
{
get { return languageId; }
set { languageId = value; Console.WriteLine("setter LanguageId"); }
}

public virtual string Firstname
{
get { return firstname; }
set { firstname = value; Console.WriteLine("setter Firstname"); }
}

public virtual string FirstnameUpperCase
{
get { return firstnameUpperCase; }
set { firstnameUpperCase = value; Console.WriteLine("setter FirstnameUpperCase"); }
}

public virtual string Lastname
{
get { return lastname; }
set { lastname = value; Console.WriteLine("setter Lastname"); }
}

public virtual string Initials
{
get { return initials; }
set { initials = value; Console.WriteLine("setter Initials"); }
}

public virtual string Pseudonyms
{
get { return pseudonyms; }
set { pseudonyms = value; Console.WriteLine("setter Pseudonyms"); }
}

public virtual string Mail
{
get { return mail; }
set { mail = value; Console.WriteLine("setter Mail"); }
}

public virtual string Phone
{
get { return phone; }
set { phone = value; Console.WriteLine("setter Phone"); }
}

public virtual string Mobile
{
get { return mobile; }
set { mobile = value; Console.WriteLine("setter Mobile"); }
}

public virtual bool ManagementFlag
{
get { return managementFlag; }
set { managementFlag = value; Console.WriteLine("setter ManagementFlag"); }
}

public virtual bool ActivityFlag
{
get { return activityFlag; }
set { activityFlag = value; Console.WriteLine("setter activityFlag"); }
}

public virtual string Information
{
get { return information; }
set { information = value; Console.WriteLine("setter information"); }
}

public virtual string Image
{
get { return image; }
set { image = value; Console.WriteLine("setter image"); }
}

public virtual string Path
{
get { return path; }
set { path = value; Console.WriteLine("setter path"); }
}
}
}


And the XML file:






<many-to-one name="CompanyId"
unique="true"
class="Company">
<column name="companyId" />
</many-to-one>

<many-to-one name="PositionId"
unique="true"
class="Position">
<column name="positionId" />
</many-to-one>

<many-to-one name="RoleId"
unique="true"
class="Role">
<column name="roleId" />
</many-to-one>

<many-to-one name="LanguageId"
unique="true"
class="Language">
<column name="languageId" />
</many-to-one>

<property name="Firstname" column="firstname" type="String" />
<property name="FirstnameUpperCase" column="firstnameUpperCase" type="String" />
<property name="Lastname" column="lastname" type="String" />
<property name="Initials" column="initials" type="String" />
<property name="Pseudonyms" column="pseudonyms" type="String" />
<property name="Mail" column="mail" type="String" />
<property name="Phone" column="phone" type="String" />
<property name="Mobile" column="mobile" type="String" />
<property name="ManagementFlag" column="managementFlag" type="Boolean" />
<property name="ActivityFlag" column="activityFlag" type="Boolean" />
<property name="Information" column="information" type="String" />
<property name="Image" column="image" type="String" />
<property name="Path" column="path" type="String" />





Each time, I want to read a User object from the MySQL database, I get the following Exception:

NHibernate.PropertyAccessException: Invalid Cast (check your mapping for property type mismatches); setter of DataAccessLayer.Poco.User ---> System.InvalidCastException: Die angegebene Umwandlung ist ung├╝ltig.
bei (Object , Object[] , SetterCallback )
bei NHibernate.Bytecode.Lightweight.AccessOptimizer.SetPropertyValues(Object target, Object[] values)
bei NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValuesWithOptimizer(Object entity, Object[] values)
--- Ende der internen Ausnahmestapel├╝berwachung ---
bei NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValuesWithOptimizer(Object entity, Object[] values)
bei NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValues(Object entity, Object[] values)
bei NHibernate.Persister.Entity.AbstractEntityPersister.SetPropertyValues(Object obj, Object[] values, EntityMode entityMode)
bei NHibernate.Engine.TwoPhaseLoad.InitializeEntity(Object entity, Boolean readOnly, ISessionImplementor session, PreLoadEvent preLoadEvent, PostLoadEvent postLoadEvent)
bei NHibernate.Loader.Loader.InitializeEntitiesAndCollections(IList hydratedObjects, Object resultSetId, ISessionImplementor session, Boolean readOnly)
bei NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies, IResultTransformer forcedResultTransformer)
bei NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies, IResultTransformer forcedResultTransformer)
bei NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters, IResultTransformer forcedResultTransformer)
bei NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters)
bei NHibernate.Loader.Loader.List(ISessionImplementor'test.exe' (CLR v4.0.30319: test.exe):
session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes)
bei NHibernate.Loader.Hql.QueryLoader.List(ISessionImplementor session, QueryParameters queryParameters)
bei NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(ISessionImplementor session, QueryParameters queryParameters)
bei NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results)
bei NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results)
bei NHibernate.Impl.AbstractSessionImpl.List(IQueryExpression queryExpression, QueryParameters parameters)
bei NHibernate.Impl.AbstractQueryImpl2.List()
bei DataAccessLayer.Impl.UserDao.get(Int32 entityId)

Answer

The most obvious thing that stands out is that you need to review the many-to-one element again. The many-to-one element is used like this:

public class Foo {
    public Bar RelatedBar {get; set;}
}

public class Bar {
    public int BarId {get; set;}
}

Foo can then be mapped like this:

<many-to-one name="RelatedBar" class="Bar"><!-- class attribute is optional -->
    <column name="RelatedBarId" />
</many-to-one>

If you really want to have something like RelatedBarId in the Foo class, you would need to map it using the property-element, and NHibernate would then not know about the relationship.