Question

I am trying to create my first nhibernate application. when i run program command window opens and database tables are created. however, transaction to insert new row to Team table fails with error "Invalid Cast (check your mapping for property type mismatches);" Error occurs in program.cs file in line session.Save(Team);. Could anyone help to find out why this happens? any help would be appreciated. Here's my code

Player.cs

namespace BDB.Entities
{
    public class Player
    {
        public virtual int Id { get; protected set; }
        public virtual string Name { get; set; }
        public virtual string Surname { get; set; }
        public virtual string Birthdate { get; set; }
        public virtual string Position { get; set; }
        public virtual int Salary { get; set; }
        public virtual Team Team { get; set; }
    }
}

PlayerMap.cs

namespace BDB.Mappings
{
    public class PlayerMap : ClassMap<Player>
    {
        public PlayerMap()
        {
            Id(x => x.Id);
            Map(x => x.Name);
            Map(x => x.Surname);
            Map(x => x.Birthdate);
            Map(x => x.Position);
            Map(x => x.Salary);
            References(x => x.Team);
        }
    }
}

Team.cs

namespace BDB.Entities
{
    public class Team
    {
        public virtual int Id { get; protected set; }
        public virtual string Country { get; set; }
        public virtual string City { get; set; }
        public virtual string Title { get; set; }
        public virtual string Website { get; set; }
        public virtual int Budget { get; set; }
        public virtual List<Player> Players { get; set; }
        public virtual List<Coach> Coaches { get; set; }

        public Team()
        {
            Players = new List<Player>();
            Coaches = new List<Coach>();
        }

        public virtual void AddPlayer(Player player)
        {
            player.Team = this;
            Players.Add(player);
        }

        public virtual void AddCoach(Coach coach)
        {
            coach.Team = this;
            Coaches.Add(coach);
        }

    }
}

TeamMap.cs

namespace BDB.Mappings
{
    public class TeamMap : ClassMap<Team>
    {
        public TeamMap()
        {
            Id(x => x.Id);
            Map(x => x.Country);
            Map(x => x.City);
            Map(x => x.Title);
            Map(x => x.Budget);
            Map(x => x.Website);
            HasMany(x => x.Players)
                .Inverse()
                .Cascade.All();
            HasMany(x => x.Coaches)
                .Inverse()
                .Cascade.All();
        }
    }
}

Coach.cs

namespace BDB.Entities
{
    public class Coach
    {
        public virtual int Id { get; protected set; }
        public virtual string Name { get; set; }
        public virtual string Surname { get; set; }
        public virtual int Experience { get; set; }
        public virtual int Salary { get; set; }
        public virtual Team Team { get; set; }
    }
}

CoachMap.cs

namespace BDB.Mappings
{
    public class CoachMap : ClassMap<Coach>
    {
        public CoachMap()
        {
            Id(x => x.Id);
            Map(x => x.Name);
            Map(x => x.Surname);
            Map(x => x.Experience);
            Map(x => x.Salary);
            References(x => x.Team);
        }
    }
}

SessionFactory.cs

namespace BDB
{
    public class SessionFactory
    {

        public static ISessionFactory ConfigureSystem()
        {
            var connString = "server=.\\SQLEXPRESS;database=litest;integrated security=SSPI;";
            var configuration = Fluently.Configure()
                .Database(MsSqlConfiguration
                .MsSql2008
                .ConnectionString(connString)
                    .ShowSql
                )
                .Mappings(m => m.FluentMappings
                .AddFromAssemblyOf<Team>()
                .AddFromAssemblyOf<Player>()
                .AddFromAssemblyOf<Coach>()) 
                .BuildConfiguration();

            var exporter = new SchemaExport(configuration);   
            exporter.Execute(true, true, false);
            ISessionFactory sessionFactory = configuration.BuildSessionFactory();
            return sessionFactory;
        }

    }
}

Program.cs

namespace BDB
{
    class Program
    {
        static void Main(string[] args)
        {
            ISessionFactory sessionFactory = SessionFactory.ConfigureSystem();

            using (var session = sessionFactory.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    Team Team = new Team { Country = "lt", City = "kau", Title = "Zal", Budget = 10000, Website = "www.kz.lt" };

                    session.Save(Team);
                    transaction.Commit();
                }
            }
            Console.ReadKey();
        }
    }
}
Was it helpful?

Solution

At first glance one thing that is incorrect is the declaration of the Players and Coaches properties:

public virtual List<Player> Players { get; set; }
public virtual List<Coach> Coaches { get; set; }

Problem is that they both use the concrete type List<>. NHibernate uses it's own collection types when managing your entities so it must be able to use those in addition to the raw list (as it uses collections that have the change tracking thing and so on). Change the declaration to those:

public virtual ICollection<Player> Players { get; set; }
public virtual ICollection<Coach> Coaches { get; set; }

Note that those interfaces still accept your List<> but also can contain the private NHibernate own collections.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top