diff --git a/core/src/main/java/org/sql2o/reflection/PojoMetadata.java b/core/src/main/java/org/sql2o/reflection/PojoMetadata.java index 4996a643..364f9df7 100644 --- a/core/src/main/java/org/sql2o/reflection/PojoMetadata.java +++ b/core/src/main/java/org/sql2o/reflection/PojoMetadata.java @@ -115,6 +115,10 @@ private PropertyAndFieldInfo initializePropertyInfo() { // prepare methods. Methods will override fields, if both exists. for (Method m : theClass.getDeclaredMethods()) { + if (m.isBridge()) { + // skip bridge methods: https://github.com/aaberg/sql2o/issues/314 + continue; + } if (m.getName().startsWith("get")) { String propertyName = m.getName().substring(3); @@ -123,14 +127,7 @@ private PropertyAndFieldInfo initializePropertyInfo() { } else { propertyName = propertyName.toLowerCase(); } - - final Getter existingGetter = propertyGetters.get(propertyName); - if (existingGetter != null && existingGetter.getType() != Object.class && m.getReturnType() == Object.class) { - // don't overwrite existing getter if it has more concrete type. See https://github.com/aaberg/sql2o/issues/314 - // for more details. - } else { - propertyGetters.put(propertyName, factoryFacade.newGetter(m)); - } + propertyGetters.put(propertyName, factoryFacade.newGetter(m)); } if (m.getName().startsWith("set") && m.getParameterTypes().length == 1) { @@ -143,14 +140,7 @@ private PropertyAndFieldInfo initializePropertyInfo() { } else { propertyName = propertyName.toLowerCase(); } - - final Setter existingSetter = propertySetters.get(propertyName); - if (existingSetter != null && existingSetter.getType() != Object.class && m.getParameterTypes()[0] == Object.class) { - // don't overwrite existing setter if it has more concrete type. See https://github.com/aaberg/sql2o/issues/314 - // for more details. - } else { - propertySetters.put(propertyName, factoryFacade.newSetter(m)); - } + propertySetters.put(propertyName, factoryFacade.newSetter(m)); } } theClass = theClass.getSuperclass(); diff --git a/core/src/test/java/org/sql2o/reflection/PojoMetadataTest.java b/core/src/test/java/org/sql2o/reflection/PojoMetadataTest.java index f3cdcc42..50bda532 100644 --- a/core/src/test/java/org/sql2o/reflection/PojoMetadataTest.java +++ b/core/src/test/java/org/sql2o/reflection/PojoMetadataTest.java @@ -1,7 +1,6 @@ package org.sql2o.reflection; import javassist.*; -import org.junit.AssumptionViolatedException; import org.junit.Test; import java.util.HashMap; @@ -20,20 +19,7 @@ public class PojoMetadataTest { */ @Test public void testPrefersGetterWithMoreConcreteType() throws Exception { - Class clazz = createClassWithGetters(false); - if (clazz.getDeclaredMethods()[0].getReturnType() == Object.class) { - // the method order is undefined :( We need to have two methods, first one returning String, second one - // returning Object. The old PojoMetadata would incorrectly use the latter; the fixed version would use the - // function returning more concrete result. - // - // try to create the class with reversed method ordering, maybe it helps? - clazz = createClassWithGetters(true); - if (clazz.getDeclaredMethods()[0].getReturnType() == Object.class) { - // nah, didn't help. bail out. - throw new AssumptionViolatedException("Can't enforce method order"); - } - } - + Class clazz = createClassWithGetters(); final PojoMetadata metadata = new PojoMetadata(clazz, false, false, new HashMap(), true); assertEquals(String.class, metadata.getPropertyGetter("id").getType()); } @@ -44,53 +30,35 @@ public void testPrefersGetterWithMoreConcreteType() throws Exception { */ @Test public void testPrefersSetterWithMoreConcreteType() throws Exception { - Class clazz = createClassWithSetters(false); - if (clazz.getDeclaredMethods()[0].getParameterTypes()[0] == Object.class) { - // the method order is undefined :( We need to have two methods, first one returning String, second one - // returning Object. The old PojoMetadata would incorrectly use the latter; the fixed version would use the - // function returning more concrete result. - // - // try to create the class with reversed method ordering, maybe it helps? - clazz = createClassWithSetters(true); - if (clazz.getDeclaredMethods()[0].getParameterTypes()[0] == Object.class) { - // nah, didn't help. bail out. - throw new AssumptionViolatedException("Can't enforce method order"); - } - } - + Class clazz = createClassWithSetters(); final PojoMetadata metadata = new PojoMetadata(clazz, false, false, new HashMap(), true); assertEquals(String.class, metadata.getPropertySetter("id").getType()); } - private Class createClassWithGetters(boolean objectThenString) throws CannotCompileException, NotFoundException { + private Class createClassWithGetters() throws CannotCompileException, NotFoundException { final ClassPool pool = ClassPool.getDefault(); final CtClass ctClass = pool.makeClass("my.test.Klass" + UUID.randomUUID().toString().replace("-", "")); ctClass.addField(new CtField(pool.get("java.lang.String"), "id", ctClass)); - if (objectThenString) { - ctClass.addMethod(CtNewMethod.make("public Object getId() { return id; }", ctClass)); - ctClass.addMethod(CtNewMethod.make("public String getId() { return id; }", ctClass)); - } else { - ctClass.addMethod(CtNewMethod.make("public String getId() { return id; }", ctClass)); - ctClass.addMethod(CtNewMethod.make("public Object getId() { return id; }", ctClass)); - } + ctClass.addMethod(withBridge(CtNewMethod.make("public Object getId() { return id; }", ctClass))); + ctClass.addMethod(CtNewMethod.make("public String getId() { return id; }", ctClass)); final Class clazz = ctClass.toClass(); assertEquals(2, clazz.getDeclaredMethods().length); return clazz; } - private Class createClassWithSetters(boolean objectThenString) throws CannotCompileException, NotFoundException { + private Class createClassWithSetters() throws CannotCompileException, NotFoundException { final ClassPool pool = ClassPool.getDefault(); final CtClass ctClass = pool.makeClass("my.test.Klass" + UUID.randomUUID().toString().replace("-", "")); ctClass.addField(new CtField(pool.get("java.lang.Object"), "id", ctClass)); - if (objectThenString) { - ctClass.addMethod(CtNewMethod.make("public void setId(Object id) { this.id = id; }", ctClass)); - ctClass.addMethod(CtNewMethod.make("public void setId(String id) { this.id = id; }", ctClass)); - } else { - ctClass.addMethod(CtNewMethod.make("public void setId(String id) { this.id = id; }", ctClass)); - ctClass.addMethod(CtNewMethod.make("public void setId(Object id) { this.id = id; }", ctClass)); - } + ctClass.addMethod(withBridge(CtNewMethod.make("public void setId(Object id) { this.id = id; }", ctClass))); + ctClass.addMethod(CtNewMethod.make("public void setId(String id) { this.id = id; }", ctClass)); final Class clazz = ctClass.toClass(); assertEquals(2, clazz.getDeclaredMethods().length); return clazz; } + + private static CtMethod withBridge(CtMethod method) { + method.setModifiers(method.getModifiers() | 0x00000040); // Modifier.BRIDGE field not public :( + return method; + } }