Skip to content

Commit b4898dd

Browse files
committed
HHH-19925 - Locking root(s) should be based on select-clause, not from-clause
1 parent 28e0421 commit b4898dd

File tree

4 files changed

+50
-50
lines changed

4 files changed

+50
-50
lines changed

hibernate-core/src/main/java/org/hibernate/sql/ast/internal/AbstractLockingClauseStrategy.java

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
import java.util.HashSet;
1616
import java.util.Set;
1717

18-
/**
19-
* @author Steve Ebersole
20-
*/
18+
/// Base support for LockingClauseStrategy implementations
19+
///
20+
/// @author Steve Ebersole
2121
public abstract class AbstractLockingClauseStrategy implements LockingClauseStrategy {
2222
private final Locking.Scope lockingScope;
2323
private final Set<NavigablePath> rootsForLocking;
@@ -31,21 +31,12 @@ public AbstractLockingClauseStrategy(
3131
this.rootsForLocking = rootsForLocking == null ? Set.of() : rootsForLocking;
3232
}
3333

34-
protected Locking.Scope getLockingScope() {
35-
return lockingScope;
36-
}
37-
38-
protected Set<NavigablePath> getRootsForLocking() {
39-
return rootsForLocking;
40-
}
41-
42-
protected Set<NavigablePath> getPathsToLock() {
43-
return pathsToLock;
44-
}
45-
4634
@Override
4735
public boolean shouldLockRoot(TableGroup root) {
48-
return rootsForLocking.contains( root.getNavigablePath() );
36+
// NOTE : the NavigablePath can be null in some cases.
37+
// we don't care about these cases, so easier to just
38+
// handle the nullness here
39+
return root.getNavigablePath() != null && rootsForLocking.contains( root.getNavigablePath() );
4940
}
5041

5142
@Override
@@ -104,9 +95,9 @@ protected void trackRoot(TableGroup root) {
10495
}
10596

10697
@Override
107-
public void registerJoin(TableGroupJoin join) {
108-
if ( shouldLockJoin( join.getJoinedGroup() ) ) {
109-
trackJoin( join );
98+
public void registerJoin(TableGroupJoin joinedGroup) {
99+
if ( shouldLockJoin( joinedGroup.getJoinedGroup() ) ) {
100+
trackJoin( joinedGroup );
110101
}
111102
}
112103

hibernate-core/src/main/java/org/hibernate/sql/ast/internal/NonLockingClauseStrategy.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public void registerRoot(TableGroup root) {
3838
}
3939

4040
@Override
41-
public void registerJoin(TableGroupJoin join) {
41+
public void registerJoin(TableGroupJoin joinedGroup) {
4242
// nothing to do
4343
}
4444

hibernate-core/src/main/java/org/hibernate/sql/ast/internal/StandardLockingClauseStrategy.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ protected void trackRoot(TableGroup root) {
100100
}
101101

102102
@Override
103-
public void registerJoin(TableGroupJoin join) {
104-
checkForOuterJoins( join );
105-
super.registerJoin( join );
103+
public void registerJoin(TableGroupJoin joinedGroup) {
104+
checkForOuterJoins( joinedGroup );
105+
super.registerJoin( joinedGroup );
106106
}
107107

108108
@Override

hibernate-core/src/main/java/org/hibernate/sql/ast/spi/LockingClauseStrategy.java

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,48 +4,57 @@
44
*/
55
package org.hibernate.sql.ast.spi;
66

7+
import org.hibernate.Incubating;
78
import org.hibernate.sql.ast.tree.from.TableGroup;
89
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
910

1011
import java.util.Collection;
1112

12-
/**
13-
* Strategy for dealing with locking via a SQL {@code FOR UPDATE (OF)}
14-
* clause.
15-
* <p/>
16-
* Some dialects do not use a {@code FOR UPDATE (OF)} to apply
17-
* locks - e.g., they apply locks in the {@code FROM} clause. Such
18-
* dialects would return a no-op version of this contract.
19-
* <p/>
20-
* Some dialects support an additional {@code FOR SHARE (OF)} clause
21-
* as well to acquire non-exclusive locks. That is also handled here,
22-
* varied by the requested {@linkplain org.hibernate.LockMode LockMode}.
23-
* <p/>
24-
* Operates in 2 "phases"-<ol>
25-
* <li>
26-
* collect tables which are to be locked (based on {@linkplain org.hibernate.Locking.Scope},
27-
* and other things)
28-
* </li>
29-
* <li>
30-
* render the appropriate locking fragment
31-
* </li>
32-
* </ol>
33-
*
34-
* @see org.hibernate.dialect.Dialect#getLockingClauseStrategy
35-
*
36-
* @author Steve Ebersole
37-
*/
13+
/// Strategy for dealing with locking via a SQL `FOR UPDATE (OF)`
14+
/// clause.
15+
///
16+
/// Some dialects do not use a `FOR UPDATE (OF)` to apply
17+
/// locks - e.g., they apply locks in the `FROM` clause. Such
18+
/// dialects would return a no-op version of this contract.
19+
///
20+
/// Some dialects support an additional `FOR SHARE (OF)` clause
21+
/// as well to acquire non-exclusive locks. That is also handled here,
22+
/// varied by the requested {@linkplain org.hibernate.LockMode LockMode}.
23+
///
24+
/// Operates in 2 "phases"-
25+
/// * collect tables which are to be locked (based on {@linkplain org.hibernate.Locking.Scope}, and other things)
26+
/// * render the appropriate locking fragment
27+
///
28+
/// @implSpec Note that this is also used to determine and track which
29+
/// tables to lock even for cases (T-SQL e.g.) where a "locking clause"
30+
/// per-se won't be used. In such cases, only the first phase (along
31+
/// with [#shouldLockRoot] and [#shouldLockJoin]) have any impact.
32+
///
33+
/// @see org.hibernate.dialect.Dialect#getLockingClauseStrategy
34+
///
35+
/// @author Steve Ebersole
36+
@Incubating
3837
public interface LockingClauseStrategy {
38+
/// Should the specified `root` be locked
3939
boolean shouldLockRoot(TableGroup root);
40+
/// Should the specified `joinedGroup` be locked
4041
boolean shouldLockJoin(TableGroup joinedGroup);
4142

43+
/// Register the given `root`
4244
void registerRoot(TableGroup root);
43-
void registerJoin(TableGroupJoin join);
45+
/// Register the given `joinedGroup`
46+
void registerJoin(TableGroupJoin joinedGroup);
4447

48+
/// Are any outer joins encountered during registration
49+
/// of [roots][#registerRoot] and [joins][#registerJoin]
4550
boolean containsOuterJoins();
4651

52+
/// For cases where a locking clause is to be used,
53+
/// render that locking clause.
4754
void render(SqlAppender sqlAppender);
4855

56+
/// All roots to be locked.
4957
Collection<TableGroup> getRootsToLock();
58+
/// All joins to be locked.
5059
Collection<TableGroupJoin> getJoinsToLock();
5160
}

0 commit comments

Comments
 (0)