I'm using an nHibernate stateless session to fetch an object, update one property and save the object back to the database.
I keep getting the error message:
proxies cannot be fetched by a stateless session
I have similar code working elsewhere, so I can't figure out why this isn't working. Does anyone have any idea what the problem might be?
I'm trying to update the ScreenLockVersion
property.
Mapping:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="ApplicationUtilities"
namespace="ApplicationUtilities.Concurrency">
<class name="Screen" table="concurrency_screen" dynamic-update="true" optimistic-lock="all">
<id name="ID" column="screenID">
<generator class="identity" />
</id>
<property name="ScreenName" column="screenName" />
<property name="SubScreenName" column="subScreenName" />
<property name="ScreenLockID" column="screenLockID" />
<property name="ScreenLockVersion" column="screenLockVersion" />
<property name="ScreenLockRequired" column="screenLockRequired" />
<many-to-one name="Parent" class="Screen" column="parentScreenID" />
<many-to-one name="Identity" class="ApplicationUtilities.SystemIdentity.Identity" column="identityID" />
<many-to-one name="Application" class="ApplicationName" column="applicationID" />
<one-to-one name="LastModified" class="LastModified" property-ref="Screen" cascade="all" />
<bag name="AffectedScreens" table="concurrency_affectedScreen" cascade="all">
<key column="updatedScreenID" />
<many-to-many column="affectedScreenID" class="Screen" />
</bag>
<bag name="ChildScreens" table="concurrency_screen">
<key column="parentScreenID" />
<many-to-many column="screenID" class="Screen" />
</bag>
</class>
</hibernate-mapping>
Code:
public class Screen : BaseDomain
{
private string screenName;
private string subScreenName;
private Screen parent;
private IList<Screen> childScreens = new List<Screen>();
private IList<Screen> affectedScreens = new List<Screen>();
private Guid screenLockID;
private int screenLockVersion;
private bool screenLockRequired;
private LastModified lastModified;
private Identity identity;
private ApplicationName application;
protected Screen()
{
this.parent = null;
this.screenLockRequired = false;
}
/// <summary>
/// Create new parent screen
/// </summary>
/// <param name="screenName">parent screenname</param>
public Screen(string screenName, ApplicationName application)
{
this.screenName = screenName;
this.subScreenName = null;
this.parent = null;
this.application = application;
}
/// <summary>
/// Create new subscreen
/// </summary>
/// <param name="screenName">parent screen name</param>
/// <param name="subScreenName">subscreen name</param>
/// <param name="parent">reference to parent screen</param>
public Screen(string screenName, string subScreenName, Screen parent, ApplicationName application)
{
this.screenName = screenName;
this.subScreenName = subScreenName;
this.application = application;
this.parent = parent;
}
#region Properties
public virtual IList<Screen> AffectedScreens
{
get { return affectedScreens; }
set { affectedScreens = value; }
}
public virtual Screen Parent
{
get { return parent; }
set { parent = value; }
}
public virtual IList<Screen> ChildScreens
{
get { return childScreens; }
set { childScreens = value; }
}
public virtual string ScreenName
{
get { return screenName; }
set { screenName = value; }
}
public virtual string SubScreenName
{
get { return subScreenName; }
set { subScreenName = value; }
}
public virtual Guid ScreenLockID
{
get { return screenLockID; }
set { screenLockID = value; }
}
public virtual int ScreenLockVersion
{
get { return screenLockVersion; }
set { screenLockVersion = value; }
}
public virtual bool ScreenLockRequired
{
get
{
if (parent != null)
return parent.ScreenLockRequired;
else
return screenLockRequired;
}
set { screenLockRequired = value; }
}
public virtual LastModified LastModified
{
get { return lastModified; }
set { lastModified = value; }
}
protected internal virtual Identity Identity
{
get { return identity; }
set { identity = value; }
}
public virtual ApplicationName Application
{
get { return application; }
set { application = value; }
}
#endregion
#region Methods
public override string ToString()
{
return ScreenName + SubScreenName;
}
public override bool Equals(object obj)
{
Screen other = obj as Screen;
if (other == null)
return false;
if (string.IsNullOrEmpty(SubScreenName))
{
if(string.IsNullOrEmpty(other.SubScreenName))
return ScreenName.Equals(other.ScreenName) && Application.Equals(other.Application);
else
return false;
}
else if (string.IsNullOrEmpty(other.SubScreenName))
return false;
else
return ScreenName.Equals(other.ScreenName) && SubScreenName.Equals(other.SubScreenName) && Application.Equals(other.Application);
}
public override int GetHashCode()
{
if(SubScreenName == null)
return ScreenName.GetHashCode() ^ Application.GetHashCode();
else
return ScreenName.GetHashCode() ^ SubScreenName.GetHashCode() ^ Application.GetHashCode();
}
#endregion
}
Stateless sessions do not support lazy-loading. You need to load your Screen
entities early (in the same query you are currently loading only the proxies).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With