Hi I use Fluent NHibernate and I am little confusing with Lazy Loading.
- I queried object in database
- modified object properties
- update database with this object
Here is code:
public class Credentials
{
public virtual int Id { get; set; }
public virtual string Nick { get; set; }
public virtual string Password { get; set; }
}
public class CredentialsMap : ClassMap<Credentials>
{
public CredentialsMap()
{
Id(x => x.Id);
Map(x => x.Nick).Column("NICK");
Map(x => x.Password).Column("PASSWORD");
Table("R_CREDENTAILS");
}
}
public class Status
{
public virtual int Id { get; set; }
public virtual string Msg { get; set; }
public virtual DateTime AddTime { get; set; }
}
public class StatusMap : ClassMap<Status>
{
public StatusMap()
{
Id(x => x.Id);
Map(x => x.Msg).Column("MESSAGE");
Map(x => x.AddTime).Column("ADD_TIME");
Table("R_STATUS");
}
}
public class Account
{
public virtual int Id { get; set; }
public virtual string SelfNick { get; set; }
public virtual Credentials Credentials { get; set; }
public virtual Status Status { get; set; }
}
public class AccountMap : ClassMap<Account>
{
public AccountMap()
{
Id(x => x.Id);
Map(x => x.SelfNick).Column("SELF_NICK");
References(x => x.Credentials)
.Column("CREDENTIALS_ID")
.ForeignKey();
References(x => x.Status)
.Column("STATUS_ID")
.ForeignKey();
Table("R_ACCOUNTS");
}
}
NHibernate configuration class:
public class NHiberanteHelper
{
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
InitializeSessionFactory();
return _sessionFactory;
}
}
private static void InitializeSessionFactory()
{
_sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(
@"Server=TEST\SQLEXPRESS;Database=SimpleNHibernate;Trusted_Connection=True;").
ShowSql()
)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Account>().Conventions.Add( DefaultCascade.All()))
.ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(true, true))
.BuildSessionFactory();
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
}
Here is usage:
public class LoginDbHelper
{
public static Account GetAccount(string nick)
{
using (var session = NHiberanteHelper.OpenSession())
{
var account = (session.QueryOver<Account>()
.JoinQueryOver<Credentials>(a => a.Credentials)
.Where(c => c.Nick == nick));
if (account != null)
return account.SingleOrDefault();
return null;
}
}
public static void SaveOrUpdateAccount(Account account)
{
using (var session = NHiberanteHelper.OpenSession())
{
using (var trans = session.BeginTransaction())
{
session.SaveOrUpdate(account);
trans.Commit();
}
}
}
}
Problem code:
var actualAccount = LoginDbHelper.GetAccount(nick);
//modify
actualAccount.Status.Msg = "New status 2";
actualAccount.Status.AddTime = DateTime.Now;
LoginDbHelper.SaveOrUpdateAccount(account);
I get this error:
{"Initializing[NHibernateSample1.Status#1]-Could not initialize proxy - no Session."}
StackTrace:
at NHibernate.Proxy.AbstractLazyInitializer.Initialize() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Proxy\AbstractLazyInitializer.cs:line 113
at NHibernate.Proxy.AbstractLazyInitializer.GetImplementation() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Proxy\AbstractLazyInitializer.cs:line 191
at NHibernate.ByteCode.Castle.LazyInitializer.Intercept(IInvocation invocation) in d:\CSharp\NH\NH\nhibernate\src\NHibernate.ByteCode.Castle\LazyInitializer.cs:line 61
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.StatusProxy.set_Msg(String value)
at NHibernateSample1.Program.Main(String[] args) in E:\C# PROJECTS\Samples\SimpleNHibernateClient\NHibernateSample1\Program.cs:line 215
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
I google it and I think It cause by Lazy Loading because in method GetAccount I close SESSION. It is my first attempt with NHibernate so HOW CAN SOLVE THIS PROBLEM CORRECTLY? It is possible disable LAZY LOADING if YES how to do it?
Session management to support lazy loading is one of the big pain points with NHibernate, in my experience.
totally agree with you. feeling like why did i choose nhibernate, should have gone with EF – Electrolyze