Hi all,
I am getting a persistent error with a quite complex app I am
writing. NHibernate is very powerful but I dont think I'm using it
properly.
Because the system is so complex I'll try to be brief.
I am using NHibernate and
VB.NET in a thick-client app.
I have entities called Venue and VenueRoom. A Venue has many rooms,
along with some other entities with similar relationships.
I am using NHibernate in what I can only describe as 'session by
screen' - ie when the user requests a screen (windows form/dialog) in
the app, it gets its own session that is discarded when the screen
closes. (is this a really bad thing?)
The parent screen calls the venue screen (showing a single venue + its
rooms). The user can add/edit/delete rooms, but if they then cancel
the screen, the changes are ignored. I do this by beginning a
transaction before opening the screen, and then either committing or
rolling it back depending on whether the user pressed Save or Cancel.
Right. The problem:
If I create/edit/delete rooms and press Save, everything is fine.
But, if I:
1. Delete an existing room
2. Press Cancel
3. Display the screen a second time with the same venue (the deleted
room is back as expected)
4. Press Save (with no editing)
the 'possible nonthreadsafe access to session' error is thrown.
My xml: (in clsVenue.hbm.xml)
<set name="Rooms" cascade="all" inverse="false">
<key column="VenueID" not-null="true"/>
<one-to-many
class="Bookings_System.clsVenueRoom,Bookings_System"/>
</set>
Code in the screen (when the screen is shown)
Dim l_venue As clsVenue =
VenueManager.getInstance.getVenue(l_venueID, getSession())
Dim l_trans = getSession().beginTransaction()
lazyCreateVenueDialog()
m_venueDialog.Mode() = MODE_EDIT
m_venueDialog.setData(l_venue)
m_venueDialog.ShowDialog(Me)
If (m_venueDialog.userConfirmed()) Then
Try
' All sub objects of venues will have been
added/deleted etc
' just need to get the venue itself and fill
it with
' the edited data
l_venue = m_venueDialog.getData()
m_venueDialog.fillData(l_venue)
VenueManager.getInstance().updateVenue
(l_venue, getSession())
l_trans.commit() <---- Exception at step 4
' Update the list and the data behind it
refreshData()
Catch ex As Exception
l_trans.rollback()
' also revert the object back to its original
state
getSession().Evict(l_venue)
MsgBox("Cannot Edit Venue:" + ex.Message())
End Try
Else
If l_trans IsNot Nothing Then
l_trans.rollback()
' also revert the object back to its original
state
getSession().Evict(l_venue)
End If
End If
The Stack Trace:
at NHibernate.Action.EntityDeleteAction.Execute() in c:\CSharp
\NH2.1.x\nhibernate\src\NHibernate\Action\EntityDeleteAction.cs:line
81
at NHibernate.Engine.ActionQueue.Execute(IExecutable executable) in
c:\CSharp\NH2.1.x\nhibernate\src\NHibernate\Engine\ActionQueue.cs:line
130
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) in c:
\CSharp\NH2.1.x\nhibernate\src\NHibernate\Engine\ActionQueue.cs:line
113
at NHibernate.Engine.ActionQueue.ExecuteActions() in c:\CSharp
\NH2.1.x\nhibernate\src\NHibernate\Engine\ActionQueue.cs:line 151
at
NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions
(IEventSource session) in c:\CSharp\NH2.1.x\nhibernate\src\NHibernate
\Event\Default\AbstractFlushingEventListener.cs:line 241
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush
(FlushEvent event) in c:\CSharp\NH2.1.x\nhibernate\src\NHibernate\Event
\Default\DefaultFlushEventListener.cs:line 19
at NHibernate.Impl.SessionImpl.Flush() in c:\CSharp\NH2.1.x
\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1477
at NHibernate.Transaction.AdoTransaction.Commit() in c:\CSharp
\NH2.1.x\nhibernate\src\NHibernate\Transaction\AdoTransaction.cs:line
187
at Bookings_System.DB.DataAccessSession.confirmTransaction
(ISessionTransaction& p_trans) in C:\Documents and Settings\david.smith
\My Documents\Visual Studio 2008\Projects\Bookings_System_svn\Bookings
System\Bookings System\Classes\DB\DataAccessSession.vb:line 56
at Bookings_System.Forms.frmVenueList.btnEdit_Click(Object sender,
EventArgs e) in C:\Documents and Settings\david.smith\My Documents
\Visual Studio 2008\Projects\Bookings_System_svn\Bookings System
\Bookings System\Forms\frmVenuesList.vb:line 396
Can anyone tell me why this is failing? I originally figured it was
something to do with it being on the event dispatch thread, but then
none of it should work.
Any suggestions appreciated (including a big list of the ways I'm
using hibernate wrong :) ).
Regards,
FP