@@ -26,57 +26,69 @@ protected internal AbstractSelectingDelegate(IPostInsertIdentityPersister persis
2626
2727 public abstract IdentifierGeneratingInsert PrepareIdentifierGeneratingInsert ( ) ;
2828
29- public object PerformInsert ( SqlCommandInfo insertSQL , ISessionImplementor session , IBinder binder )
29+ public object PerformInsert ( SqlCommandInfo insertSql , ISessionImplementor session , IBinder binder )
3030 {
31+ // NH-2145: Prevent connection releases between insert and select when we cannot perform
32+ // them as a single statement. Retrieving id most of the time relies on using the same connection.
33+ session . ConnectionManager . FlushBeginning ( ) ;
3134 try
3235 {
33- // prepare and execute the insert
34- var insert = session . Batcher . PrepareCommand ( insertSQL . CommandType , insertSQL . Text , insertSQL . ParameterTypes ) ;
3536 try
3637 {
37- binder . BindValues ( insert ) ;
38- session . Batcher . ExecuteNonQuery ( insert ) ;
38+ // prepare and execute the insert
39+ var insert = session . Batcher . PrepareCommand ( insertSql . CommandType , insertSql . Text , insertSql . ParameterTypes ) ;
40+ try
41+ {
42+ binder . BindValues ( insert ) ;
43+ session . Batcher . ExecuteNonQuery ( insert ) ;
44+ }
45+ finally
46+ {
47+ session . Batcher . CloseCommand ( insert , null ) ;
48+ }
3949 }
40- finally
50+ catch ( DbException sqle )
4151 {
42- session . Batcher . CloseCommand ( insert , null ) ;
52+ throw ADOExceptionHelper . Convert ( session . Factory . SQLExceptionConverter , sqle ,
53+ "could not insert: " + persister . GetInfoString ( ) , insertSql . Text ) ;
4354 }
44- }
45- catch ( DbException sqle )
46- {
47- throw ADOExceptionHelper . Convert ( session . Factory . SQLExceptionConverter , sqle ,
48- "could not insert: " + persister . GetInfoString ( ) , insertSQL . Text ) ;
49- }
5055
51- SqlString selectSQL = SelectSQL ;
52- using ( new SessionIdLoggingContext ( session . SessionId ) )
53- try
54- {
55- //fetch the generated id in a separate query
56- var idSelect = session . Batcher . PrepareCommand ( CommandType . Text , selectSQL , ParametersTypes ) ;
57- try
56+ var selectSql = SelectSQL ;
57+ using ( new SessionIdLoggingContext ( session . SessionId ) )
5858 {
59- BindParameters ( session , idSelect , binder . Entity ) ;
60- var rs = session . Batcher . ExecuteReader ( idSelect ) ;
6159 try
6260 {
63- return GetResult ( session , rs , binder . Entity ) ;
61+ //fetch the generated id in a separate query
62+ var idSelect = session . Batcher . PrepareCommand ( CommandType . Text , selectSql , ParametersTypes ) ;
63+ try
64+ {
65+ BindParameters ( session , idSelect , binder . Entity ) ;
66+ var rs = session . Batcher . ExecuteReader ( idSelect ) ;
67+ try
68+ {
69+ return GetResult ( session , rs , binder . Entity ) ;
70+ }
71+ finally
72+ {
73+ session . Batcher . CloseReader ( rs ) ;
74+ }
75+ }
76+ finally
77+ {
78+ session . Batcher . CloseCommand ( idSelect , null ) ;
79+ }
6480 }
65- finally
81+ catch ( DbException sqle )
6682 {
67- session . Batcher . CloseReader ( rs ) ;
83+ throw ADOExceptionHelper . Convert ( session . Factory . SQLExceptionConverter , sqle ,
84+ "could not retrieve generated id after insert: " + persister . GetInfoString ( ) ,
85+ insertSql . Text ) ;
6886 }
6987 }
70- finally
71- {
72- session . Batcher . CloseCommand ( idSelect , null ) ;
73- }
7488 }
75- catch ( DbException sqle )
89+ finally
7690 {
77- throw ADOExceptionHelper . Convert ( session . Factory . SQLExceptionConverter , sqle ,
78- "could not retrieve generated id after insert: " + persister . GetInfoString ( ) ,
79- insertSQL . Text ) ;
91+ session . ConnectionManager . FlushEnding ( ) ;
8092 }
8193 }
8294
0 commit comments