HHH-16676 Handle treat expressions in toHqlString

This commit is contained in:
Christian Beikov 2023-05-23 12:51:48 +02:00
parent 282cf76987
commit a1c6500621
2 changed files with 59 additions and 3 deletions

View File

@ -28,6 +28,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.SqmCopyContext; import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmNode; import org.hibernate.query.sqm.tree.SqmNode;
import org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath; import org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
import org.hibernate.query.sqm.tree.expression.SqmAliasedNodeRef; import org.hibernate.query.sqm.tree.expression.SqmAliasedNodeRef;
import org.hibernate.query.sqm.tree.expression.SqmExpression; import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
@ -588,12 +589,14 @@ public class SqmQuerySpec<T> extends SqmQueryPart<T>
sb.append( root.getCorrelationParent().resolveAlias() ); sb.append( root.getCorrelationParent().resolveAlias() );
sb.append( ' ' ).append( root.resolveAlias() ); sb.append( ' ' ).append( root.resolveAlias() );
appendJoins( root, sb ); appendJoins( root, sb );
appendTreatJoins( root, sb );
} }
} }
else { else {
sb.append( root.getEntityName() ); sb.append( root.getEntityName() );
sb.append( ' ' ).append( root.resolveAlias() ); sb.append( ' ' ).append( root.resolveAlias() );
appendJoins( root, sb ); appendJoins( root, sb );
appendTreatJoins( root, sb );
} }
separator = ", "; separator = ", ";
} }
@ -639,8 +642,16 @@ public class SqmQuerySpec<T> extends SqmQueryPart<T>
} }
if ( sqmJoin instanceof SqmAttributeJoin<?, ?> ) { if ( sqmJoin instanceof SqmAttributeJoin<?, ?> ) {
final SqmAttributeJoin<?, ?> attributeJoin = (SqmAttributeJoin<?, ?>) sqmJoin; final SqmAttributeJoin<?, ?> attributeJoin = (SqmAttributeJoin<?, ?>) sqmJoin;
sb.append( sqmFrom.resolveAlias() ).append( '.' ); if ( sqmFrom instanceof SqmTreatedPath<?, ?> ) {
sb.append( ( attributeJoin ).getAttribute().getName() ); final SqmTreatedPath<?, ?> treatedPath = (SqmTreatedPath<?, ?>) sqmFrom;
sb.append( "treat(" );
sb.append( treatedPath.getWrappedPath().resolveAlias() );
sb.append( " as " ).append( treatedPath.getTreatTarget().getName() ).append( ')' );
}
else {
sb.append( sqmFrom.resolveAlias() );
}
sb.append( '.' ).append( ( attributeJoin ).getAttribute().getName() );
sb.append( ' ' ).append( sqmJoin.resolveAlias() ); sb.append( ' ' ).append( sqmJoin.resolveAlias() );
if ( attributeJoin.getJoinPredicate() != null ) { if ( attributeJoin.getJoinPredicate() != null ) {
sb.append( " on " ); sb.append( " on " );
@ -681,4 +692,10 @@ public class SqmQuerySpec<T> extends SqmQueryPart<T>
separator = ", "; separator = ", ";
} }
} }
private void appendTreatJoins(SqmFrom<?, ?> sqmFrom, StringBuilder sb) {
for ( SqmFrom<?, ?> sqmTreat : sqmFrom.getSqmTreats() ) {
appendJoins( sqmTreat, sb );
}
}
} }

View File

@ -4,20 +4,32 @@ import org.hibernate.query.spi.SqmQuery;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.Jpa; import org.hibernate.testing.orm.junit.Jpa;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Query; import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery; import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Expression; import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Join;
import jakarta.persistence.criteria.Root; import jakarta.persistence.criteria.Root;
import org.hamcrest.CoreMatchers;
import org.hamcrest.MatcherAssert;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
@Jpa( @Jpa(
annotatedClasses = ToHqlStringTest.TestEntity.class annotatedClasses = {
ToHqlStringTest.TestEntity.class,
ToHqlStringTest.TestEntitySub.class
}
) )
@TestForIssue( jiraKey = "HHH-15389") @TestForIssue( jiraKey = "HHH-15389")
public class ToHqlStringTest { public class ToHqlStringTest {
@ -60,6 +72,27 @@ public class ToHqlStringTest {
); );
} }
@Test
@JiraKey( "HHH-16676" )
public void testCriteriaWithTreatToHqlString(EntityManagerFactoryScope scope) {
scope.inTransaction(
entityManager -> {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Object> criteriaQuery = builder.createQuery( Object.class );
Root<TestEntity> root = criteriaQuery.from( TestEntity.class );
Join<Object, Object> entity = builder.treat( root, TestEntitySub.class ).join( "entity" );
criteriaQuery = criteriaQuery.select( entity );
TypedQuery<Object> query = entityManager.createQuery( criteriaQuery );
String hqlString = ( (SqmQuery) query ).getSqmStatement().toHqlString();
final int fromIndex = hqlString.indexOf( " from " );
final String alias = hqlString.substring( "select ".length(), fromIndex );
assertThat( hqlString.substring( fromIndex ), containsString( alias ) );
}
);
}
public static class TestDto { public static class TestDto {
@Id @Id
public Integer id; public Integer id;
@ -74,4 +107,10 @@ public class ToHqlStringTest {
public String name; public String name;
} }
@Entity(name = "TestEntitySub")
public static class TestEntitySub extends TestEntity {
@ManyToOne(fetch = FetchType.LAZY)
TestEntity entity;
}
} }