user1408082
user1408082

Reputation:

nHibernate concurrency version not being updated when editing child bag or child property

I am using nHibernate (3.3.3GA) concurrency with the version tag in my parent mapping file.

1, When I update my child collection (.add or .remove) the parent version doesn't update.

2, When I update a property on a child entity the parent version doesn't update.

The only time I can get the parent version to update is when I edit a property on the parent entity itself.

Could someone take a look and see if there is something I am missing or doing wrong?

I have the following code:

Parent Class:

[DataContract]
public class Parent
{
  public Parent()
  {
    this.Id = -1;
    this.Children = new List<Child>();
  }

  [DataMember(Name = "Id")]
  public int Id { get; set; }

  [DataMember(Name = "Name")]
  public string Name { get; set; }

  [DataMember(Name = "Children")]
  public ILIst<Child> Children { get; set; }

  [DataMember(Name = "Deleted")]
  public bool Deleted { get; set; }

  [DataMember(Name = "Version")]
  public byte[] Version { get; set; }

  public override string ToString()
  {
    return this.Name;
  }
}

Child Class:

[DataContract]
public class Child
{
  public Child()
  {
    this.Id = -1;
  }

  [DataMember(Name = "Id")]
  public int Id { get; set; }

  [DataMember(Name = "Parent")]
  public Parent Parent { get; set; }

  [DataMember(Name = "Name")]
  public string Name { get; set; }

  [DataMember(Name = "Deleted")]
  public bool Deleted { get; set; }

  public override string ToString()
  {
    return this.Name;
  }
}

Parent Mapping:

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="TestApp.Entities" auto-import="false">

  <class name="TestApp.Entities.Parent" table="TestDb.dbo.ParentTable" dynamic-update="true" lazy="false" optimistic-lock="dirty">

    <id name="Id" column="ParentID" type="int" unsaved-value="-1">
      <generator class="native" />
    </id>

    <version name="Version" generated="always" type="BinaryBlob" unsaved-value="null">
      <column name="Version" sql-type="timestamp" not-null="false" />
    </version>

    <property name="Name" column="Name" />

    <bag name="Children" table="TestDb.dbo.ChildTable" lazy="false" inverse="true" where="Deleted = 0" fetch="join">
      <key column="ParentID" />
      <one-to-many class="TestApp.Entities.Child" />
    </bag>    

  </class>

</hibernate-mapping>

Child Mapping:

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="TestApp.Entities" auto-import="false">

  <class name="TestApp.Entities.Child" table="TestDb.dbo.ChildTable" dynamic-update="true" lazy="false">

    <id name="Id" column="ChildID" type="int" unsaved-value="-1">
      <generator class="native" />
    </id>

    <many-to-one name="Parent" class="TestApp.Entities.Parent" column="ParentID" cascade="none" fetch="join" />

    <property name="Name" column="Name" />

  </class>

</hibernate-mapping>

So next I edit the child collection within parent (.add or .remove) and hit save. Parent version doesn't update. Next I try editing child[0].Name and hit save, again parent version doesn't update.

I am using the following to save to the db:

public void Merge<T>(ref T entity) where T : class
{
  try
  {
    T updatedEntity = null;

    using (ISession session = this.SessionFactory.OpenSession())
    {
      using (session.BeginTransaction())
      {
        updatedEntity = (T)session.Merge(entity);

        session.Transaction.Commit();
      }
    }

    entity = updatedEntity;
  }
  catch (StaleObjectStateException sose)
  {
    throw sose;
  }
}

Can anyone spot the cause of why my parent version isn't updating when I edit my child collection?

many thanks

Upvotes: 1

Views: 1265

Answers (1)

user1408082
user1408082

Reputation:

Ok so with the help of Radim Kohler I have now fixed the problem.

Changing the 'version' column in the database from a timestamp to a datetime then altering the 'version' mapping as follows:

Before:

<version name="Version" generated="always" type="BinaryBlob" unsaved-value="null">
  <column name="Version" sql-type="timestamp" not-null="false" />
</version>

After:

<version name="LastUpdated" type="DateTime" unsaved-value="null">
  <column name="LastUpdated" sql-type="datetime" not-null="false" />
</version>

Has now solved the problem. Now when I update my child collection with an .Add() or .Remove() or I edit a property of 1 or more children within the collection my parent 'LastUpdated' property is updated.

Upvotes: 1

Related Questions