HHH-12537: Query hint test for SAP HANA

- add org.hibernate.test.queryhint.QueryHintHANATest
This commit is contained in:
Jonathan Bregler 2018-05-02 13:06:00 +02:00 committed by Vlad Mihalcea
parent 1651c804fb
commit 8fcdbb35e6
1 changed files with 198 additions and 0 deletions

View File

@ -0,0 +1,198 @@
/*
* 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.test.queryhint;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.util.List;
import java.util.Map;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import org.hibernate.Criteria;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.criterion.Restrictions;
import org.hibernate.dialect.AbstractHANADialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.Query;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
/**
* @author Jonathan Bregler
*/
@RequiresDialect(AbstractHANADialect.class)
public class QueryHintHANATest extends BaseNonConfigCoreFunctionalTestCase {
private PreparedStatementSpyConnectionProvider connectionProvider;
@Override
protected void addSettings(Map settings) {
settings.put( AvailableSettings.USE_SQL_COMMENTS, "true" );
settings.put(
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
connectionProvider );
}
@Override
protected void buildResources() {
connectionProvider = new PreparedStatementSpyConnectionProvider( false, false );
super.buildResources();
}
@Override
public void releaseResources() {
super.releaseResources();
connectionProvider.stop();
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[]{ Employee.class, Department.class };
}
@Override
protected void afterSessionFactoryBuilt(SessionFactoryImplementor sessionFactory) {
Department department = new Department();
department.name = "Sales";
Employee employee1 = new Employee();
employee1.department = department;
Employee employee2 = new Employee();
employee2.department = department;
doInHibernate( this::sessionFactory, s -> {
s.persist( department );
s.persist( employee1 );
s.persist( employee2 );
} );
}
@Test
public void testQueryHint() {
connectionProvider.clear();
doInHibernate( this::sessionFactory, s -> {
Query<Employee> query = s.createQuery( "FROM QueryHintHANATest$Employee e WHERE e.department.name = :departmentName", Employee.class )
.addQueryHint( "NO_CS_JOIN" )
.setParameter( "departmentName", "Sales" );
List<Employee> results = query.list();
assertEquals( results.size(), 2 );
} );
assertEquals(
1,
connectionProvider.getPreparedStatements().size() );
assertThat( connectionProvider.getPreparedSQLStatements().get( 0 ), containsString( " with hint (NO_CS_JOIN)" ) );
connectionProvider.clear();
// test multiple hints
doInHibernate( this::sessionFactory, s -> {
Query<Employee> query = s.createQuery( "FROM QueryHintHANATest$Employee e WHERE e.department.name = :departmentName", Employee.class )
.addQueryHint( "NO_CS_JOIN" )
.addQueryHint( "OPTIMIZE_METAMODEL" )
.setParameter( "departmentName", "Sales" );
List<Employee> results = query.list();
assertEquals( results.size(), 2 );
} );
assertEquals(
1,
connectionProvider.getPreparedStatements().size() );
assertThat( connectionProvider.getPreparedSQLStatements().get( 0 ), containsString( " with hint (NO_CS_JOIN,OPTIMIZE_METAMODEL)" ) );
connectionProvider.clear();
// ensure the insertion logic can handle a comment appended to the front
doInHibernate( this::sessionFactory, s -> {
Query<Employee> query = s.createQuery( "FROM QueryHintHANATest$Employee e WHERE e.department.name = :departmentName", Employee.class )
.setComment( "this is a test" )
.addQueryHint( "NO_CS_JOIN" )
.setParameter( "departmentName", "Sales" );
List<Employee> results = query.list();
assertEquals( results.size(), 2 );
} );
assertEquals(
1,
connectionProvider.getPreparedStatements().size() );
assertThat( connectionProvider.getPreparedSQLStatements().get( 0 ), containsString( " with hint (NO_CS_JOIN)" ) );
connectionProvider.clear();
// test Criteria
doInHibernate( this::sessionFactory, s -> {
Criteria criteria = s.createCriteria( Employee.class )
.addQueryHint( "NO_CS_JOIN" )
.createCriteria( "department" ).add( Restrictions.eq( "name", "Sales" ) );
List<?> results = criteria.list();
assertEquals( results.size(), 2 );
} );
assertEquals(
1,
connectionProvider.getPreparedStatements().size() );
assertThat( connectionProvider.getPreparedSQLStatements().get( 0 ), containsString( " with hint (NO_CS_JOIN)" ) );
connectionProvider.clear();
}
@Test
@TestForIssue(jiraKey = "HHH-12362")
public void testQueryHintAndComment() {
connectionProvider.clear();
doInHibernate( this::sessionFactory, s -> {
Query<Employee> query = s.createQuery( "FROM QueryHintHANATest$Employee e WHERE e.department.name = :departmentName", Employee.class )
.addQueryHint( "NO_CS_JOIN" )
.setComment( "My_Query" )
.setParameter( "departmentName", "Sales" );
List<Employee> results = query.list();
assertEquals( results.size(), 2 );
} );
assertEquals(
1,
connectionProvider.getPreparedStatements().size() );
assertThat( connectionProvider.getPreparedSQLStatements().get( 0 ), containsString( " with hint (NO_CS_JOIN)" ) );
assertThat( connectionProvider.getPreparedSQLStatements().get( 0 ), containsString( "/* My_Query */ select" ) );
connectionProvider.clear();
}
@Entity
public static class Employee {
@Id
@GeneratedValue
public long id;
@ManyToOne(fetch = FetchType.LAZY)
public Department department;
}
@Entity
public static class Department {
@Id
@GeneratedValue
public long id;
public String name;
}
}