HHH-13889 fix the issue that inline string literal in Criteria is not escaped

This commit is contained in:
Nathan Xu 2020-03-14 15:25:36 -04:00 committed by Andrea Boriero
parent 716a8bac20
commit 5f83662226
2 changed files with 60 additions and 1 deletions

View File

@ -8,6 +8,7 @@ package org.hibernate.query.criteria.internal.expression;
import java.io.Serializable;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.query.criteria.LiteralHandlingMode;
import org.hibernate.query.criteria.internal.CriteriaBuilderImpl;
import org.hibernate.query.criteria.internal.ParameterRegistry;
@ -118,7 +119,7 @@ public class LiteralExpression<T> extends ExpressionImpl<T> implements Serializa
}
if ( ValueHandlerFactory.isCharacter( literal ) ) {
return '\'' + handler.render( literal ) + '\'';
return renderingContext.getDialect().inlineLiteral( handler.render( literal ) );
}
else {
return handler.render( literal );

View File

@ -0,0 +1,58 @@
package org.hibernate.query.criteria;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.Id;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Root;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
/**
* @author Michiel Haisma
* @author Nathan Xu
*/
@TestForIssue( jiraKey = "HHH-13889" )
public class CriteriaStringInlineLiteralTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Animal.class };
}
@Test
public void testCriteriaInlineStringLiteralRendering() {
EntityManager entityManager = getOrCreateEntityManager();
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Animal> criteriaQuery = cb.createQuery( Animal.class );
Root<Animal> animalRoot = criteriaQuery.from( Animal.class );
CriteriaBuilder.Case<String> sCase = cb.selectCase();
Expression<String> caseSelect =
sCase.when( cb.equal( animalRoot.get( "name" ), cb.literal( "kitty" ) ), cb.literal( "Cat" ) )
.otherwise("escapez'moi" );
criteriaQuery.multiselect( caseSelect );
criteriaQuery.where( cb.equal( animalRoot.get( "name" ), "myFavoriteAnimal" ) );
entityManager.createQuery( criteriaQuery); // would throw exception for unescaped otherwise literal in HHH-13889
}
@Entity(name = "Animal")
public static class Animal {
@Id
private Long id;
private String name;
public Animal() {
}
public Animal(String name) {
this.name = name;
}
}
}