HHH-14213 fix query numeric literal (integer representation) parsing exception message

This commit is contained in:
Nathan Xu 2020-09-13 12:42:16 -04:00 committed by Sanne Grinovero
parent dd74a613cc
commit cadc3bf9dc
2 changed files with 56 additions and 1 deletions

View File

@ -219,12 +219,14 @@ public class LiteralProcessor implements HqlSqlTokenTypes {
} }
private String determineIntegerRepresentation(String text, int type) { private String determineIntegerRepresentation(String text, int type) {
Class<?> javaTypeClass = Integer.class;
try { try {
if ( type == NUM_BIG_INTEGER ) { if ( type == NUM_BIG_INTEGER ) {
String literalValue = text; String literalValue = text;
if ( literalValue.endsWith( "bi" ) || literalValue.endsWith( "BI" ) ) { if ( literalValue.endsWith( "bi" ) || literalValue.endsWith( "BI" ) ) {
literalValue = literalValue.substring( 0, literalValue.length() - 2 ); literalValue = literalValue.substring( 0, literalValue.length() - 2 );
} }
javaTypeClass = BigInteger.class;
return new BigInteger( literalValue ).toString(); return new BigInteger( literalValue ).toString();
} }
if ( type == NUM_INT ) { if ( type == NUM_INT ) {
@ -242,10 +244,11 @@ public class LiteralProcessor implements HqlSqlTokenTypes {
if ( literalValue.endsWith( "l" ) || literalValue.endsWith( "L" ) ) { if ( literalValue.endsWith( "l" ) || literalValue.endsWith( "L" ) ) {
literalValue = literalValue.substring( 0, literalValue.length() - 1 ); literalValue = literalValue.substring( 0, literalValue.length() - 1 );
} }
javaTypeClass = Long.class;
return Long.valueOf( literalValue ).toString(); return Long.valueOf( literalValue ).toString();
} }
catch (Throwable t) { 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 );
} }
} }

View File

@ -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;
}
}