Following your question regarding using the same Session I changed my
DAO methods Persist and Delete to Close the session:

public void Persist(T obj)
{
    using (ITransaction txn = nHibernateDB.Session.BeginTransaction())
    {
        try
        {
            nHibernateDB.Session.Persist(obj);
            txn.Commit();
        }
        catch
        {
            txn.Rollback();
            throw;
        }
        finally
        {
            nHibernateDB.CloseSession();
        }
    }
}

THIS HAS FIXED MY PROBLEM!!!


However I'm now wondering if my Session management is correct.  Does
the above look OK? Is this standard practice?

Should I be doing this for ALL data access methods???

Eg: I have a Get method as follows:

public T GetById(int id)
{
    return nHibernateDB.Session.Get<T>(id);
}


Should this also be using transactions and closing the Session when
it's done????

Thanks!

Paul


On May 11, 1:16 pm, robinsonpr <[email protected]> wrote:
> I don't know to be honest....the nHibernate DB class is already in
> existence in my organisation.  Here is the implementation of the
> Session property:
>
> public static nh.ISession Session
> {
>     get
>     {
>         nh.ISession session =
> (nh.ISession)CallContext.GetData(sessionGuid);
>
>         if (session == null)
>         {
>             session =
> nHibernateDB.GetNHibernateDB().SessionFactory.OpenSession();
>             CallContext.SetData(sessionGuid, session);
>         }
>
>         return session;
>     }
>
> }
>
> Is this not how Sessions should be handled?
>
> On May 11, 1:00 pm, Paco Wensveen <[email protected]> wrote:
>
>
>
>
>
> > I don't know what's wrong, but why do use reuse the session for
> > multiple transactions?
>
> > On Tue, May 11, 2010 at 1:25 PM, robinsonpr <[email protected]> wrote:
> > > Hi,
>
> > > I have a strange error which may or may not be related to
> > > transactions.  Here is my scenario....
>
> > > I have 2 entities with typical one-to-many parent child relationship.
> > > One "Document" can have many "DocumentAudit" objects.
>
> > > Parent mapping:
>
> > > <?xml version="1.0"?>
> > > <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-
> > > import="true" assembly="Business">
> > >    <class name="Business.Domain.Document" table="DOCUMENT"
> > > lazy="false">
> > >        <id name="Id" type="int" column="DocumentId">
> > >            <generator class="native" />
> > >        </id>
> > >        <property name="FileName" column="FileName" type="string"
> > > length="220" />
> > >        <bag name="DocumentAudits" cascade="all" lazy="true"
> > > inverse="true">
> > >            <key column="DocumentId" />
> > >            <one-to-many class="Business.Domain.DocumentAudit" />
> > >        </bag>
> > >    </class>
> > > </hibernate-mapping>
>
> > > And here is the child:
>
> > > <?xml version="1.0"?>
> > > <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-
> > > import="true" assembly="Business">
> > >    <class name="Business.Domain.DocumentAudit" table="DOCUMENT_AUDIT"
> > > lazy="true">
> > >        <cache usage="read-write"/>
> > >        <id name="Id" type="int" column="DocumentAuditId">
> > >            <generator class="native" />
> > >        </id>
> > >        <property name="Action" column="Action" type="string"
> > > length="50" />
> > >        <property name="Actor" column="Actor" type="string"
> > > length="50" />
> > >        <many-to-one name="Document" class="Business.Domain.Document"
> > > fetch="select">
> > >            <column name="DocumentId" unique="true" />
> > >        </many-to-one>
> > >    </class>
> > > </hibernate-mapping>
>
> > > I have a generic data access class called BaseBroker which has Persist
> > > and Delete methods as follows:
>
> > >    public void Persist(T obj)
> > >    {
> > >        using (ITransaction txn =
> > > nHibernateDB.Session.BeginTransaction())
> > >        {
> > >            try
> > >            {
> > >                nHibernateDB.Session.Persist(obj);
> > >                txn.Commit();
> > >            }
> > >            catch
> > >            {
> > >                txn.Rollback();
> > >                throw;
> > >            }
> > >        }
> > >    }
>
> > >    public void Delete(T obj)
> > >    {
> > >        using (ITransaction txn =
> > > nHibernateDB.Session.BeginTransaction())
> > >        {
> > >            try
> > >            {
> > >                nHibernateDB.Session.Delete(obj);
> > >                txn.Commit();
> > >            }
> > >            catch
> > >            {
> > >                txn.Rollback();
> > >                throw;
> > >            }
> > >        }
> > >    }
>
> > > All seems OK and I've got some test fixtures covering everyday adding
> > > and deleting of objects.  All working fine.
>
> > > HOWEVER, I've run into a very strange error.  There is a unique index
> > > on the Document.FileName column.  I've written a test which needs to
> > > verify that attempting to insert a Document with an existing FileName
> > > generates the expected exception.  So the steps in the test are as
> > > follows:
>
> > > 1. Create new Document "doc1" with 1 new DocumentAudit child.
> > > 2. Call Persist(doc1)
> > > 3. Create new Document "doc2" with 1 new DocumentAudit child, and the
> > > SAME FileName as doc1
> > > 4. Call Persist(doc2) -> should generate a unique index exception,
> > > catch and verify it
> > > 5. Cleanup: call Delete(doc1) to delete the first instance that was
> > > persisted successfully
>
> > > What's happening when I run this test is this...it all goes as
> > > expected right up to the last step when it tries to clean up and
> > > delete doc1.  Instead of deleting doc1 I get the following exception:
>
> > > Test method
> > > BusinessTests.Brokers.DocumentBrokerTests.InsertDuplicateFileNameTest
> > > threw exception:  NHibernate.Exceptions.GenericADOException: could not
> > > insert: [Business.Domain.DocumentAudit][SQL: INSERT INTO
> > > DOCUMENT_AUDIT (Action, Actor, DocumentId) VALUES (?, ?, ?); select
> > > SCOPE_IDENTITY()] --->  System.Data.SqlClient.SqlException: Cannot
> > > insert the value NULL into column 'DocumentId', table
> > > 'dbo.DOCUMENT_AUDIT'; column does not allow nulls. INSERT fails.
> > > The statement has been terminated..
>
> > > So I've put some debug into the code (in the form of Console.WriteLine
> > > in various places).  Look at the Console output (my debug bits start
> > > with "==>"):
>
> > > ==> About to create 1st instance
> > > NHibernate: INSERT INTO DOCUMENT (FileName) VALUES (@p0); select
> > > SCOPE_IDENTITY();@p0 = 'test.txt'
> > > NHibernate: INSERT INTO DOCUMENT_AUDIT (Action, Actor, DocumentId)
> > > VALUES (@p0, @p1, @p2); select SCOPE_IDENTITY();@p0 = 'create', @p1 =
> > > 'testuser', @p2 = 39
> > > ==> About to create 2nd instance
> > > NHibernate: INSERT INTO DOCUMENT (FileName) VALUES (@p0); select
> > > SCOPE_IDENTITY();@p0 = 'test.txt'
> > > ==> Caught and handled exception
> > > ==> About to delete 1st instance
> > > NHibernate: INSERT INTO DOCUMENT_AUDIT (Action, Actor, DocumentId)
> > > VALUES (@p0, @p1, @p2); select SCOPE_IDENTITY();@p0 = 'create', @p1 =
> > > 'testuser', @p2 = NULL
>
> > > So as you can see the bit the generated the error was the last
> > > statement - @p2 (the DocumentId) is null.
>
> > > The bizarre thing is that after the Exception is caught and handled
> > > (and the transaction rolled back) the Delete statement should be
> > > executed.  But it doesn't do that, it's like it's still got a "queue"
> > > of SQL statements it needs to execute, as it tries to insert into
> > > DOCUMENT_AUDIT!
>
> > > It's almost like the transaction rollback didn't flush the pending SQL
> > > statements???
>
> > > I hope somebody can help!!
>
> > > Paul
>
> > > --
> > > 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 
> > > athttp://groups.google.com/group/nhusers?hl=en.
>
> > --
> > 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 
> > athttp://groups.google.com/group/nhusers?hl=en.-Hide quoted text -
>
> > - Show quoted text -
>
> --
> 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 
> athttp://groups.google.com/group/nhusers?hl=en.- Hide quoted text -
>
> - Show quoted text -

-- 
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.

Reply via email to