HHH-16003 Add test for issue

This commit is contained in:
Marco Belladelli 2023-01-30 18:23:43 +01:00 committed by Christian Beikov
parent 5e8b43edf9
commit 7db2dd9d60
1 changed files with 228 additions and 0 deletions

View File

@ -0,0 +1,228 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.query.hql;
import java.io.Serializable;
import java.time.LocalDateTime;
import org.hibernate.testing.jdbc.SQLStatementInspector;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import jakarta.persistence.AttributeOverride;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.TypedQuery;
import static java.util.Objects.requireNonNull;
import static java.util.UUID.randomUUID;
import static org.junit.jupiter.api.Assertions.assertNotNull;
/**
* @author Marco Belladelli
*/
@SessionFactory(useCollectingStatementInspector = true)
@DomainModel(annotatedClasses = SameTableAliasInSubqueryWithEmbeddedTest.MasterDataFileEntity.class)
public class SameTableAliasInSubqueryWithEmbeddedTest {
@BeforeAll
public void setUp(SessionFactoryScope scope) {
scope.inTransaction( session -> {
final MasterDataMetaData metadata1 = new MasterDataMetaData(
"SYSTEM",
"AT",
TransportMode.INTERNATIONAL,
"EUR",
"NESTED_1"
);
final MasterDataFileEntity entity1 = new MasterDataFileEntity(
new PrimaryKey(),
metadata1,
LocalDateTime.now(),
MasterDataImportStatus.SUCCESS
);
session.persist( entity1 );
final MasterDataMetaData metadata2 = new MasterDataMetaData(
"PREMIUM",
"DE",
TransportMode.DOMESTIC,
"EUR",
"NESTED_2"
);
final MasterDataFileEntity entity2 = new MasterDataFileEntity(
new PrimaryKey(),
metadata2,
LocalDateTime.now(),
MasterDataImportStatus.SUCCESS
);
session.persist( entity2 );
} );
}
@AfterAll
public void tearDown(SessionFactoryScope scope) {
scope.inTransaction(
session -> session.createMutationQuery( "delete from MasterDataFileEntity" ).executeUpdate()
);
}
@Test
public void test(SessionFactoryScope scope) {
final String jpql =
"select mdf.id from MasterDataFileEntity as mdf " +
"where mdf.dataImportStatus = 'SUCCESS' " +
" and mdf.metaData.country = :countryCode " +
" and mdf.metaData.nestedEmbeddable.nestedProperty = :nested " +
" and mdf.importFinishedAt = " +
" (select max(mdf.importFinishedAt) from MasterDataFileEntity as mdf " +
" where mdf.dataImportStatus = 'SUCCESS' " +
" and mdf.metaData.country = :countryCode " +
" and mdf.metaData.nestedEmbeddable.nestedProperty = :nested)";
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
statementInspector.clear();
scope.inTransaction( session -> {
TypedQuery<PrimaryKey> query = session.createQuery( jpql, PrimaryKey.class );
query.setParameter( "countryCode", "DE" );
query.setParameter( "nested", "NESTED_2" );
assertNotNull( query.getSingleResult() );
statementInspector.assertNumberOfOccurrenceInQueryNoSpace( 0, "m1_0", 6 );
statementInspector.assertNumberOfOccurrenceInQueryNoSpace( 0, "m2_0", 5 );
} );
}
@Test
public void testNestedOnly(SessionFactoryScope scope) {
final String jpql =
"select mdf.id from MasterDataFileEntity as mdf " +
"where mdf.metaData.nestedEmbeddable.nestedProperty = :nested " +
" and mdf.importFinishedAt = " +
" (select max(mdf.importFinishedAt) from MasterDataFileEntity as mdf " +
" where mdf.metaData.nestedEmbeddable.nestedProperty = :nested)";
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
statementInspector.clear();
scope.inTransaction( session -> {
TypedQuery<PrimaryKey> query = session.createQuery( jpql, PrimaryKey.class );
query.setParameter( "nested", "NESTED_2" );
assertNotNull( query.getSingleResult() );
statementInspector.assertNumberOfOccurrenceInQueryNoSpace( 0, "m1_0", 4 );
statementInspector.assertNumberOfOccurrenceInQueryNoSpace( 0, "m2_0", 3 );
} );
}
@Embeddable
public static class PrimaryKey implements Serializable {
private String value;
public PrimaryKey() {
value = randomUUID().toString();
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
public enum TransportMode {
DOMESTIC, INTERNATIONAL;
}
@Embeddable
public static class NestedEmbeddable {
private String nestedProperty;
public NestedEmbeddable() {
}
public NestedEmbeddable(String nestedProperty) {
this.nestedProperty = nestedProperty;
}
}
@Embeddable
public static class MasterDataMetaData {
private String country;
@Enumerated(EnumType.STRING)
private TransportMode transportMode;
private String product;
private String currencyCode;
@Embedded
private NestedEmbeddable nestedEmbeddable;
protected MasterDataMetaData() {
}
public MasterDataMetaData(
String product,
String country,
TransportMode transportMode,
String currencyCode,
String nestedProperty) {
this.product = requireNonNull( product, "Product must not be null" );
this.country = requireNonNull( country, "Country must not be null" );
this.transportMode = requireNonNull( transportMode, "TransportMode must not be null" );
this.currencyCode = requireNonNull( currencyCode, "CurrencyCode must not be null" );
this.nestedEmbeddable = new NestedEmbeddable( nestedProperty );
}
}
public enum MasterDataImportStatus {
CREATED, FAILED, SUCCESS;
}
@Entity(name = "MasterDataFileEntity")
@Table(name = "MasterDataFileEntity")
public static class MasterDataFileEntity {
@Id
@AttributeOverride(name = "value", column = @Column(name = "id", nullable = false, length = 36))
private PrimaryKey id;
@Embedded
private MasterDataMetaData metaData;
private LocalDateTime importFinishedAt;
@Enumerated(EnumType.STRING)
private MasterDataImportStatus dataImportStatus;
protected MasterDataFileEntity() {
}
public MasterDataFileEntity(
PrimaryKey id,
MasterDataMetaData metaData,
LocalDateTime importFinishedAt,
MasterDataImportStatus dataImportStatus) {
this.id = id;
this.metaData = metaData;
this.importFinishedAt = importFinishedAt;
this.dataImportStatus = dataImportStatus;
}
public PrimaryKey getId() {
return id;
}
}
}