From f91ed82757ec722072f6fb747c4cb6a6a23a4426 Mon Sep 17 00:00:00 2001 From: Nathan Xu Date: Sun, 13 Sep 2020 12:42:16 -0400 Subject: [PATCH] HHH-14213 fix query numeric literal (integer representation) parsing exception message --- .../internal/ast/util/LiteralProcessor.java | 5 +- ...esentationLiteralParsingExceptionTest.java | 52 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/query/IntegerRepresentationLiteralParsingExceptionTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/LiteralProcessor.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/LiteralProcessor.java index 147531dd2c..480a653aba 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/LiteralProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/LiteralProcessor.java @@ -219,12 +219,14 @@ public class LiteralProcessor implements HqlSqlTokenTypes { } private String determineIntegerRepresentation(String text, int type) { + Class javaTypeClass = Integer.class; try { if ( type == NUM_BIG_INTEGER ) { String literalValue = text; if ( literalValue.endsWith( "bi" ) || literalValue.endsWith( "BI" ) ) { literalValue = literalValue.substring( 0, literalValue.length() - 2 ); } + javaTypeClass = BigInteger.class; return new BigInteger( literalValue ).toString(); } if ( type == NUM_INT ) { @@ -242,10 +244,11 @@ public class LiteralProcessor implements HqlSqlTokenTypes { if ( literalValue.endsWith( "l" ) || literalValue.endsWith( "L" ) ) { literalValue = literalValue.substring( 0, literalValue.length() - 1 ); } + javaTypeClass = Long.class; return Long.valueOf( literalValue ).toString(); } catch (Throwable t) { - throw new HibernateException( "Could not parse literal [" + text + "] as integer", t ); + throw new HibernateException( "Could not parse literal [" + text + "] as " + javaTypeClass.getName(), t ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/query/IntegerRepresentationLiteralParsingExceptionTest.java b/hibernate-core/src/test/java/org/hibernate/query/IntegerRepresentationLiteralParsingExceptionTest.java new file mode 100644 index 0000000000..66b27504df --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/query/IntegerRepresentationLiteralParsingExceptionTest.java @@ -0,0 +1,52 @@ +package org.hibernate.query; + +import javax.persistence.Entity; +import javax.persistence.Id; + +import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; + +import org.hibernate.testing.TestForIssue; +import org.junit.Assert; +import org.junit.Test; + +import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; + +/** + * @author Andrias Sundskar + * @author Nathan Xu + */ +@TestForIssue( jiraKey = "HHH-14213" ) +public class IntegerRepresentationLiteralParsingExceptionTest extends BaseEntityManagerFunctionalTestCase { + + @Override + public Class[] getAnnotatedClasses() { + return new Class[] { ExampleEntity.class }; + } + + @Test + public void testAppropriateExceptionMessageGenerated() { + try { + doInJPA( this::entityManagerFactory, entityManager -> { + // -9223372036854775808 is beyond Long range, so an Exception will be thrown + entityManager.createQuery( "select count(*) from ExampleEntity where counter = -9223372036854775808L" ) + .getSingleResult(); + } ); + Assert.fail( "Exception should be thrown" ); + } + catch (Exception e) { + // without fixing HHH-14213, the following exception would be thrown: + // "Could not parse literal [9223372036854775808L] as integer" + // which is confusing and misleading + Assert.assertTrue( e.getMessage().endsWith( " as java.lang.Long" ) ); + } + } + + @Entity(name = "ExampleEntity") + static class ExampleEntity { + + @Id + int id; + + long counter; + } +}