HHH-10382 - GetterFieldImpl creates unnecessary objects

This commit is contained in:
Andrej Golovnin 2015-12-16 21:04:06 +01:00 committed by Vlad Mihalcea
parent 2d8e9d66e2
commit 58303884bd
2 changed files with 78 additions and 0 deletions

View File

@ -14,6 +14,7 @@ import java.lang.reflect.Method;
import java.util.Locale;
import java.util.Map;
import org.hibernate.boot.archive.internal.ByteArrayInputStreamAccess;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.property.access.internal.AbstractFieldSerialForm;
@ -36,6 +37,29 @@ public class GetterFieldImpl implements Getter {
@Override
public Object get(Object owner) {
try {
// This is needed because until JDK 9 the Reflection API
// does not use the same caching as used for auto-boxing.
// See https://bugs.openjdk.java.net/browse/JDK-5043030 for details.
// The code below can be removed when we move to JDK 9.
// double and float are intentionally not handled here because
// the JLS § 5.1.7 does not define caching for boxed values of
// this types.
Class<?> type = field.getType();
if ( type.isPrimitive() ) {
if ( type == Boolean.TYPE ) {
return Boolean.valueOf( field.getBoolean( owner ) );
} else if ( type == Byte.TYPE ) {
return Byte.valueOf( field.getByte( owner ) );
} else if ( type == Character.TYPE ) {
return Character.valueOf( field.getChar( owner ) );
} else if ( type == Integer.TYPE ) {
return Integer.valueOf( field.getInt( owner ) );
} else if ( type == Long.TYPE ) {
return Long.valueOf( field.getLong( owner ) );
} else if ( type == Short.TYPE ) {
return Short.valueOf( field.getShort( owner ) );
}
}
return field.get( owner );
}
catch (Exception e) {

View File

@ -0,0 +1,54 @@
package org.hibernate.property.access.spi;
import java.lang.reflect.Field;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* @author Vlad Mihalcea
*/
public class GetterFieldImplTest {
@Test
public void testGet() throws Exception {
Target target = new Target();
assertEquals( true, getter( "active" ).get( target ) );
assertEquals( (byte) 2, getter( "children" ).get( target ) );
assertEquals( 'M', getter( "gender" ).get( target ) );
assertEquals( Integer.MAX_VALUE, getter( "code" ).get( target ) );
assertEquals( Long.MAX_VALUE, getter( "id" ).get( target ) );
assertEquals( (short) 34, getter( "age" ).get( target ) );
assertEquals( "John Doe", getter( "name" ).get( target ) );
}
private static class Target {
private boolean active = true;
private byte children = 2;
private char gender = 'M';
private int code = Integer.MAX_VALUE;
private long id = Long.MAX_VALUE;
private short age = 34;
private String name = "John Doe";
}
private Getter getter(String property) {
try {
Field field = Target.class.getDeclaredField( property );
field.setAccessible( true );
return new GetterFieldImpl( Target.class, property, field );
}
catch (NoSuchFieldException e) {
throw new IllegalArgumentException( e );
}
}
}