Hello,
I've got a problem using detached Objects and versioning. As I'm
starting to use NHibernate for Windows Forms Applications this would
be my favorite approach, since it seems to be the most fitting for me.
Basic flow should be:
1. Get an Object out of a Session
2. Close Session
3. Work with the detached object
4. call session.Update() to persist changes
5. Optional: If stalestateexception occurs do something
my class:
public class SignalList
{
#region Fields
Decimal _signalListId;
String _description;
SignalCollection _signals;
int _nhVersion;
#endregion
#region Constructors
public SignalList()
{
Initialise();
}
#endregion
#region Internal
protected virtual void Initialise()
{
_description = "";
_signals = new SignalCollection(this);
}
#endregion
#region Public Properties
public virtual Decimal SignalListId
{
get { return _signalListId; }
protected set { _signalListId = value; }
}
public virtual String Description
{
get { return _description; }
set { _description = value; }
}
public virtual SignalCollection Signals
{
get { return _signals; }
protected set { _signals = value; }
}
protected virtual int NhVersion
{
get { return _nhVersion; }
set { _nhVersion = value; }
}
#endregion
}
The Mapping:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="SignalList.Domain" namespace="SignalListManager.Domain">
<class name="SignalList" table="SL_SIGNALLIST" lazy="false"
optimistic-lock="version" >
<id name="SignalListId" column="ID_SIGNALLIST" type="Decimal">
<generator class="sequence">
<param name="sequence">SL_SIGNALLIST_SEQ</param>
</generator>
</id>
<version column="NH_VERSION" name="NhVersion" />
<property name="Description" type="String" column="DESCRIPTION" />
<component class="SignalCollection" name="Signals">
<many-to-one class="SignalList" name="SignalList"
column="CollectionSignalList" foreign-
key="fk_ColSignalList_SignalList"/>
<bag name="Signals" table="SL_SIGNAL" lazy="false" cascade="all"
inverse="true">
<key column="ID_SIGNALLIST" />
<one-to-many class="Signal" />
</bag>
</component>
</class>
</hibernate-mapping>
The Collection looks like this:
public class SignalCollection : IList<Signal>, ICollection
{
#region Fields
SignalList _signalList;
IList<Signal> _signals;
#endregion
#region Constructors
SignalCollection()
{
_signalList = null;
_signals = new List<Signal>();
}
public SignalCollection(SignalList signalList)
{
_signalList = signalList;
_signals = new List<Signal>();
}
#endregion
#region Internal
public void AddInternal(Signal item)
{
if (!_signals.Contains(item))
{
item.SignalList = _signalList;
_signals.Add(item);
}
}
public bool RemoveInternal(Signal item)
{
if (_signals.Contains(item))
{
item.SignalList = null;
_signals.Remove(item);
return true;
}
return false;
}
protected virtual IList<Signal> Signals
{
get { return _signals; }
set { _signals = value; }
}
protected virtual SignalList SignalList
{
get { return _signalList; }
set { _signalList = value; }
}
#endregion
//IList<Signal> Implementation
}
The Dal:
public void Insert(SignalList signalList)
{
using (ISession session = SessionFactory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
try
{
session.SaveOrUpdate(signalList);
transaction.Commit();
}
catch (Exception ex)
{
throw new Exception("Error saving to DB", ex);
}
}
}
}
public void Update(SignalList signalList)
{
using (ISession session = SessionFactory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
try
{
session.Update(signalList);
transaction.Commit();
}
catch (StaleStateException ex)
{
throw new Exception("StaleStateException");
}
catch (Exception ex)
{
throw new Exception("Error saving to DB", ex);
}
}
}
}
The Problem is:
I first create an SignalList list1 and add some signals. I call
Dal.Insert(list1);
Everything works fine. All objects are persisted to db and the version
is 1.
Now I simulate another User changing the object. Directly in the DB I
set the Version to 10.
Now I change something in my Object in the program e.g.
list1.Description = "New Description";
The Object is dirty now.
I call Dal.Update(list1);
And that's the part where I don't understand NHibernate. Normally I
should get an StaleStateException, because the In-Memory State of the
Object doesn't match the DB State ( 1 <-> 10 )
But NHibernate just updates the in-memory objects and performs the
changes on the newly fetched objects. So now the Version of list1 is
11 instead of getting a StaleStateException.
My NHibernate.cfg.xml:
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property
name="connection.provider">NHibernate.Connection.DriverConnectionProvider</
property>
<property name="dialect">NHibernate.Dialect.OracleDialect</property>
<property
name="connection.driver_class">NHibernate.Driver.OracleClientDriver</
property>
<property name="connection.connection_string">some connection String</
property>
<property name="show_sql">true</property>
</session-factory>
</hibernate-configuration>
Another question I have is: Does Update always call Updates for all
childs if cascading is enabled, even if none of the childs has
changed?
Thanks for your help =)
Greetings,
Florian Fanderl
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en
-~----------~----~----~----~------~----~------~--~---