Skip to content

Commit 1bc025e

Browse files
committed
Merge branch 'NH-1082'
2 parents bc73aa0 + e999b17 commit 1bc025e

13 files changed

+257
-7
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
namespace NHibernate.Test.NHSpecificTest.NH1082
3+
{
4+
public class C
5+
{
6+
private int id;
7+
private string value;
8+
9+
public virtual string Value
10+
{
11+
get { return this.value; }
12+
set { this.value = value; }
13+
}
14+
15+
public virtual int ID
16+
{
17+
get { return id; }
18+
set { id = value; }
19+
}
20+
}
21+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
using System;
2+
using NHibernate.Cfg;
3+
using NUnit.Framework;
4+
using Environment = NHibernate.Cfg.Environment;
5+
6+
namespace NHibernate.Test.NHSpecificTest.NH1082
7+
{
8+
[TestFixture]
9+
public class Fixture : BugTestCase
10+
{
11+
public override string BugNumber
12+
{
13+
get { return "NH1082"; }
14+
}
15+
16+
[Test]
17+
public void ExceptionsInBeforeTransactionCompletionAbortTransaction()
18+
{
19+
#pragma warning disable 618
20+
Assert.IsFalse(sessions.Settings.IsInterceptorsBeforeTransactionCompletionIgnoreExceptionsEnabled);
21+
#pragma warning restore 618
22+
23+
var c = new C {ID = 1, Value = "value"};
24+
25+
var sessionInterceptor = new SessionInterceptorThatThrowsExceptionAtBeforeTransactionCompletion();
26+
using (ISession s = sessions.OpenSession(sessionInterceptor))
27+
using (ITransaction t = s.BeginTransaction())
28+
{
29+
s.Save(c);
30+
31+
Assert.Throws<BadException>(t.Commit);
32+
}
33+
34+
using (ISession s = sessions.OpenSession())
35+
{
36+
var objectInDb = s.Get<C>(1);
37+
Assert.IsNull(objectInDb);
38+
}
39+
}
40+
41+
42+
[Test]
43+
public void ExceptionsInSynchronizationBeforeTransactionCompletionAbortTransaction()
44+
{
45+
#pragma warning disable 618
46+
Assert.IsFalse(sessions.Settings.IsInterceptorsBeforeTransactionCompletionIgnoreExceptionsEnabled);
47+
#pragma warning restore 618
48+
49+
var c = new C { ID = 1, Value = "value" };
50+
51+
var synchronization = new SynchronizationThatThrowsExceptionAtBeforeTransactionCompletion();
52+
using (ISession s = sessions.OpenSession())
53+
using (ITransaction t = s.BeginTransaction())
54+
{
55+
t.RegisterSynchronization(synchronization);
56+
57+
s.Save(c);
58+
59+
Assert.Throws<BadException>(t.Commit);
60+
}
61+
62+
using (ISession s = sessions.OpenSession())
63+
{
64+
var objectInDb = s.Get<C>(1);
65+
Assert.IsNull(objectInDb);
66+
}
67+
}
68+
}
69+
70+
71+
[TestFixture]
72+
[Obsolete("Can be removed when Environment.InterceptorsBeforeTransactionCompletionIgnoreExceptions is removed.")]
73+
public class OldBehaviorEnabledFixture : BugTestCase
74+
{
75+
public override string BugNumber
76+
{
77+
get { return "NH1082"; }
78+
}
79+
80+
protected override void Configure(Configuration configuration)
81+
{
82+
configuration.SetProperty(Environment.InterceptorsBeforeTransactionCompletionIgnoreExceptions, "true");
83+
base.Configure(configuration);
84+
}
85+
86+
[Test]
87+
public void ExceptionsInBeforeTransactionCompletionAreIgnored()
88+
{
89+
Assert.IsTrue(sessions.Settings.IsInterceptorsBeforeTransactionCompletionIgnoreExceptionsEnabled);
90+
91+
var c = new C {ID = 1, Value = "value"};
92+
93+
var sessionInterceptor = new SessionInterceptorThatThrowsExceptionAtBeforeTransactionCompletion();
94+
using (ISession s = sessions.OpenSession(sessionInterceptor))
95+
using (ITransaction t = s.BeginTransaction())
96+
{
97+
s.Save(c);
98+
99+
Assert.DoesNotThrow(t.Commit);
100+
}
101+
102+
using (ISession s = sessions.OpenSession())
103+
{
104+
var objectInDb = s.Get<C>(1);
105+
106+
Assert.IsNotNull(objectInDb);
107+
108+
s.Delete(objectInDb);
109+
s.Flush();
110+
}
111+
}
112+
113+
114+
[Test]
115+
public void ExceptionsInSynchronizationBeforeTransactionCompletionAreIgnored()
116+
{
117+
Assert.IsTrue(sessions.Settings.IsInterceptorsBeforeTransactionCompletionIgnoreExceptionsEnabled);
118+
119+
var c = new C { ID = 1, Value = "value" };
120+
121+
var synchronization = new SynchronizationThatThrowsExceptionAtBeforeTransactionCompletion();
122+
using (ISession s = sessions.OpenSession())
123+
using (ITransaction t = s.BeginTransaction())
124+
{
125+
t.RegisterSynchronization(synchronization);
126+
127+
s.Save(c);
128+
129+
Assert.DoesNotThrow(t.Commit);
130+
}
131+
132+
using (ISession s = sessions.OpenSession())
133+
{
134+
var objectInDb = s.Get<C>(1);
135+
136+
Assert.IsNotNull(objectInDb);
137+
138+
s.Delete(objectInDb);
139+
s.Flush();
140+
}
141+
}
142+
}
143+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" namespace="NHibernate.Test.NHSpecificTest.NH1082" default-lazy="false">
3+
4+
<class name="C">
5+
<id name="ID" type="Int32" unsaved-value="-1">
6+
<generator class="assigned" />
7+
</id>
8+
9+
<property name="Value" column="fValue" not-null="true" length="255" />
10+
</class>
11+
12+
</hibernate-mapping>
13+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
3+
namespace NHibernate.Test.NHSpecificTest.NH1082
4+
{
5+
public class SessionInterceptorThatThrowsExceptionAtBeforeTransactionCompletion : EmptyInterceptor
6+
{
7+
public override void BeforeTransactionCompletion(ITransaction tx)
8+
{
9+
throw new BadException();
10+
}
11+
}
12+
13+
public class BadException : Exception
14+
{ }
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using NHibernate.Transaction;
2+
3+
namespace NHibernate.Test.NHSpecificTest.NH1082
4+
{
5+
public class SynchronizationThatThrowsExceptionAtBeforeTransactionCompletion : ISynchronization
6+
{
7+
public void BeforeCompletion()
8+
{
9+
throw new BadException();
10+
}
11+
12+
public void AfterCompletion(bool success)
13+
{
14+
}
15+
}
16+
}

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,7 @@
681681
<Compile Include="NHSpecificTest\BagWithLazyExtraAndFilter\Domain.cs" />
682682
<Compile Include="NHSpecificTest\BagWithLazyExtraAndFilter\Fixture.cs" />
683683
<Compile Include="Component\Basic\ComponentWithUniqueConstraintTests.cs" />
684+
<Compile Include="NHSpecificTest\NH1082\SynchronizationThatThrowsExceptionAtBeforeTransactionCompletion.cs" />
684685
<Compile Include="NHSpecificTest\NH2756\Fixture.cs" />
685686
<Compile Include="NHSpecificTest\NH2756\Model.cs" />
686687
<Compile Include="NHSpecificTest\NH2865\Entity.cs" />
@@ -689,6 +690,9 @@
689690
<Compile Include="NHSpecificTest\NH3377\Fixture.cs" />
690691
<Compile Include="NHSpecificTest\NH3392\Fixture.cs" />
691692
<Compile Include="NHSpecificTest\NH3392\Model.cs" />
693+
<Compile Include="NHSpecificTest\NH1082\Domain.cs" />
694+
<Compile Include="NHSpecificTest\NH1082\Fixture.cs" />
695+
<Compile Include="NHSpecificTest\NH1082\SessionInterceptorThatThrowsExceptionAtBeforeTransactionCompletion.cs" />
692696
<Compile Include="NHSpecificTest\NH3459\Fixture.cs" />
693697
<Compile Include="NHSpecificTest\NH3459\Order.cs" />
694698
<Compile Include="NHSpecificTest\NH2692\Fixture.cs" />
@@ -3003,6 +3007,7 @@
30033007
<SubType>Designer</SubType>
30043008
</EmbeddedResource>
30053009
<EmbeddedResource Include="Unionsubclass\DatabaseKeyword.hbm.xml" />
3010+
<EmbeddedResource Include="NHSpecificTest\NH1082\Mappings.hbm.xml" />
30063011
<EmbeddedResource Include="NHSpecificTest\NH2692\Mappings.hbm.xml">
30073012
<SubType>Designer</SubType>
30083013
</EmbeddedResource>

src/NHibernate/Cfg/Environment.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ public static string Version
171171
/// <summary> Enable ordering of insert statements for the purpose of more effecient batching.</summary>
172172
public const string OrderInserts = "order_inserts";
173173

174+
/// <summary>
175+
/// If this setting is set to false, exceptions in IInterceptor.BeforeTransactionCompletion bubble to the caller of ITransaction.Commit and abort the commit.
176+
/// If this setting is set to true, exceptions in IInterceptor.BeforeTransactionCompletion are ignored and the commit is performed.
177+
/// The default setting is false.
178+
/// </summary>
179+
[Obsolete("This setting is likely to be removed in a future version of NHibernate. The workaround is to catch all exceptions in the IInterceptor implementation.")]
180+
public const string InterceptorsBeforeTransactionCompletionIgnoreExceptions = "interceptors.beforetransactioncompletion_ignore_exceptions";
181+
174182
private static readonly Dictionary<string, string> GlobalProperties;
175183

176184
private static IBytecodeProvider BytecodeProviderInstance;

src/NHibernate/Cfg/Settings.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Collections.Generic;
23
using System.Data;
34
using NHibernate.AdoNet;
@@ -125,6 +126,9 @@ public Settings()
125126
/// </summary>
126127
public ILinqToHqlGeneratorsRegistry LinqToHqlGeneratorsRegistry { get; internal set; }
127128

129+
[Obsolete("This setting is likely to be removed in a future version of NHibernate. The workaround is to catch all exceptions in the IInterceptor implementation.")]
130+
public bool IsInterceptorsBeforeTransactionCompletionIgnoreExceptionsEnabled { get; internal set; }
131+
128132
#endregion
129133
}
130134
}

src/NHibernate/Cfg/SettingsFactory.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,12 @@ public Settings BuildSettings(IDictionary<string, string> properties)
265265
log.Info("Named query checking : " + EnabledDisabled(namedQueryChecking));
266266
settings.IsNamedQueryStartupCheckingEnabled = namedQueryChecking;
267267

268+
#pragma warning disable 618 // Disable warning for use of obsolete symbols.
269+
var interceptorsBeforeTransactionCompletionIgnoreExceptions = PropertiesHelper.GetBoolean(Environment.InterceptorsBeforeTransactionCompletionIgnoreExceptions, properties, false);
270+
log.Info("Ignoring exceptions in BeforeTransactionCompletion : " + EnabledDisabled(interceptorsBeforeTransactionCompletionIgnoreExceptions));
271+
settings.IsInterceptorsBeforeTransactionCompletionIgnoreExceptionsEnabled = interceptorsBeforeTransactionCompletionIgnoreExceptions;
272+
#pragma warning restore 618
273+
268274
// Not ported - settings.StatementFetchSize = statementFetchSize;
269275
// Not ported - ScrollableResultSetsEnabled
270276
// Not ported - GetGeneratedKeysEnabled

src/NHibernate/Impl/SessionFactoryImpl.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Data;
4+
using System.Linq;
45
using System.Runtime.Serialization;
56
using System.Security;
67
using System.Text;
7-
using System.Linq;
8-
98
using NHibernate.Cache;
109
using NHibernate.Cfg;
1110
using NHibernate.Connection;
@@ -491,10 +490,14 @@ public ISession OpenSession(IInterceptor sessionLocalInterceptor)
491490
public ISession OpenSession(IDbConnection connection, bool flushBeforeCompletionEnabled, bool autoCloseSessionEnabled,
492491
ConnectionReleaseMode connectionReleaseMode)
493492
{
493+
#pragma warning disable 618
494+
var isInterceptorsBeforeTransactionCompletionIgnoreExceptionsEnabled = settings.IsInterceptorsBeforeTransactionCompletionIgnoreExceptionsEnabled;
495+
#pragma warning restore 618
496+
494497
return
495498
new SessionImpl(connection, this, true, settings.CacheProvider.NextTimestamp(), interceptor,
496499
settings.DefaultEntityMode, flushBeforeCompletionEnabled, autoCloseSessionEnabled,
497-
connectionReleaseMode);
500+
isInterceptorsBeforeTransactionCompletionIgnoreExceptionsEnabled, connectionReleaseMode);
498501
}
499502

500503
public IEntityPersister GetEntityPersister(string entityName)
@@ -1205,9 +1208,14 @@ private IDictionary<string, HibernateException> CheckNamedQueries()
12051208

12061209
private SessionImpl OpenSession(IDbConnection connection, bool autoClose, long timestamp, IInterceptor sessionLocalInterceptor)
12071210
{
1211+
#pragma warning disable 618
1212+
var isInterceptorsBeforeTransactionCompletionIgnoreExceptionsEnabled = settings.IsInterceptorsBeforeTransactionCompletionIgnoreExceptionsEnabled;
1213+
#pragma warning restore 618
1214+
12081215
SessionImpl session = new SessionImpl(connection, this, autoClose, timestamp, sessionLocalInterceptor ?? interceptor,
12091216
settings.DefaultEntityMode, settings.IsFlushBeforeCompletionEnabled,
1210-
settings.IsAutoCloseSessionEnabled, settings.ConnectionReleaseMode);
1217+
settings.IsAutoCloseSessionEnabled, isInterceptorsBeforeTransactionCompletionIgnoreExceptionsEnabled,
1218+
settings.ConnectionReleaseMode);
12111219
if (sessionLocalInterceptor != null)
12121220
{
12131221
// NH specific feature

0 commit comments

Comments
 (0)