diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java index 814d8c293b64..bfcbccd77879 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java @@ -197,17 +197,18 @@ public Size apply( methodVisitor.visitVarInsn( Opcodes.ALOAD, 2 ); methodVisitor.visitLdcInsn( index++ ); methodVisitor.visitInsn( Opcodes.AALOAD ); - if ( setter.getParameterTypes()[0].isPrimitive() ) { + Class firstParameterType = setter.getParameterTypes()[0]; + if ( firstParameterType.isPrimitive() ) { PrimitiveUnboxingDelegate.forReferenceType( TypeDescription.Generic.OBJECT ) .assignUnboxedTo( - new TypeDescription.Generic.OfNonGenericType.ForLoadedType( setter.getParameterTypes()[0] ), + new TypeDescription.Generic.OfNonGenericType.ForLoadedType( firstParameterType ), ReferenceTypeAwareAssigner.INSTANCE, Assigner.Typing.DYNAMIC ) .apply( methodVisitor, implementationContext ); } else { - methodVisitor.visitTypeInsn( Opcodes.CHECKCAST, Type.getInternalName( setter.getParameterTypes()[0] ) ); + methodVisitor.visitTypeInsn( Opcodes.CHECKCAST, Type.getInternalName( firstParameterType ) ); } methodVisitor.visitMethodInsn( Opcodes.INVOKEVIRTUAL, diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/ReflectHelper.java b/hibernate-core/src/main/java/org/hibernate/internal/util/ReflectHelper.java index 66e82fd20800..edac0df2dd38 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/util/ReflectHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/util/ReflectHelper.java @@ -423,16 +423,14 @@ private static Field locateField(Class clazz, String propertyName) { return null; } - try { - Field field = clazz.getDeclaredField( propertyName ); - if ( !isStaticField( field ) ) { - return field; - } + Field field = findField(propertyName, clazz.getDeclaredFields()); + if (field == null) { return locateField( clazz.getSuperclass(), propertyName ); } - catch ( NoSuchFieldException nsfe ) { - return locateField( clazz.getSuperclass(), propertyName ); + if ( !isStaticField( field ) ) { + return field; } + return locateField( clazz.getSuperclass(), propertyName ); } public static boolean isStaticField(Field field) { @@ -490,7 +488,8 @@ private static Method getGetterOrNull(Class[] interfaces, String propertyName) { } private static Method getGetterOrNull(Class containerClass, String propertyName) { - for ( Method method : containerClass.getDeclaredMethods() ) { + Method[] declaredMethods = containerClass.getDeclaredMethods(); + for ( Method method : declaredMethods) { // if the method has parameters, skip it if ( method.getParameterCount() != 0 ) { continue; @@ -514,9 +513,8 @@ private static Method getGetterOrNull(Class containerClass, String propertyName) // 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 ) ) { - verifyNoIsVariantExists( containerClass, propertyName, method, stemName ); + if ( stemName.equals( propertyName ) || Introspector.decapitalize( stemName ).equals( propertyName ) ) { + verifyNoIsVariantExists( containerClass, propertyName, method, stemName, declaredMethods); return method; } @@ -525,9 +523,8 @@ private static Method getGetterOrNull(Class containerClass, String propertyName) // 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 ) ) { - verifyNoGetVariantExists( containerClass, propertyName, method, stemName ); + if ( stemName.equals( propertyName ) || Introspector.decapitalize( stemName ).equals( propertyName ) ) { + verifyNoGetVariantExists( containerClass, propertyName, method, stemName, declaredMethods); return method; } } @@ -536,21 +533,39 @@ private static Method getGetterOrNull(Class containerClass, String propertyName) return null; } + private static Method findAnyMatch(String name, Method[] methods) { + for (Method method : methods) { + if (method.getName().equals(name)) { + return method; + } + } + return null; + } + + private static Field findField(String name, Field[] methods) { + for (Field field : methods) { + if (field.getName().equals(name)) { + return field; + } + } + return null; + } + private static void verifyNoIsVariantExists( Class containerClass, String propertyName, Method getMethod, - String stemName) { - // verify that the Class does not also define a method with the same stem name with 'is' - try { - final Method isMethod = containerClass.getDeclaredMethod( "is" + stemName ); - if ( !Modifier.isStatic( isMethod.getModifiers() ) && isMethod.getAnnotation( Transient.class ) == null ) { - // No such method should throw the caught exception. So if we get here, there was - // such a method. - checkGetAndIsVariants( containerClass, propertyName, getMethod, isMethod ); - } + String stemName, + Method[] declaredMethods) { + + Method isMethod = findAnyMatch( "is" + stemName, declaredMethods); + if (isMethod == null) { + return; } - catch (NoSuchMethodException ignore) { + + // verify that the Class does not also define a method with the same stem name with 'is' + if ( !Modifier.isStatic( isMethod.getModifiers() ) && isMethod.getAnnotation( Transient.class ) == null ) { + checkGetAndIsVariants( containerClass, propertyName, getMethod, isMethod ); } } @@ -580,17 +595,15 @@ private static void verifyNoGetVariantExists( Class containerClass, String propertyName, Method isMethod, - String stemName) { - // verify that the Class does not also define a method with the same stem name with 'is' - try { - final Method getMethod = containerClass.getDeclaredMethod( "get" + stemName ); - // No such method should throw the caught exception. So if we get here, there was - // such a method. - if ( !Modifier.isStatic( getMethod.getModifiers() ) && getMethod.getAnnotation( Transient.class ) == null ) { - checkGetAndIsVariants( containerClass, propertyName, getMethod, isMethod ); - } + String stemName, + Method[] declaredMethods) { + Method getMethod = findAnyMatch( "get" + stemName, declaredMethods); + if (getMethod == null) { + return; } - catch (NoSuchMethodException ignore) { + // verify that the Class does not also define a method with the same stem name with 'get' + if ( !Modifier.isStatic( getMethod.getModifiers() ) && getMethod.getAnnotation( Transient.class ) == null ) { + checkGetAndIsVariants( containerClass, propertyName, getMethod, isMethod ); } } @@ -663,8 +676,7 @@ private static Method setterOrNull(Class theClass, String propertyName, Class pr final String methodName = method.getName(); if ( method.getParameterCount() == 1 && methodName.startsWith( "set" ) ) { final String testOldMethod = methodName.substring( 3 ); - final String testStdMethod = Introspector.decapitalize( testOldMethod ); - if ( testStdMethod.equals( propertyName ) || testOldMethod.equals( propertyName ) ) { + if (testOldMethod.equals( propertyName ) || Introspector.decapitalize( testOldMethod ).equals( propertyName )) { potentialSetter = method; if ( propertyType == null || method.getParameterTypes()[0].equals( propertyType ) ) { break; @@ -703,8 +715,7 @@ public static Method findGetterMethodForFieldAccess(Field field, String property // 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 ) ) { + if ( stemName.equals( propertyName ) || Introspector.decapitalize( stemName ).equals( propertyName ) ) { return method; } @@ -713,8 +724,7 @@ public static Method findGetterMethodForFieldAccess(Field field, String property // 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 ) ) { + if ( stemName.equals( propertyName ) || Introspector.decapitalize( stemName ).equals( propertyName ) ) { return method; } } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/StringHelper.java b/hibernate-core/src/main/java/org/hibernate/internal/util/StringHelper.java index 1299b5648b90..3a086b6cb627 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/util/StringHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/util/StringHelper.java @@ -128,7 +128,10 @@ public static String replace( return template; } else { - String beforePlaceholder = template.substring( 0, loc ); + String beforePlaceholder = ""; + if (loc > 0) { + beforePlaceholder = template.substring(0, loc); + } String afterPlaceholder = template.substring( loc + placeholder.length() ); return replace( beforePlaceholder,