Skip to content

Commit

Permalink
HHH-12579 Use the field description with type variables resolved to c…
Browse files Browse the repository at this point in the history
…ast the return value of the $$_hibernate_read_<property>() method
  • Loading branch information
gsmet authored and yrodiere committed May 24, 2018
1 parent b4c7208 commit c0652a5
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 9 deletions.
Expand Up @@ -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 );
}
}

Expand Down Expand Up @@ -100,6 +103,10 @@ public Size apply(
// 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() );
}
Expand All @@ -110,8 +117,8 @@ public Size apply(

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
Expand All @@ -137,8 +144,8 @@ protected void fieldWrite(MethodVisitor methodVisitor) {

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
Expand Down
@@ -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
}
}
}

0 comments on commit c0652a5

Please sign in to comment.