HHH-14231 Fix ClassCastException in ScrollableResultsImpl for primitive array value

This commit is contained in:
Nathan Xu 2020-09-26 09:15:40 -04:00 committed by Sanne Grinovero
parent 77cf9d5108
commit 733ece81f4
3 changed files with 75 additions and 2 deletions

View File

@ -17,6 +17,7 @@ import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.QueryParameters;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.hql.internal.HolderInstantiator;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.loader.Loader;
import org.hibernate.type.Type;
@ -200,10 +201,10 @@ public class ScrollableResultsImpl extends AbstractScrollableResults implements
true
);
if ( result != null && result.getClass().isArray() ) {
currentRow = (Object[]) result;
currentRow = ArrayHelper.toObjectArray( result );
}
else {
currentRow = new Object[] {result};
currentRow = new Object[] { result };
}
if ( getHolderInstantiator() != null ) {

View File

@ -433,6 +433,18 @@ public final class ArrayHelper {
return trimmed;
}
public static Object[] toObjectArray(Object array) {
if ( array instanceof Object[] ) {
return ( Object[] ) array;
}
final int arrayLength = Array.getLength( array );
final Object[] outputArray = new Object[ arrayLength ];
for ( int i = 0; i < arrayLength; ++i ) {
outputArray[ i ] = Array.get( array, i );
}
return outputArray;
}
@AllowSysOut
public static void main(String... args) {
int[] batchSizes = ArrayHelper.getBatchSizes( 32 );

View File

@ -0,0 +1,60 @@
package org.hibernate.internal;
import java.util.stream.Stream;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.TypedQuery;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.TestForIssue;
import org.junit.Before;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
/**
* @author Dragoş Haiduc
* @author Nathan Xu
*/
@TestForIssue( jiraKey = "HHH-14231" )
public class ScrollableResultsObjectArrayCastingTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Product.class };
}
@Before
public void SetUp() {
doInJPA( this::entityManagerFactory, entityManager -> {
Product product = new Product();
product.binaryValue = "".getBytes();
entityManager.persist( product );
} );
}
@Test
public void testNoClassCastExceptionThrown() {
doInJPA( this::entityManagerFactory, entityManager -> {
TypedQuery<byte[]> typedQuery = entityManager.createQuery( "select p.binaryValue from Product p", byte[].class );
Stream<byte[]> stream = typedQuery.getResultStream();
stream.findFirst();
} );
}
@Entity(name = "Product")
public static class Product {
@Id @GeneratedValue
Integer id;
String name;
@Lob
byte[] binaryValue;
}
}