HHH-12579 Use the field description with type variables resolved to cast the return value of the $$_hibernate_read_<property>() method
This commit is contained in:
parent
b4c720871f
commit
c0652a5359
|
@ -24,19 +24,22 @@ abstract class FieldReaderAppender implements ByteCodeAppender {
|
|||
|
||||
protected final TypeDescription managedCtClass;
|
||||
|
||||
protected final FieldDescription persistentFieldAsDefined;
|
||||
protected final FieldDescription persistentField;
|
||||
|
||||
private FieldReaderAppender(TypeDescription managedCtClass, FieldDescription.InDefinedShape persistentFieldAsDefined) {
|
||||
protected final FieldDescription.InDefinedShape persistentFieldAsDefined;
|
||||
|
||||
private FieldReaderAppender(TypeDescription managedCtClass, FieldDescription persistentField) {
|
||||
this.managedCtClass = managedCtClass;
|
||||
this.persistentFieldAsDefined = persistentFieldAsDefined;
|
||||
this.persistentField = persistentField;
|
||||
this.persistentFieldAsDefined = persistentField.asDefined();
|
||||
}
|
||||
|
||||
static ByteCodeAppender of(TypeDescription managedCtClass, FieldDescription persistentField) {
|
||||
if ( !persistentField.isVisibleTo( managedCtClass ) ) {
|
||||
return new MethodDispatching( managedCtClass, persistentField.asDefined() );
|
||||
return new MethodDispatching( managedCtClass, persistentField );
|
||||
}
|
||||
else {
|
||||
return new FieldWriting( managedCtClass, persistentField.asDefined() );
|
||||
return new FieldWriting( managedCtClass, persistentField );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,6 +103,10 @@ abstract class FieldReaderAppender implements ByteCodeAppender {
|
|||
// return field
|
||||
methodVisitor.visitVarInsn( Opcodes.ALOAD, 0 );
|
||||
fieldRead( methodVisitor );
|
||||
if ( !persistentField.getType().isPrimitive()
|
||||
&& !persistentField.getType().asErasure().getInternalName().equals( persistentFieldAsDefined.getType().asErasure().getInternalName() ) ) {
|
||||
methodVisitor.visitTypeInsn( Opcodes.CHECKCAST, persistentField.getType().asErasure().getInternalName() );
|
||||
}
|
||||
methodVisitor.visitInsn( Type.getType( persistentFieldAsDefined.getType().asErasure().getDescriptor() ).getOpcode( Opcodes.IRETURN ) );
|
||||
return new Size( 4 + persistentFieldAsDefined.getType().getStackSize().getSize(), instrumentedMethod.getStackSize() );
|
||||
}
|
||||
|
@ -110,8 +117,8 @@ abstract class FieldReaderAppender implements ByteCodeAppender {
|
|||
|
||||
private static class FieldWriting extends FieldReaderAppender {
|
||||
|
||||
private FieldWriting(TypeDescription managedCtClass, FieldDescription.InDefinedShape persistentFieldAsDefined) {
|
||||
super( managedCtClass, persistentFieldAsDefined );
|
||||
private FieldWriting(TypeDescription managedCtClass, FieldDescription persistentField) {
|
||||
super( managedCtClass, persistentField );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -137,8 +144,8 @@ abstract class FieldReaderAppender implements ByteCodeAppender {
|
|||
|
||||
private static class MethodDispatching extends FieldReaderAppender {
|
||||
|
||||
private MethodDispatching(TypeDescription managedCtClass, FieldDescription.InDefinedShape persistentFieldAsDefined) {
|
||||
super( managedCtClass, persistentFieldAsDefined );
|
||||
private MethodDispatching(TypeDescription managedCtClass, FieldDescription persistentField) {
|
||||
super( managedCtClass, persistentField );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.bytecode.enhancement.basic;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
import org.hibernate.annotations.Cache;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(BytecodeEnhancerRunner.class)
|
||||
public class GenericReturnValueMappedSuperclassEnhancementTest {
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-12579")
|
||||
public void enhanceClassWithGenericReturnValueOnMappedSuperclass() {
|
||||
SimpleEntity implementation = new SimpleEntity();
|
||||
|
||||
implementation.setEntity( SimpleEntity.Type.ONE );
|
||||
|
||||
assertEquals( SimpleEntity.Type.ONE, implementation.getEntity() );
|
||||
}
|
||||
|
||||
@MappedSuperclass
|
||||
@Cache(usage = CacheConcurrencyStrategy.NONE)
|
||||
public static class AbstractMappedSuperclassWithGenericReturnValue<T extends Marker> {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public int id;
|
||||
|
||||
@Access(AccessType.PROPERTY)
|
||||
private T entity;
|
||||
|
||||
public T getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void setEntity(T entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
}
|
||||
|
||||
public interface Marker {
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Cache(usage = CacheConcurrencyStrategy.NONE)
|
||||
public static class SimpleEntity extends AbstractMappedSuperclassWithGenericReturnValue<SimpleEntity.Type> {
|
||||
|
||||
public enum Type implements Marker {
|
||||
ONE
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue