HHH-12096 - Problem finding correlated getter-method for field access

This commit is contained in:
Steve Ebersole 2017-11-16 13:46:03 -06:00 committed by Vlad Mihalcea
parent 977cafca3c
commit 8acebf7df8
3 changed files with 106 additions and 2 deletions

View File

@ -14,7 +14,6 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Locale;
import java.util.regex.Pattern;
import javax.persistence.Transient;
import org.hibernate.AssertionFailure;
@ -636,4 +635,51 @@ public final class ReflectHelper {
return potentialSetter;
}
/**
* Similar to {@link #getterMethodOrNull}, except that here we are just looking for the
* corresponding getter for a field (defined as field access) if one exists.
*
* We do not look at supers, although conceivably the super could declare the method
* as an abstract - but again, that is such an edge case...
*/
public static Method findGetterMethodForFieldAccess(Field field, String propertyName) {
for ( Method method : field.getDeclaringClass().getDeclaredMethods() ) {
// if the method has parameters, skip it
if ( method.getParameterCount() != 0 ) {
continue;
}
if ( Modifier.isStatic( method.getModifiers() ) ) {
continue;
}
if ( ! method.getReturnType().isAssignableFrom( field.getType() ) ) {
continue;
}
final String methodName = method.getName();
// try "get"
if ( methodName.startsWith( "get" ) ) {
final String stemName = methodName.substring( 3 );
final String decapitalizedStemName = Introspector.decapitalize( stemName );
if ( stemName.equals( propertyName ) || decapitalizedStemName.equals( propertyName ) ) {
return method;
}
}
// if not "get", then try "is"
if ( methodName.startsWith( "is" ) ) {
final String stemName = methodName.substring( 2 );
String decapitalizedStemName = Introspector.decapitalize( stemName );
if ( stemName.equals( propertyName ) || decapitalizedStemName.equals( propertyName ) ) {
return method;
}
}
}
return null;
}
}

View File

@ -33,7 +33,8 @@ public class GetterFieldImpl implements Getter {
this.containerClass = containerClass;
this.propertyName = propertyName;
this.field = field;
this.getterMethod = ReflectHelper.getterMethodOrNull( containerClass, propertyName);
this.getterMethod = ReflectHelper.findGetterMethodForFieldAccess( field, propertyName );
}
@Override

View File

@ -0,0 +1,57 @@
/*
* 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.jpa.compliance;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import org.hibernate.boot.MetadataSources;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;
/**
* @author Steve Ebersole
*/
@TestForIssue( jiraKey = "12096")
public class GetterAndIsMethodChecks extends BaseUnitTestCase {
@Test
public void testIt() {
new MetadataSources().addAnnotatedClass( A.class ).buildMetadata().buildSessionFactory().close();
}
@Entity( name= "A" )
public static class A {
@Id
private Integer id;
@OneToOne
private A b;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public boolean isB() {
return true;
}
public A getB() {
return b;
}
public void setB(A b) {
this.b = b;
}
}
}