HHH-14482 Do not discard prior implicit join by key

This commit is contained in:
Andrea Boriero 2021-03-08 19:10:26 +01:00
parent a022127428
commit 1905e8bba3
4 changed files with 44 additions and 5 deletions

View File

@ -45,6 +45,12 @@ public class DomainPathPart implements SemanticPathPart {
throw new SemanticException( "Cannot resolve path (`" + name + "`) relative to `" + lhs.getNavigablePath() + "`" );
}
//noinspection unchecked
final SqmPath<?> existingImplicitJoinPath = lhs.getImplicitJoinPath( name );
if ( existingImplicitJoinPath != null ) {
currentPath = existingImplicitJoinPath;
return this;
}
currentPath = subPathSource.createSqmPath( lhs, creationState );
if ( isTerminal ) {
return currentPath;

View File

@ -125,11 +125,21 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
}
final String relativeName = path.getNavigablePath().getLocalName();
if ( !implicitJoinPaths.containsKey( relativeName ) ) {
implicitJoinPaths.put( relativeName, path );
final SqmPath<?> previous = implicitJoinPaths.put( relativeName, path );
if ( previous != null && previous != path ) {
throw new IllegalStateException( "Implicit-join path registration unexpectedly overrode previous registration - " + relativeName );
}
}
@Override
public SqmPath<?> getImplicitJoinPath(String name) {
if ( implicitJoinPaths == null ) {
return null;
}
return implicitJoinPaths.get( name );
}
@Override
public String getExplicitAlias() {
return getAlias();

View File

@ -77,6 +77,8 @@ public interface SqmPath<T> extends SqmExpression<T>, SemanticPathPart, JpaPath<
*/
void registerImplicitJoinPath(SqmPath<?> path);
SqmPath<?> getImplicitJoinPath(String name);
/**
* This node's type is its "referenced path source"
*/

View File

@ -54,14 +54,35 @@ public class SubQueryImplicitJoinReferenceTest {
public void performHqlTest(SessionFactoryScope scope) {
// Now simulate running an audit query
scope.inSession( session -> {
session.createQuery( "select e__ FROM org.hibernate.orm.test.SubQueryImplicitJoinReferenceTest$TheEntity e__ "
session.createQuery( "select e__ FROM TheEntity e__ "
+ "WHERE e__.originalId.rev.id = (select max(e2__.originalId.rev.id) FROM "
+ "org.hibernate.orm.test.SubQueryImplicitJoinReferenceTest$TheEntity e2__ WHERE " +
+ "TheEntity e2__ WHERE " +
"e2__.originalId.rev.id <= 2 and e__.originalId.id = e2__.originalId.id)" ).list();
} );
}
@Entity
@Test
public void performHqlTest2(SessionFactoryScope scope) {
// Now simulate running an audit query
scope.inSession( session -> {
session.createQuery( "select e__ FROM TheEntity e__ "
+ "WHERE e__.originalId.id = (select max(e2__.originalId.id) FROM "
+ "TheEntity e2__ WHERE " +
"e__.originalId.id = e2__.originalId.id and e2__.originalId.rev.id <= 2)" ).list();
} );
}
@Test
public void performHqlTest3(SessionFactoryScope scope) {
// Now simulate running an audit query
scope.inSession( session -> {
session.createQuery( "select e2__.originalId.id, e2__.originalId.rev.id FROM "
+ "TheEntity e2__ WHERE " +
" e2__.originalId.rev.id <= 2" ).list();
} );
}
@Entity(name = "TheEntity")
public static class TheEntity {
@EmbeddedId
private OriginalId originalId;