Skip to content

Commit 9803134

Browse files
committed
HHH-19429 Avoid concurrent modifications of reusablePaths in AbstractSqmPath
1 parent 461448b commit 9803134

File tree

1 file changed

+9
-23
lines changed

1 file changed

+9
-23
lines changed

hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import jakarta.persistence.metamodel.PluralAttribute;
3434
import jakarta.persistence.metamodel.SingularAttribute;
3535

36-
import static java.util.Collections.emptyList;
3736
import static org.hibernate.internal.util.NullnessUtil.castNonNull;
3837

3938
/**
@@ -49,7 +48,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
4948
* E.g., given {@code p.mate.mate} the {@code SqmRoot} identified by {@code p} would
5049
* have a reusable path for the {@code p.mate} path.
5150
*/
52-
private Map<String, SqmPath<?>> reusablePaths;
51+
private final Map<String, SqmPath<?>> reusablePaths = new ConcurrentHashMap<>( 0 );
5352

5453
protected AbstractSqmPath(
5554
NavigablePath navigablePath,
@@ -103,32 +102,27 @@ public SqmPath<?> getLhs() {
103102

104103
@Override
105104
public List<SqmPath<?>> getReusablePaths() {
106-
return reusablePaths == null ? emptyList() : new ArrayList<>( reusablePaths.values() );
105+
return new ArrayList<>( reusablePaths.values() );
107106
}
108107

109108
@Override
110109
public void visitReusablePaths(Consumer<SqmPath<?>> consumer) {
111-
if ( reusablePaths != null ) {
112-
reusablePaths.values().forEach( consumer );
113-
}
110+
reusablePaths.values().forEach( consumer );
114111
}
115112

116113
@Override
117114
public void registerReusablePath(SqmPath<?> path) {
118115
assert path.getLhs() == this;
119-
if ( reusablePaths == null ) {
120-
reusablePaths = new ConcurrentHashMap<>();
121-
}
122116
final String relativeName = path.getNavigablePath().getLocalName();
123-
final SqmPath<?> previous = reusablePaths.put( relativeName, path );
117+
final SqmPath<?> previous = reusablePaths.putIfAbsent( relativeName, path );
124118
if ( previous != null && previous != path ) {
125119
throw new IllegalStateException( "Implicit-join path registration unexpectedly overrode previous registration - " + relativeName );
126120
}
127121
}
128122

129123
@Override
130124
public SqmPath<?> getReusablePath(String name) {
131-
return reusablePaths == null ? null : reusablePaths.get( name );
125+
return reusablePaths.get( name );
132126
}
133127

134128
@Override
@@ -206,18 +200,10 @@ protected <X> SqmPath<X> resolvePath(PersistentAttribute<?, X> attribute) {
206200
protected <X> SqmPath<X> resolvePath(String attributeName, SqmPathSource<X> pathSource) {
207201
final SqmPathSource<?> intermediatePathSource =
208202
getResolvedModel().getIntermediatePathSource( pathSource );
209-
if ( reusablePaths == null ) {
210-
reusablePaths = new ConcurrentHashMap<>();
211-
final SqmPath<X> path = pathSource.createSqmPath( this, intermediatePathSource );
212-
reusablePaths.put( attributeName, path );
213-
return path;
214-
}
215-
else {
216-
//noinspection unchecked
217-
return (SqmPath<X>)
218-
reusablePaths.computeIfAbsent( attributeName,
219-
name -> pathSource.createSqmPath( this, intermediatePathSource ) );
220-
}
203+
//noinspection unchecked
204+
return (SqmPath<X>)
205+
reusablePaths.computeIfAbsent( attributeName,
206+
name -> pathSource.createSqmPath( this, intermediatePathSource ) );
221207
}
222208

223209
protected <S extends T> SqmTreatedPath<T, S> getTreatedPath(ManagedDomainType<S> treatTarget) {

0 commit comments

Comments
 (0)