HHH-16014 Cache treated paths + root logic in copy context for paths
This commit is contained in:
parent
b0d03e39e2
commit
8fa39d773b
|
@ -8,6 +8,8 @@ package org.hibernate.query.sqm.tree;
|
|||
|
||||
import java.util.IdentityHashMap;
|
||||
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -21,9 +23,14 @@ public interface SqmCopyContext {
|
|||
final IdentityHashMap<Object, Object> map = new IdentityHashMap<>();
|
||||
return new SqmCopyContext() {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getCopy(T original) {
|
||||
//noinspection unchecked
|
||||
return (T) map.get( original );
|
||||
if (original instanceof SqmPath) {
|
||||
return (T) getPathCopy( (SqmPath<?>) original );
|
||||
}
|
||||
else {
|
||||
return (T) map.get( original );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,6 +42,32 @@ public interface SqmCopyContext {
|
|||
return copy;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends SqmPath<?>> T getPathCopy(T original) {
|
||||
T existing = (T) map.get( original );
|
||||
if ( existing != null ) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
SqmPath<?> root = getRoot( original );
|
||||
if ( root != original ) {
|
||||
root.copy( this );
|
||||
// root path might have already copied original
|
||||
return (T) map.get( original );
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private SqmPath<?> getRoot(SqmPath<?> path) {
|
||||
if ( path.getLhs() != null ) {
|
||||
return getRoot( path.getLhs() );
|
||||
}
|
||||
else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,20 +12,22 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import jakarta.persistence.metamodel.MapAttribute;
|
||||
import jakarta.persistence.metamodel.PluralAttribute;
|
||||
import jakarta.persistence.metamodel.SingularAttribute;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.metamodel.model.domain.PersistentAttribute;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||
import org.hibernate.query.sqm.tree.expression.AbstractSqmExpression;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
|
||||
import jakarta.persistence.metamodel.MapAttribute;
|
||||
import jakarta.persistence.metamodel.PluralAttribute;
|
||||
import jakarta.persistence.metamodel.SingularAttribute;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -183,6 +185,17 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
|
|||
}
|
||||
}
|
||||
|
||||
protected <S extends T> SqmTreatedPath<T, S> getTreatedPath(EntityDomainType<S> treatTarget) {
|
||||
final NavigablePath treat = getNavigablePath().treatAs( treatTarget.getHibernateEntityName() );
|
||||
//noinspection unchecked
|
||||
SqmTreatedPath<T, S> path = (SqmTreatedPath<T, S>) getLhs().getReusablePath( treat.getLocalName() );
|
||||
if ( path == null ) {
|
||||
path = new SqmTreatedSimplePath<>( this, treatTarget, nodeBuilder() );
|
||||
getLhs().registerReusablePath( path );
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <Y> SqmPath<Y> get(SingularAttribute<? super T, Y> jpaAttribute) {
|
||||
|
|
|
@ -75,7 +75,6 @@ public class SqmEntityValuedSimplePath<T> extends AbstractSqmSimplePath<T> {
|
|||
|
||||
@Override
|
||||
public <S extends T> SqmTreatedPath<T, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
|
||||
return new SqmTreatedSimplePath<>( this, treatTarget, nodeBuilder() );
|
||||
return getTreatedPath( treatTarget );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ public class SqmIndexedCollectionAccessPath<T> extends AbstractSqmPath<T> implem
|
|||
@Override
|
||||
public <S extends T> SqmTreatedPath<T, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
|
||||
if ( getReferencedPathSource().getSqmPathType() instanceof EntityDomainType ) {
|
||||
return new SqmTreatedSimplePath<>( this, treatTarget, nodeBuilder() );
|
||||
return getTreatedPath( treatTarget );
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException( );
|
||||
|
|
|
@ -168,11 +168,7 @@ public class SqmPluralValuedSimplePath<E> extends AbstractSqmSimplePath<E> {
|
|||
|
||||
@Override
|
||||
public <S extends E> SqmTreatedPath<E, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
|
||||
return new SqmTreatedSimplePath<>(
|
||||
this,
|
||||
treatTarget,
|
||||
nodeBuilder()
|
||||
);
|
||||
return getTreatedPath( treatTarget );
|
||||
}
|
||||
|
||||
// @Override
|
||||
|
|
|
@ -23,7 +23,7 @@ public class TreatedNavigablePath extends NavigablePath {
|
|||
public TreatedNavigablePath(NavigablePath parent, String entityTypeName, String alias) {
|
||||
super(
|
||||
parent,
|
||||
entityTypeName,
|
||||
"#" + entityTypeName,
|
||||
alias,
|
||||
"treat(" + parent + " as " + entityTypeName + ")",
|
||||
TreatedNavigablePath::calculateTreatedFullPath,
|
||||
|
|
Loading…
Reference in New Issue