views:

34

answers:

1

I'm facing the same issue others already posted on SO: On reading objects from the database, NHibernate would update all the objects because the value of one field is not proper in the DB.

(In detail: A newly added date column contains "1/1/0001" in all rows, so on mapping, NHibernate replaces the date and, on tx.Commit(), updates every single row.)

[Edit: It turned out that this was wrong. Instead, these date fields were null but would be updated to 1/1/0001 by NHibernate. See Diego's answer for details.]

To prevent that, I found this post with an answer by Ben Scheirman as well as the blog comment referred to by the OP.

The commenter Christian says:

You can also disable automatic dirty checking and updating by disabling the snapshots in Hibernate with session.setReadOnly(o, true) or for all queried objects with query.setReadOnly(true).

(Note that this blog post is about Java Hibernate.)

query.SetReadOnly(true) was successful where I used queries. However, I also have code like this:

ISession session = this.NHibernateHelper.SessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();

try
{
    BO resultBO = session.Get<BO>(id);

    tx.Commit();
    return resultBO;
}
catch (Exception ex)
{
    tx.Rollback();
    throw ex;
}
finally
{
    session.Close();
}

In this case I don't have a query, and the said Session.SetReadOnly(resultBO, true) does not exist in NHibernate. Where has it gone?

I guess "evict" is basically not a good idea because it makes the object transient so I can't use it to update values in another session (at least it gets more complicated. I would also need to make sure all objects are always evicted so my generic update methods wouldn't need to differentiate between persistent and transient objects - or am I completely wrong?

Thanks and cheers, chiccodoro

+3  A: 

You are attacking the symptom instead of the disease.

What you have there is a ghost (see http://jfromaniello.blogspot.com/2010/02/nhibernate-ghostbuster-version-11.html)

Make the property nullable and you'll be fine.

Diego Mijelshon
You hit the mark! I erred in saying that the column would contain "1/1/0001" dates. These seem actually to be written in by Hibernate. First they were indeed null. I changed the corresponding property to "DateTime?", now it works fine. -- Still, to fill my gap there: What would the Hibernate "Session.setReadOnly" look like in NHibernate?
chiccodoro
There is no full readonly setting in NHibernate, but you can set `Session.FlushMode = FlushMode.Never` and it won't flush anything to the DB unless you specifically tell it to.
Diego Mijelshon
Session.setReadOnly isn't a full readonly setting, it takes an entity as an argument and makes that entity readonly. Is there a way to achieve that in NHibernate?
chiccodoro
Only `Session.Evict`, which detaches the object from the session.
Diego Mijelshon