HHH-16182 Fix some tests for older databases and adapt assertion for boolean function

This commit is contained in:
Christian Beikov 2023-03-02 21:53:38 +01:00
parent 2a017db0bc
commit 1bd0180172
3 changed files with 50 additions and 48 deletions

View File

@ -10,6 +10,8 @@ import java.sql.Types;
import org.hibernate.boot.model.FunctionContributions; import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.boot.model.FunctionContributor; import org.hibernate.boot.model.FunctionContributor;
import org.hibernate.dialect.AbstractHANADialect;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.OracleDialect; import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.SQLServerDialect; import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.SybaseASEDialect; import org.hibernate.dialect.SybaseASEDialect;
@ -330,16 +332,7 @@ public class BooleanMappingTests {
return result.intValue(); return result.intValue();
} }
/**
* @implNote Skipped for dialects without support for boolean (predicate) expressions. The test
* is really about handling the SQM function reference anyway; the actual Dialect implementation
* is not standard.
*/
@Test @Test
@SkipForDialect(dialectClass = OracleDialect.class)
@SkipForDialect(dialectClass = SybaseDialect.class)
@SkipForDialect(dialectClass = SybaseASEDialect.class)
@SkipForDialect(dialectClass = SQLServerDialect.class)
public void testBooleanFunctionAsPredicate(SessionFactoryScope scope) { public void testBooleanFunctionAsPredicate(SessionFactoryScope scope) {
// Not strictly relevant to boolean mappings, but test that boolean // Not strictly relevant to boolean mappings, but test that boolean
// functions work *as a* predicate after HHH-16182 // functions work *as a* predicate after HHH-16182
@ -351,20 +344,20 @@ public class BooleanMappingTests {
} ); } );
assertThat( statementInspector.getSqlQueries().size(), equalTo( 1 ) ); assertThat( statementInspector.getSqlQueries().size(), equalTo( 1 ) );
assertThat( statementInspector.getSqlQueries().get( 0 ), containsString( "(1=1)" ) ); assertThat( statementInspector.getSqlQueries().get( 0 ), containsString( "where (1=1) or (2=2)" ) );
assertThat( statementInspector.getSqlQueries().get( 0 ), containsString( "(2=2)" ) );
} }
/** /**
* @implNote Skipped for dialects without support for boolean (predicate) expressions. The test * @implNote Skipped for dialects without support for comparing a boolean predicate against a boolean expressions,
* is really about handling the SQM function reference anyway; the actual Dialect implementation * i.e. `(1=1)=true`. The test is really about handling the SQM function reference anyway;
* is not standard. * the actual Dialect implementation is not standard.
*/ */
@Test @Test
@SkipForDialect(dialectClass = OracleDialect.class) @SkipForDialect(dialectClass = OracleDialect.class)
@SkipForDialect(dialectClass = SybaseDialect.class)
@SkipForDialect(dialectClass = SybaseASEDialect.class)
@SkipForDialect(dialectClass = SQLServerDialect.class) @SkipForDialect(dialectClass = SQLServerDialect.class)
@SkipForDialect(dialectClass = SybaseDialect.class, matchSubTypes = true)
@SkipForDialect(dialectClass = AbstractHANADialect.class, matchSubTypes = true)
@SkipForDialect(dialectClass = DB2Dialect.class, majorVersion = 10)
public void testBooleanFunctionInPredicate(SessionFactoryScope scope) { public void testBooleanFunctionInPredicate(SessionFactoryScope scope) {
// Not strictly relevant to boolean mappings, but test that boolean // Not strictly relevant to boolean mappings, but test that boolean
// functions work *in a* predicate after HHH-16182 // functions work *in a* predicate after HHH-16182

View File

@ -7058,21 +7058,30 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
@Override @Override
public Object visitBooleanExpressionPredicate(SqmBooleanExpressionPredicate predicate) { public Object visitBooleanExpressionPredicate(SqmBooleanExpressionPredicate predicate) {
final Expression booleanExpression = (Expression) predicate.getBooleanExpression().accept( this ); final Expression booleanExpression = (Expression) predicate.getBooleanExpression().accept( this );
final JdbcMapping jdbcMapping = booleanExpression.getExpressionType().getJdbcMapping( 0 ); if ( booleanExpression instanceof SelfRenderingExpression ) {
if ( jdbcMapping.getValueConverter() != null ) { final Predicate sqlPredicate = new SelfRenderingPredicate( (SelfRenderingExpression) booleanExpression );
// handle converted booleans (yes-no, etc) if ( predicate.isNegated() ) {
return new ComparisonPredicate( return new NegatedPredicate( sqlPredicate );
}
return sqlPredicate;
}
else {
final JdbcMapping jdbcMapping = booleanExpression.getExpressionType().getJdbcMapping( 0 );
if ( jdbcMapping.getValueConverter() != null ) {
// handle converted booleans (yes-no, etc)
return new ComparisonPredicate(
booleanExpression,
ComparisonOperator.EQUAL,
new JdbcLiteral<>( jdbcMapping.convertToRelationalValue( !predicate.isNegated() ), jdbcMapping )
);
}
return new BooleanExpressionPredicate(
booleanExpression, booleanExpression,
ComparisonOperator.EQUAL, predicate.isNegated(),
new JdbcLiteral<>( jdbcMapping.convertToRelationalValue( !predicate.isNegated() ), jdbcMapping ) getBooleanType()
); );
} }
return new BooleanExpressionPredicate(
booleanExpression,
predicate.isNegated(),
getBooleanType()
);
} }
@Override @Override

View File

@ -23,9 +23,11 @@ import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne; import jakarta.persistence.OneToOne;
import jakarta.persistence.Version; import jakarta.persistence.Version;
import org.hibernate.annotations.Cache; import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase; import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.TestForIssue; import org.hibernate.testing.TestForIssue;
import org.junit.Test; import org.junit.Test;
@ -33,7 +35,7 @@ public class CacheableEntityGraphTest extends BaseEntityManagerFunctionalTestCas
@Override @Override
protected Class<?>[] getAnnotatedClasses() { protected Class<?>[] getAnnotatedClasses() {
return new Class[]{Product.class, Color.class, Tag.class}; return new Class[] { Product.class, Color.class, Tag.class };
} }
@Test @Test
@ -42,34 +44,32 @@ public class CacheableEntityGraphTest extends BaseEntityManagerFunctionalTestCas
EntityManager em = getOrCreateEntityManager(); EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin(); em.getTransaction().begin();
Tag tag = new Tag(Set.of(TagType.FOO)); Tag tag = new Tag( Set.of( TagType.FOO ) );
em.persist(tag); em.persist( tag );
Color color = new Color(); Color color = new Color();
em.persist(color); em.persist( color );
Product product = new Product(tag, color); Product product = new Product( tag, color );
em.persist(product); em.persist( product );
em.getTransaction().commit(); em.getTransaction().commit();
em.clear(); em.clear();
EntityGraph<Product> entityGraph = em.createEntityGraph(Product.class); EntityGraph<Product> entityGraph = em.createEntityGraph( Product.class );
entityGraph.addAttributeNodes("tag"); entityGraph.addAttributeNodes( "tag" );
em.createQuery( em.createQuery( "select p from Product p", Product.class )
"select p from org.hibernate.orm.test.jpa.graphs.CacheableEntityGraphTest$Product p", .setMaxResults( 2 )
Product.class) .setHint( "jakarta.persistence.loadgraph", entityGraph )
.setMaxResults(2)
.setHint("jakarta.persistence.loadgraph", entityGraph)
.getSingleResult(); .getSingleResult();
} }
@Entity @Entity(name = "Product")
public static class Product { public static class Product {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue
public int id; public int id;
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@ -87,11 +87,11 @@ public class CacheableEntityGraphTest extends BaseEntityManagerFunctionalTestCas
} }
} }
@Entity @Entity(name = "Color")
public static class Color { public static class Color {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue
public int id; public int id;
@OneToOne(fetch = FetchType.LAZY) @OneToOne(fetch = FetchType.LAZY)
@ -99,11 +99,11 @@ public class CacheableEntityGraphTest extends BaseEntityManagerFunctionalTestCas
} }
@Cacheable @Cacheable
@Entity @Entity(name = "Tag")
public static class Tag { public static class Tag {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue
public int id; public int id;
@Version @Version
@ -118,7 +118,7 @@ public class CacheableEntityGraphTest extends BaseEntityManagerFunctionalTestCas
} }
public Tag(Set<TagType> types) { public Tag(Set<TagType> types) {
this.types.addAll(types); this.types.addAll( types );
} }
} }