From d22c04b9e4ce378c13bbbd2ddec351742b53f37f Mon Sep 17 00:00:00 2001 From: Francesco Date: Wed, 8 Nov 2023 14:51:04 +0100 Subject: [PATCH] Fixed handling of Collection types in ManyToMany (#35) --- .../external/dbmapping/DbObject.java | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/tech/ailef/snapadmin/external/dbmapping/DbObject.java b/src/main/java/tech/ailef/snapadmin/external/dbmapping/DbObject.java index 0737561..7f04306 100644 --- a/src/main/java/tech/ailef/snapadmin/external/dbmapping/DbObject.java +++ b/src/main/java/tech/ailef/snapadmin/external/dbmapping/DbObject.java @@ -27,6 +27,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import jakarta.persistence.ManyToMany; @@ -71,7 +72,7 @@ public class DbObject { @SuppressWarnings("unchecked") public List getValues(DbField field) { - List values = (List)get(field.getJavaName()).getValue(); + Collection values = (Collection)get(field.getJavaName()).getValue(); return values.stream().map(o -> new DbObject(o, field.getConnectedSchema())) .collect(Collectors.toList()); } @@ -221,9 +222,34 @@ public class DbObject { throw new SnapAdminException("Unable to find setter method for " + fieldName + " in " + schema.getClassName()); } + Class[] types = setter.getParameterTypes(); + if (types.length != 1) + throw new SnapAdminException("Setter " + setter + " has " + types.length + " parameters (expected 1)"); + + Class expectedSetterType = types[0]; + if (!expectedSetterType.isAssignableFrom(value.getClass())) { + // If the value is not assignable we check if it's a collection + // mismatch, e.g. the setter expects a Set but we are passing a List + // or viceversa + if (expectedSetterType == Set.class) { + // Convert value to Set + value = ((Collection)value).stream().collect(Collectors.toSet()); + } else if (expectedSetterType == List.class) { + // Convert value to List + value = ((Collection)value).stream().collect(Collectors.toList()); + } + } + + + + + try { setter.invoke(instance, value); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + if (e instanceof IllegalArgumentException) { + throw new RuntimeException("setter: " + setter + ", passed: " + value.getClass(), e); + } throw new RuntimeException(e); } }