Trying to insert a record into a table using nhibernate and fluent.
Script to create the table is as follows
Use [my_lives]
Go
IF Exists(Select * From sys.objects Where object_id = OBJECT_ID(N'[dbo].[tblProfiles]') and Type In (N'U'))
Begin
Drop Table [dbo].[tblProfiles]
End
Go
CREATE TABLE [dbo].[tblProfiles](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Network] [nvarchar](50) NULL,
[NetworkId] [nvarchar](50) NULL,
[Email] [nvarchar](255) NULL,
[Name] [nvarchar](60) NULL,
[GivenName] [nvarchar](50) NULL,
[FamilyName] [nvarchar](50) NULL,
[Picture] [nvarchar](255) NULL,
[DOB] [datetime] NULL,
[RelationshipStatus] [nvarchar](10) NULL,
[Gender] [nvarchar](10) NULL,
CONSTRAINT [PK_tblProfiles] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Mapping is as follows;
using FluentNHibernate.Mapping;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YourLivesDataEngine.DataObjects;
namespace YourLivesDataEngine.Mappings
{
public class ProfileMap
: ClassMap<Profile>
{
public ProfileMap()
{
Table("tblProfiles");
Id(x => x.Id).GeneratedBy.Identity(); ;
Map(x => x.Email);
Map(x => x.FamilyName);
Map(x => x.Gender);
Map(x => x.GivenName);
Map(x => x.Id);
Map(x => x.Name);
Map(x => x.Network);
Map(x => x.NetworkId);
Map(x => x.Picture);
}
}
}
The profile object is defined as such
public class Profile
{
public virtual long Id { get; set; }
public virtual String Network { get; set; }
public virtual String NetworkId { get; set; }
public virtual String Email { get; set; }
public virtual String Name { get; set; }
public virtual String GivenName { get; set; }
public virtual String FamilyName { get; set; }
public virtual String Picture { get; set; }
public virtual String Gender { get; set; }
}
and finally the code to insert the profile
public long Insert ( Profile Profile)
{
ISessionFactory factory = null;
factory = CreateSessionFactory();
try
{
using (var session = factory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Save(Profile);
transaction.Commit();
}
}
}
catch (Exception e)
{
throw e;
}
return SelectByNetworkId(Profile.Network,Profile.NetworkId).Id;
} // end Insert Procedure
the trouble is when it gets to the Save session.Save(Profile) I am getting a null exception. None of the properties are null and the session has a value, as does the transaction - but cannot see why I am getting a null exception.
Sure I am doing something daft as I have written code like this hundreds of times but cannot see it.
Stack trace of the error is as follows;
at NHibernate.Engine.EntityKey..ctor(Object identifier, String rootEntityName, String entityName, IType identifierType, Boolean batchLoadable, ISessionFactoryImplementor factory, EntityMode entityMode)
at NHibernate.Engine.EntityKey..ctor(Object id, IEntityPersister persister, EntityMode entityMode)
at NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
at NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.Save(Object obj)
at YourLivesDataEngine.DataTables.Profiles.Insert(Profile Profile) in C:\Users\Paul\Documents\Visual Studio 2015\Projects\YourLives\YourLivesDataEngine\DataTables\Profiles.cs:line 46
Steven Manuel is correct, the answer lies in the mapping definition. ID appears both in the call to ID and the call to Map.
I've made some other changes to get it working. NetworkId would be unique within a network, so used that. This will be OK until I add some other networks, at which point I will need to find some way of defining a combined Id between NetworkId and Network.