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.