HHH-11393 - Hibernate/JPA CriteriaQuery trim function generate wrong SQL

This commit is contained in:
Andrea Boriero 2017-01-13 16:47:27 +00:00 committed by Vlad Mihalcea
parent c0d5fe9153
commit 4dad087b39
2 changed files with 120 additions and 105 deletions

View File

@ -107,8 +107,8 @@ public class TrimFunction
LiteralExpression.class ) ) {
// If the character is a literal, treat it as one. A few dialects
// do not support parameters as trim() arguments.
renderedTrimChar = ( ( LiteralExpression<Character> )
trimCharacter ).getLiteral().toString();
renderedTrimChar = '\'' + ( (LiteralExpression<Character>)
trimCharacter ).getLiteral().toString() + '\'';
}
else {
renderedTrimChar = ( (Renderable) trimCharacter ).render(

View File

@ -12,6 +12,7 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.TypedQuery;
@ -43,10 +44,16 @@ import org.hibernate.jpa.test.metamodel.Product;
import org.hibernate.jpa.test.metamodel.ShelfLife;
import org.hibernate.jpa.test.metamodel.Spouse;
import org.hibernate.testing.BeforeClassOnce;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.transaction.TransactionUtil;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
/**
* @author Steve Ebersole
*/
@ -76,149 +83,153 @@ public class CriteriaCompilingTest extends BaseEntityManagerFunctionalTestCase {
};
}
@Test
public void testTrim() {
final String expectedResult = "David R. Vincent";
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
Customer customer = new Customer( );
customer.setId( "id" );
customer.setName( " David R. Vincent " );
em.persist( customer );
em.getTransaction().commit();
em.close();
@Before
public void setUp(){
TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
Customer customer = new Customer();
customer.setId( "id" );
customer.setName( " David R. Vincent " );
entityManager.persist( customer );
customer = new Customer();
customer.setId( "id2" );
customer.setName( "R Vincent" );
entityManager.persist( customer );
} );
}
em = getOrCreateEntityManager();
@Test
public void testTrim() {
final String expectedResult = "David R. Vincent";
TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
EntityTransaction et = em.getTransaction();
et.begin();
CriteriaQuery<String> cquery = cb.createQuery( String.class );
Root<Customer> cust = cquery.from( Customer.class );
CriteriaQuery<String> cquery = cb.createQuery( String.class );
Root<Customer> cust = cquery.from( Customer.class );
//Get Metamodel from Root
EntityType<Customer> Customer_ = cust.getModel();
//Get Metamodel from Root
EntityType<Customer> Customer_ = cust.getModel();
cquery.where(
cb.equal(
cust.get( Customer_.getSingularAttribute( "name", String.class ) ),
cb.literal( " David R. Vincent " )
)
);
cquery.select(
cb.trim(
CriteriaBuilder.Trimspec.BOTH,
cust.get( Customer_.getSingularAttribute( "name", String.class ) )
)
);
cquery.where(
cb.equal(
cust.get( Customer_.getSingularAttribute( "name", String.class ) ),
cb.literal( " David R. Vincent " )
)
);
cquery.select(
cb.trim(
CriteriaBuilder.Trimspec.BOTH,
cust.get( Customer_.getSingularAttribute( "name", String.class ) )
)
);
TypedQuery<String> tq = entityManager.createQuery( cquery );
String result = tq.getSingleResult();
Assert.assertEquals( "Mismatch in received results", expectedResult, result );
} );
}
TypedQuery<String> tq = em.createQuery( cquery );
@Test
@TestForIssue(jiraKey = "HHH-11393")
public void testTrimAChar() {
TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Customer> query = criteriaBuilder.createQuery( Customer.class );
final Root<Customer> from = query.from( Customer.class );
query.select( from );
String result = tq.getSingleResult();
et.commit();
em.close();
Assert.assertEquals( "Mismatch in received results", expectedResult, result );
}
query.where( criteriaBuilder.equal( criteriaBuilder.trim(
CriteriaBuilder.Trimspec.LEADING,
criteriaBuilder.literal( 'R' ),
from.get( "name" )
), " Vincent" ) );
List<Customer> resultList = entityManager.createQuery( query ).getResultList();
assertThat( resultList.size(), is( 1 ) );
} );
}
@Test
public void testJustSimpleRootCriteria() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
// First w/o explicit selection...
CriteriaQuery<Customer> criteria = entityManager.getCriteriaBuilder().createQuery( Customer.class );
criteria.from( Customer.class );
entityManager.createQuery( criteria ).getResultList();
// First w/o explicit selection...
CriteriaQuery<Customer> criteria = em.getCriteriaBuilder().createQuery( Customer.class );
criteria.from( Customer.class );
em.createQuery( criteria ).getResultList();
// Now with...
criteria = em.getCriteriaBuilder().createQuery( Customer.class );
Root<Customer> root = criteria.from( Customer.class );
criteria.select( root );
em.createQuery( criteria ).getResultList();
em.getTransaction().commit();
em.close();
// Now with...
criteria = entityManager.getCriteriaBuilder().createQuery( Customer.class );
Root<Customer> root = criteria.from( Customer.class );
criteria.select( root );
entityManager.createQuery( criteria ).getResultList();
});
}
@Test
public void testSimpleJoinCriteria() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
// String based...
CriteriaQuery<Order> criteria = em.getCriteriaBuilder().createQuery( Order.class );
Root<Order> root = criteria.from( Order.class );
root.join( "lineItems" );
criteria.select( root );
em.createQuery( criteria ).getResultList();
em.getTransaction().commit();
em.close();
// String based...
CriteriaQuery<Order> criteria = entityManager.getCriteriaBuilder().createQuery( Order.class );
Root<Order> root = criteria.from( Order.class );
root.join( "lineItems" );
criteria.select( root );
entityManager.createQuery( criteria ).getResultList();
});
}
@Test
public void testSimpleFetchCriteria() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
// String based...
CriteriaQuery<Order> criteria = em.getCriteriaBuilder().createQuery( Order.class );
Root<Order> root = criteria.from( Order.class );
root.fetch( "lineItems" );
criteria.select( root );
em.createQuery( criteria ).getResultList();
em.getTransaction().commit();
em.close();
// String based...
CriteriaQuery<Order> criteria = entityManager.getCriteriaBuilder().createQuery( Order.class );
Root<Order> root = criteria.from( Order.class );
root.fetch( "lineItems" );
criteria.select( root );
entityManager.createQuery( criteria ).getResultList();
} );
}
@Test
public void testSerialization() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
CriteriaQuery<Order> criteria = em.getCriteriaBuilder().createQuery( Order.class );
Root<Order> root = criteria.from( Order.class );
root.fetch( "lineItems" );
criteria.select( root );
CriteriaQuery<Order> criteria = entityManager.getCriteriaBuilder().createQuery( Order.class );
Root<Order> root = criteria.from( Order.class );
root.fetch( "lineItems" );
criteria.select( root );
criteria = serializeDeserialize( criteria );
criteria = serializeDeserialize( criteria );
em.createQuery( criteria ).getResultList();
em.getTransaction().commit();
em.close();
entityManager.createQuery( criteria ).getResultList();
} );
}
@Test
@TestForIssue(jiraKey = "HHH-10960")
public void testDeprecation() {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
Session session = em.unwrap( Session.class );
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Order> query = builder.createQuery( Order.class );
Root<Order> from = query.from( Order.class );
query.orderBy( builder.desc( from.get( "totalPrice" )));
TypedQuery<Order> jpaQuery = session.createQuery( query );
org.hibernate.query.Query<?> hibQuery = jpaQuery.unwrap( org.hibernate.query.Query.class );
Session session = entityManager.unwrap( Session.class );
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Order> query = builder.createQuery( Order.class );
Root<Order> from = query.from( Order.class );
query.orderBy( builder.desc( from.get( "totalPrice" ) ) );
TypedQuery<Order> jpaQuery = session.createQuery( query );
org.hibernate.query.Query<?> hibQuery = jpaQuery.unwrap( org.hibernate.query.Query.class );
ScrollableResults sr = hibQuery.scroll( ScrollMode.FORWARD_ONLY );
ScrollableResults sr = hibQuery.scroll( ScrollMode.FORWARD_ONLY );
hibQuery.setCacheMode( CacheMode.IGNORE ).scroll( ScrollMode.FORWARD_ONLY );
hibQuery.setCacheMode( CacheMode.IGNORE ).scroll( ScrollMode.FORWARD_ONLY );
org.hibernate.query.Query<Order> anotherQuery = session.createQuery( "select o from Order o where totalPrice in :totalPrices", Order.class );
anotherQuery.setParameterList( "totalPrices", Arrays.asList(12.5d, 14.6d) );
em.getTransaction().commit();
em.close();
org.hibernate.query.Query<Order> anotherQuery = session.createQuery(
"select o from Order o where totalPrice in :totalPrices",
Order.class
);
anotherQuery.setParameterList( "totalPrices", Arrays.asList( 12.5d, 14.6d ) );
});
}
@SuppressWarnings( {"unchecked"})
@ -243,4 +254,8 @@ public class CriteriaCompilingTest extends BaseEntityManagerFunctionalTestCase {
return serializedObject;
}
@Override
public void releaseResources() {
super.releaseResources();
}
}