diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaBuilder.java index f3cced766..0632e89f2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaBuilder.java @@ -37,8 +37,7 @@ final class DtoMetaBuilder { if (includeMethod(method)) { try { final String name = propertyName(method.getName()); - final Class> propertyType = propertyType(method); - properties.add(new DtoMetaProperty(typeManager, dtoType, method, name, propertyType)); + properties.add(new DtoMetaProperty(typeManager, dtoType, method, name)); } catch (Exception e) { CoreLog.log.debug("exclude on " + dtoType + " method " + method, e); } @@ -46,10 +45,6 @@ final class DtoMetaBuilder { } } - static Class> propertyType(Method method) { - return method.getParameterTypes()[0]; - } - static String propertyName(String methodName) { final String name = methodName.substring(3); return Character.toLowerCase(name.charAt(0)) + name.substring(1); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaProperty.java index fe7d794a1..b73500434 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaProperty.java @@ -8,6 +8,7 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Method; +import java.lang.reflect.Type; import java.sql.SQLException; final class DtoMetaProperty implements DtoReadSet { @@ -19,18 +20,30 @@ final class DtoMetaProperty implements DtoReadSet { private final MethodHandle setter; private final ScalarType> scalarType; - DtoMetaProperty(TypeManager typeManager, Class> dtoType, Method writeMethod, String name, Class> propertyType) throws IllegalAccessException, NoSuchMethodException { + DtoMetaProperty(TypeManager typeManager, Class> dtoType, Method writeMethod, String name) throws IllegalAccessException, NoSuchMethodException { this.dtoType = dtoType; this.name = name; if (writeMethod != null) { - this.setter = LOOKUP.findVirtual(dtoType, writeMethod.getName(), MethodType.methodType(void.class, propertyType)); - this.scalarType = typeManager.getScalarType(propertyType); + this.setter = lookupMethodHandle(dtoType, writeMethod); + this.scalarType = typeManager.getScalarType(propertyType(writeMethod), propertyClass(writeMethod)); } else { this.scalarType = null; this.setter = null; } } + private static MethodHandle lookupMethodHandle(Class> dtoType, Method method) throws NoSuchMethodException, IllegalAccessException { + return LOOKUP.findVirtual(dtoType, method.getName(), MethodType.methodType(method.getReturnType(), method.getParameterTypes())); + } + + static Type propertyType(Method method) { + return method.getParameters()[0].getParameterizedType(); + } + + static Class> propertyClass(Method method) { + return method.getParameterTypes()[0]; + } + String getName() { return name; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/DefaultTypeManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/DefaultTypeManager.java index ea4a72ab6..627d7a9ef 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/DefaultTypeManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/DefaultTypeManager.java @@ -251,6 +251,18 @@ public final class DefaultTypeManager implements TypeManager { return nativeMap.get(jdbcType); } + @Override + public ScalarType> getScalarType(Type propertyType, Class> propertyClass) { + if (propertyType instanceof ParameterizedType) { + ParameterizedType pt = (ParameterizedType)propertyType; + Type rawType = pt.getRawType(); + if (List.class == rawType || Set.class == rawType) { + return getArrayScalarType((Class>)rawType, null, propertyType, true); + } + } + return getScalarType(propertyClass); + } + /** * This can return null if no matching ScalarType is found. */ diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/TypeManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/TypeManager.java index 3a7071317..d604ba8b0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/TypeManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/TypeManager.java @@ -47,6 +47,13 @@ public interface TypeManager { */ ScalarType> getScalarType(Class> type, int jdbcType); + /** + * Find and return the ScalarType taking into account the property type with generics. + *
+ * For example Array based ScalarType for types like {@code List