Skip to content

Commit 7effa35

Browse files
author
Doan Van Tuan
committed
GH1565 Refine code as per reviewer comments:
- Restore and mark SetLockMode(LockMode) obsolete - Only check for outer join if the dialect is not support locking entire outer join - Rename test class to reflect that it not limited to PostgreSQL
1 parent abb3c82 commit 7effa35

File tree

2 files changed

+31
-29
lines changed

2 files changed

+31
-29
lines changed

src/NHibernate.Test/NHSpecificTest/GH1565/PostgresOuterJoinLockTest.cs renamed to src/NHibernate.Test/NHSpecificTest/GH1565/LockEntityWithOuterJoinTest.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
using NHibernate.Cfg;
2-
using NHibernate.Dialect;
3-
using NUnit.Framework;
1+
using NUnit.Framework;
42

53
namespace NHibernate.Test.NHSpecificTest.GH1565
64
{
75
[TestFixture]
8-
public class PostgresOuterJoinLockTest : BugTestCase
6+
public class LockEntityWithOuterJoinTest : BugTestCase
97
{
108
[Test]
119
public void LockWithOuterJoin_ShouldBePossible()
@@ -16,7 +14,7 @@ public void LockWithOuterJoin_ShouldBePossible()
1614
{
1715
var entity = session.Get<MainEntity>(id, LockMode.Upgrade);
1816
Assert.That(entity.Id, Is.EqualTo(id));
19-
transaction.Rollback();
17+
transaction.Commit();
2018
}
2119
}
2220
}
@@ -46,11 +44,6 @@ protected override void OnTearDown()
4644
session.CreateSQLQuery("delete from MainEntity").ExecuteUpdate();
4745
}
4846
}
49-
50-
protected override bool AppliesTo(Dialect.Dialect dialect)
51-
{
52-
return dialect is PostgreSQLDialect;
53-
}
5447
}
5548

5649
public class MainEntity

src/NHibernate/SqlCommand/SqlSelectBuilder.cs

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11

2+
using System;
23
using NHibernate.Engine;
34
using NHibernate.Type;
45
using NHibernate.Util;
@@ -21,10 +22,9 @@ public class SqlSelectBuilder : SqlBaseBuilder, ISqlStringBuilder
2122
private SqlString groupByClause;
2223
private SqlString havingClause;
2324
private LockMode lockMode;
24-
private string aliasToLock;
25+
private string mainTableAlias;
2526
private string comment;
26-
private bool hasOuterJoin = false;
27-
27+
2828
public SqlSelectBuilder(ISessionFactoryImplementor factory)
2929
: base(factory.Dialect, factory) {}
3030

@@ -42,7 +42,6 @@ public SqlSelectBuilder SetComment(string comment)
4242
public SqlSelectBuilder SetFromClause(string fromClause)
4343
{
4444
this.fromClause = fromClause;
45-
hasOuterJoin = hasOuterJoin || fromClause.ToLowerInvariant().Contains("left outer join");
4645
return this;
4746
}
4847

@@ -65,8 +64,7 @@ public SqlSelectBuilder SetFromClause(string tableName, string alias)
6564
/// <returns>The SqlSelectBuilder</returns>
6665
public SqlSelectBuilder SetFromClause(SqlString fromClause)
6766
{
68-
// it is safe to do this because a fromClause will have no
69-
// parameters
67+
// it is safe to do this because a fromClause will have no parameters
7068
return SetFromClause(fromClause.ToString());
7169
}
7270

@@ -113,9 +111,6 @@ public SqlSelectBuilder SetOuterJoins(SqlString outerJoinsAfterFrom, SqlString o
113111
}
114112

115113
this.outerJoinsAfterWhere = tmpOuterJoinsAfterWhere;
116-
117-
hasOuterJoin = hasOuterJoin ||
118-
outerJoinsAfterFrom != null && outerJoinsAfterFrom.ToString().ToLowerInvariant().Contains("outer join");
119114
return this;
120115
}
121116

@@ -187,10 +182,18 @@ public SqlSelectBuilder SetHavingClause(SqlString havingSqlString)
187182
return this;
188183
}
189184

190-
public SqlSelectBuilder SetLockMode(LockMode lockMode, string alias)
185+
[Obsolete("For some DBMS's such as PostgreSQL, a lock on query with OUTER JOIN is not possible without specifying the not-null side. " +
186+
"Use the new method SetLockMode(LockMode, mainTableAlias) instead.")]
187+
public SqlSelectBuilder SetLockMode(LockMode lockMode)
188+
{
189+
this.lockMode = lockMode;
190+
return this;
191+
}
192+
193+
public SqlSelectBuilder SetLockMode(LockMode lockMode, string mainTableAlias)
191194
{
192195
this.lockMode = lockMode;
193-
aliasToLock = alias;
196+
this.mainTableAlias = mainTableAlias;
194197
return this;
195198
}
196199

@@ -300,17 +303,23 @@ public SqlString ToSqlString()
300303

301304
private string GetForUpdateString()
302305
{
303-
if (!Dialect.SupportsOuterJoinForUpdate && hasOuterJoin)
304-
{
305-
if (Equals(lockMode, LockMode.Upgrade))
306-
return Dialect.GetForUpdateString(aliasToLock);
307-
if (Equals(lockMode, LockMode.UpgradeNoWait))
308-
return Dialect.GetForUpdateNowaitString(aliasToLock);
309-
}
306+
if (Dialect.SupportsOuterJoinForUpdate || !HasOuterJoin())
307+
return Dialect.GetForUpdateString(lockMode);
308+
309+
if (Equals(lockMode, LockMode.Upgrade))
310+
return Dialect.GetForUpdateString(mainTableAlias);
311+
if (Equals(lockMode, LockMode.UpgradeNoWait))
312+
return Dialect.GetForUpdateNowaitString(mainTableAlias);
310313

311314
return Dialect.GetForUpdateString(lockMode);
312-
}
313315

316+
bool HasOuterJoin()
317+
{
318+
return
319+
StringHelper.ContainsCaseInsensitive(fromClause, "outer join") ||
320+
!string.IsNullOrWhiteSpace(outerJoinsAfterFrom?.ToString());
321+
}
322+
}
314323
#endregion
315324
}
316325
}

0 commit comments

Comments
 (0)