From 0e65efea57ae2bb8b5786563572cee474f7e297d Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Sun, 25 Aug 2019 15:58:46 +1200 Subject: [PATCH] #1804 - Kotlin: Generating collection with wildcard type - Get error BeanNotRegisteredException: Error with association to [null] from [...Foo.manyProperty]. Is null registered? --- .../deploy/parse/DeployCreateProperties.java | 9 ++- src/test/java/org/tests/o2m/OmBasicChild.java | 50 ++++++++++++++++ .../java/org/tests/o2m/OmBasicParent.java | 60 +++++++++++++++++++ .../org/tests/o2m/TestOneToManyWildcard.java | 35 +++++++++++ 4 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/tests/o2m/OmBasicChild.java create mode 100644 src/test/java/org/tests/o2m/OmBasicParent.java create mode 100644 src/test/java/org/tests/o2m/TestOneToManyWildcard.java diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/DeployCreateProperties.java b/src/main/java/io/ebeaninternal/server/deploy/parse/DeployCreateProperties.java index 2ecb5ecd6..b32320ad7 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/parse/DeployCreateProperties.java +++ b/src/main/java/io/ebeaninternal/server/deploy/parse/DeployCreateProperties.java @@ -313,10 +313,17 @@ public class DeployCreateProperties { Type[] typeArgs = ptype.getActualTypeArguments(); if (typeArgs.length == 1) { - // probably a Set or List + // expecting set or list if (typeArgs[0] instanceof Class) { return (Class) typeArgs[0]; } + if (typeArgs[0] instanceof WildcardType) { + final Type[] upperBounds = ((WildcardType) typeArgs[0]).getUpperBounds(); + if (upperBounds.length == 1 && upperBounds[0] instanceof Class) { + // kotlin generated wildcard type + return (Class) upperBounds[0]; + } + } // throw new RuntimeException("Unexpected Parameterised Type? "+typeArgs[0]); return null; } diff --git a/src/test/java/org/tests/o2m/OmBasicChild.java b/src/test/java/org/tests/o2m/OmBasicChild.java new file mode 100644 index 000000000..b94ca0a66 --- /dev/null +++ b/src/test/java/org/tests/o2m/OmBasicChild.java @@ -0,0 +1,50 @@ +package org.tests.o2m; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.Version; + +@Entity +public class OmBasicChild { + + @Id + private long id; + + private final String name; + + @ManyToOne + private final OmBasicParent parent; + + @Version + private long version; + + public OmBasicChild(String name, OmBasicParent parent) { + this.name = name; + this.parent = parent; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public OmBasicParent getParent() { + return parent; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } +} diff --git a/src/test/java/org/tests/o2m/OmBasicParent.java b/src/test/java/org/tests/o2m/OmBasicParent.java new file mode 100644 index 000000000..76faeca0e --- /dev/null +++ b/src/test/java/org/tests/o2m/OmBasicParent.java @@ -0,0 +1,60 @@ +package org.tests.o2m; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Version; +import java.util.List; + +import static javax.persistence.CascadeType.ALL; + +@Entity +public class OmBasicParent { + + @Id + private long id; + + private final String name; + + @Version + private long version; + + /** + * Not really sensible Java code here but Kotlin can generate + * a collection type that looks like this + */ + @OneToMany(cascade = ALL, mappedBy = "parent") + private List children; + + public OmBasicParent(String name) { + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } +} diff --git a/src/test/java/org/tests/o2m/TestOneToManyWildcard.java b/src/test/java/org/tests/o2m/TestOneToManyWildcard.java new file mode 100644 index 000000000..2cf5561c8 --- /dev/null +++ b/src/test/java/org/tests/o2m/TestOneToManyWildcard.java @@ -0,0 +1,35 @@ +package org.tests.o2m; + +import io.ebean.DB; +import org.junit.Test; + +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TestOneToManyWildcard { + + @Test + public void test() { + + OmBasicParent parent = new OmBasicParent("p1"); + OmBasicChild c1 = new OmBasicChild("c1", parent); + OmBasicChild c2 = new OmBasicChild("c2", parent); + + DB.save(parent); + DB.saveAll(Arrays.asList(c1, c2)); + + // we can't add to this in Java but Kotlin can + //parent.getChildren().add(c1); + + // exercise + final OmBasicParent found = DB.find(OmBasicParent.class) + .where().idEq(parent.getId()) + .findOne(); + + assertThat(found).isNotNull(); + assertThat(found.getChildren()).hasSize(2); + + DB.delete(parent); + } +}