mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#2692 - [querybean generation] Compile error, incorrect generation with nested inner class/record @Embeddable and @IdClass
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
package org.example.domain;
|
||||
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@IdClass(MyInner.ID.class)
|
||||
public class MyInner {
|
||||
|
||||
@Embeddable
|
||||
public static class ID {
|
||||
final long id;
|
||||
final String one;
|
||||
|
||||
public ID(long id, String one) {
|
||||
this.id = id;
|
||||
this.one = one;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ID id1 = (ID) o;
|
||||
return id == id1.id && one.equals(id1.one);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, one);
|
||||
}
|
||||
}
|
||||
|
||||
@Id
|
||||
long id;
|
||||
@Id
|
||||
String one;
|
||||
String description;
|
||||
|
||||
public long id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public MyInner id(long id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String one() {
|
||||
return one;
|
||||
}
|
||||
|
||||
public MyInner one(String beanOne) {
|
||||
this.one = beanOne;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public MyInner description(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package org.querytest;
|
||||
|
||||
import io.ebean.DB;
|
||||
import org.example.domain.MyInner;
|
||||
import org.example.domain.query.QMyInner;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class MyInnerTest {
|
||||
|
||||
@Test
|
||||
void insert_and_find() {
|
||||
|
||||
MyInner myInner = new MyInner()
|
||||
.id(42).one("one").description("foo");
|
||||
|
||||
DB.save(myInner);
|
||||
|
||||
MyInner found = DB.find(MyInner.class, new MyInner.ID(42, "one"));
|
||||
assertThat(found).isNotNull();
|
||||
|
||||
MyInner found2 = new QMyInner()
|
||||
.id.eq(42)
|
||||
.one.eq("one")
|
||||
.findOne();
|
||||
|
||||
assertThat(found2).isNotNull();
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
<artifactId>kotlin-querybean-generator</artifactId>
|
||||
|
||||
<properties>
|
||||
<kotlin.version>1.6.0</kotlin.version>
|
||||
<kotlin.version>1.6.20</kotlin.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -61,6 +61,13 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.6.2-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
@@ -106,7 +113,7 @@
|
||||
<annotationProcessorPath>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>kotlin-querybean-generator</artifactId>
|
||||
<version>12.13.0</version>
|
||||
<version>13.6.2-SNAPSHOT</version>
|
||||
</annotationProcessorPath>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
@@ -155,8 +162,8 @@
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
<!-- Turn off annotation processing for building -->
|
||||
<compilerArgument>-proc:none</compilerArgument>
|
||||
</configuration>
|
||||
|
||||
+10
-39
@@ -63,13 +63,9 @@ class SimpleQueryBeanWriter {
|
||||
);
|
||||
|
||||
private final Set<String> importTypes = new TreeSet<>();
|
||||
|
||||
private final List<PropertyMeta> properties = new ArrayList<>();
|
||||
|
||||
private final TypeElement element;
|
||||
|
||||
private final ProcessingContext processingContext;
|
||||
|
||||
private final boolean isEntity;
|
||||
private final boolean embeddable;
|
||||
private final String dbName;
|
||||
@@ -80,10 +76,9 @@ class SimpleQueryBeanWriter {
|
||||
|
||||
private String destPackage;
|
||||
private String origDestPackage;
|
||||
|
||||
private String shortName;
|
||||
private String origShortName;
|
||||
|
||||
private final String shortInnerName;
|
||||
private final String origShortName;
|
||||
private Append writer;
|
||||
|
||||
SimpleQueryBeanWriter(TypeElement element, ProcessingContext processingContext) {
|
||||
@@ -92,8 +87,12 @@ class SimpleQueryBeanWriter {
|
||||
this.element = element;
|
||||
this.processingContext = processingContext;
|
||||
this.beanFullName = element.getQualifiedName().toString();
|
||||
this.destPackage = derivePackage(beanFullName) + ".query";
|
||||
this.shortName = deriveShortName(beanFullName);
|
||||
boolean nested = element.getNestingKind().isNested();
|
||||
this.destPackage = Util.packageOf(nested, beanFullName) + ".query";
|
||||
String sn = Util.shortName(nested, beanFullName);
|
||||
this.shortInnerName = Util.shortName(false, sn);
|
||||
this.shortName = sn.replace(".", "");
|
||||
this.origShortName = shortName;
|
||||
this.isEntity = processingContext.isEntity(element);
|
||||
this.embeddable = processingContext.isEmbeddable(element);
|
||||
this.dbName = findDbName();
|
||||
@@ -129,10 +128,7 @@ class SimpleQueryBeanWriter {
|
||||
* </p>
|
||||
*/
|
||||
private void addClassProperties() {
|
||||
|
||||
List<VariableElement> fields = processingContext.allFields(element);
|
||||
|
||||
for (VariableElement field : fields) {
|
||||
for (VariableElement field : processingContext.allFields(element)) {
|
||||
PropertyType type = processingContext.getPropertyType(field);
|
||||
if (type != null) {
|
||||
type.addImports(importTypes);
|
||||
@@ -145,9 +141,7 @@ class SimpleQueryBeanWriter {
|
||||
* Write the type query bean (root bean).
|
||||
*/
|
||||
void writeRootBean() throws IOException {
|
||||
|
||||
gatherPropertyDetails();
|
||||
|
||||
if (isEmbeddable()) {
|
||||
processingContext.addEntity(beanFullName, dbName);
|
||||
} else if (isEntity()) {
|
||||
@@ -193,15 +187,12 @@ class SimpleQueryBeanWriter {
|
||||
* Write the type query assoc bean.
|
||||
*/
|
||||
void writeAssocBean() throws IOException {
|
||||
|
||||
writingAssocBean = true;
|
||||
origDestPackage = destPackage;
|
||||
destPackage = destPackage + ".assoc";
|
||||
origShortName = shortName;
|
||||
shortName = "Assoc" + shortName;
|
||||
|
||||
prepareAssocBeanImports();
|
||||
|
||||
writer = new Append(createFileWriter());
|
||||
|
||||
writePackage();
|
||||
@@ -279,7 +270,6 @@ class SimpleQueryBeanWriter {
|
||||
* Write all the fields.
|
||||
*/
|
||||
private void writeFields() {
|
||||
|
||||
for (PropertyMeta property : properties) {
|
||||
String typeDefn = property.getTypeDefn(shortName, writingAssocBean);
|
||||
lang().fieldDefn(writer, property.getName(), typeDefn);
|
||||
@@ -292,7 +282,6 @@ class SimpleQueryBeanWriter {
|
||||
* Write the class definition.
|
||||
*/
|
||||
private void writeClass() {
|
||||
|
||||
if (writingAssocBean) {
|
||||
writer.append("/**").eol();
|
||||
writer.append(" * Association query bean for %s.", shortName).eol();
|
||||
@@ -301,7 +290,7 @@ class SimpleQueryBeanWriter {
|
||||
writer.append(" */").eol();
|
||||
writer.append(Constants.AT_GENERATED).eol();
|
||||
writer.append(Constants.AT_TYPEQUERYBEAN).eol();
|
||||
lang().beginAssocClass(writer, shortName, origShortName);
|
||||
lang().beginAssocClass(writer, shortName, shortInnerName);
|
||||
|
||||
} else {
|
||||
writer.append("/**").eol();
|
||||
@@ -331,7 +320,6 @@ class SimpleQueryBeanWriter {
|
||||
* Write all the imports.
|
||||
*/
|
||||
private void writeImports() {
|
||||
|
||||
for (String importType : importTypes) {
|
||||
writer.append("import %s;", importType).eol();
|
||||
}
|
||||
@@ -343,9 +331,7 @@ class SimpleQueryBeanWriter {
|
||||
}
|
||||
|
||||
private Writer createFileWriter() throws IOException {
|
||||
|
||||
String relPath = destPackage.replace('.', '/');
|
||||
|
||||
File absDir = new File(generatedSourcesDir, relPath);
|
||||
if (!absDir.exists() && !absDir.mkdirs()) {
|
||||
processingContext.logNote("failed to create directories for:" + absDir.getAbsolutePath());
|
||||
@@ -356,19 +342,4 @@ class SimpleQueryBeanWriter {
|
||||
return new FileWriter(absFile);
|
||||
}
|
||||
|
||||
private String derivePackage(String name) {
|
||||
int pos = name.lastIndexOf('.');
|
||||
if (pos == -1) {
|
||||
return "";
|
||||
}
|
||||
return name.substring(0, pos);
|
||||
}
|
||||
|
||||
private String deriveShortName(String name) {
|
||||
int pos = name.lastIndexOf('.');
|
||||
if (pos == -1) {
|
||||
return name;
|
||||
}
|
||||
return name.substring(pos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package io.ebean.querybean.generator;
|
||||
|
||||
class Util {
|
||||
|
||||
static String packageOf(boolean nested, String originName) {
|
||||
return nested ? nestedPackageOf(originName) : packageOf(originName);
|
||||
}
|
||||
|
||||
private static String nestedPackageOf(String cls) {
|
||||
int pos = cls.lastIndexOf('.');
|
||||
if (pos < 0) {
|
||||
return "";
|
||||
}
|
||||
pos = cls.lastIndexOf('.', pos - 1);
|
||||
return (pos == -1) ? "" : cls.substring(0, pos);
|
||||
}
|
||||
|
||||
private static String packageOf(String cls) {
|
||||
int pos = cls.lastIndexOf('.');
|
||||
return (pos == -1) ? "" : cls.substring(0, pos);
|
||||
}
|
||||
|
||||
static String shortName(boolean nested, String fullType) {
|
||||
return nested ? nestedShortName(fullType): shortName(fullType);
|
||||
}
|
||||
|
||||
private static String nestedShortName(String fullType) {
|
||||
int pos = fullType.lastIndexOf('.');
|
||||
if (pos < 0) {
|
||||
return fullType;
|
||||
} else {
|
||||
pos = fullType.lastIndexOf('.', pos - 1);
|
||||
return pos < 0 ? fullType : fullType.substring(pos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private static String shortName(String fullType) {
|
||||
int p = fullType.lastIndexOf('.');
|
||||
if (p == -1) {
|
||||
return fullType;
|
||||
} else {
|
||||
return fullType.substring(p + 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package io.ebean.querybean.generator
|
||||
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
internal class UtilTest {
|
||||
|
||||
@Test
|
||||
fun packageOf() {
|
||||
Assertions.assertEquals(Util.packageOf(true, "com.example.Foo.Bar"), "com.example")
|
||||
Assertions.assertEquals(Util.packageOf(false, "com.example.other.foo.Bar"), "com.example.other.foo")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shortName() {
|
||||
Assertions.assertEquals(Util.shortName(true, "com.example.Foo.Bar"), "Foo.Bar")
|
||||
Assertions.assertEquals(Util.shortName(false, "com.example.foo.Bar"), "Bar")
|
||||
Assertions.assertEquals(Util.shortName(false, "Bar"), "Bar")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.example.domain
|
||||
|
||||
import javax.persistence.*
|
||||
|
||||
@Entity
|
||||
@Table(name = "t_inner")
|
||||
@IdClass(MyKotInner.Mid::class)
|
||||
class MyKotInner {
|
||||
|
||||
@Id
|
||||
var one: String = "0"
|
||||
@Id
|
||||
var two: String = "0"
|
||||
|
||||
var description: String? = null
|
||||
|
||||
@Embeddable
|
||||
data class Mid(val one: String, val two: String)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.example.otherpackage
|
||||
|
||||
import io.ebean.DB
|
||||
import org.assertj.core.api.AssertionsForInterfaceTypes.assertThat
|
||||
import org.example.domain.MyKotInner
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class InnerTest {
|
||||
|
||||
@Test
|
||||
fun split_normal() {
|
||||
val my = MyKotInner()
|
||||
my.one = "a"
|
||||
my.two = "b"
|
||||
my.description = "desc"
|
||||
DB.save(my)
|
||||
|
||||
val myId = MyKotInner.Mid("a", "b")
|
||||
|
||||
val found = DB.find(MyKotInner::class.java, myId)
|
||||
assertThat(found).isNotNull
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
ebean-version: 141
|
||||
@@ -0,0 +1,9 @@
|
||||
ebean.ddl.generate=true
|
||||
ebean.ddl.run=true
|
||||
#datasource.default=h2
|
||||
|
||||
datasource.db.username=sa
|
||||
datasource.db.password=
|
||||
datasource.db.url=jdbc:h2:mem:testKotlin
|
||||
|
||||
|
||||
+9
-25
@@ -18,13 +18,9 @@ import java.util.TreeSet;
|
||||
class SimpleQueryBeanWriter {
|
||||
|
||||
private final Set<String> importTypes = new TreeSet<>();
|
||||
|
||||
private final List<PropertyMeta> properties = new ArrayList<>();
|
||||
|
||||
private final TypeElement element;
|
||||
|
||||
private final ProcessingContext processingContext;
|
||||
|
||||
private final String dbName;
|
||||
private final String beanFullName;
|
||||
private final boolean isEntity;
|
||||
@@ -33,17 +29,21 @@ class SimpleQueryBeanWriter {
|
||||
|
||||
private String destPackage;
|
||||
private String origDestPackage;
|
||||
|
||||
private String shortName;
|
||||
private String origShortName;
|
||||
private final String shortInnerName;
|
||||
private final String origShortName;
|
||||
private Append writer;
|
||||
|
||||
SimpleQueryBeanWriter(TypeElement element, ProcessingContext processingContext) {
|
||||
this.element = element;
|
||||
this.processingContext = processingContext;
|
||||
this.beanFullName = element.getQualifiedName().toString();
|
||||
this.destPackage = derivePackage(beanFullName) + ".query";
|
||||
this.shortName = deriveShortName(beanFullName);
|
||||
boolean nested = element.getNestingKind().isNested();
|
||||
this.destPackage = Util.packageOf(nested, beanFullName) + ".query";
|
||||
String sn = Util.shortName(nested, beanFullName);
|
||||
this.shortInnerName = Util.shortName(false, sn);
|
||||
this.shortName = sn.replace('.', '$');
|
||||
this.origShortName = shortName;
|
||||
this.isEntity = processingContext.isEntity(element);
|
||||
this.embeddable = processingContext.isEmbeddable(element);
|
||||
this.dbName = findDbName();
|
||||
@@ -125,7 +125,6 @@ class SimpleQueryBeanWriter {
|
||||
writingAssocBean = true;
|
||||
origDestPackage = destPackage;
|
||||
destPackage = destPackage + ".assoc";
|
||||
origShortName = shortName;
|
||||
shortName = "Assoc" + shortName;
|
||||
|
||||
prepareAssocBeanImports();
|
||||
@@ -318,7 +317,7 @@ class SimpleQueryBeanWriter {
|
||||
writer.append(" */").eol();
|
||||
writer.append(Constants.AT_GENERATED).eol();
|
||||
writer.append(Constants.AT_TYPEQUERYBEAN).eol();
|
||||
writer.append("public class Q%s<R> extends TQAssocBean<%s,R> {", shortName, origShortName).eol();
|
||||
writer.append("public class Q%s<R> extends TQAssocBean<%s,R> {", shortName, shortInnerName).eol();
|
||||
|
||||
} else {
|
||||
writer.append("/**").eol();
|
||||
@@ -388,19 +387,4 @@ class SimpleQueryBeanWriter {
|
||||
return jfo.openWriter();
|
||||
}
|
||||
|
||||
private String derivePackage(String name) {
|
||||
int pos = name.lastIndexOf('.');
|
||||
if (pos == -1) {
|
||||
return "";
|
||||
}
|
||||
return name.substring(0, pos);
|
||||
}
|
||||
|
||||
private String deriveShortName(String name) {
|
||||
int pos = name.lastIndexOf('.');
|
||||
if (pos == -1) {
|
||||
return name;
|
||||
}
|
||||
return name.substring(pos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package io.ebean.querybean.generator;
|
||||
|
||||
class Util {
|
||||
|
||||
static String packageOf(boolean nested, String originName) {
|
||||
return nested ? nestedPackageOf(originName) : packageOf(originName);
|
||||
}
|
||||
|
||||
private static String nestedPackageOf(String cls) {
|
||||
int pos = cls.lastIndexOf('.');
|
||||
if (pos < 0) {
|
||||
return "";
|
||||
}
|
||||
pos = cls.lastIndexOf('.', pos - 1);
|
||||
return (pos == -1) ? "" : cls.substring(0, pos);
|
||||
}
|
||||
|
||||
private static String packageOf(String cls) {
|
||||
int pos = cls.lastIndexOf('.');
|
||||
return (pos == -1) ? "" : cls.substring(0, pos);
|
||||
}
|
||||
|
||||
static String shortName(boolean nested, String fullType) {
|
||||
return nested ? nestedShortName(fullType): shortName(fullType);
|
||||
}
|
||||
|
||||
private static String nestedShortName(String fullType) {
|
||||
int pos = fullType.lastIndexOf('.');
|
||||
if (pos < 0) {
|
||||
return fullType;
|
||||
} else {
|
||||
pos = fullType.lastIndexOf('.', pos - 1);
|
||||
return pos < 0 ? fullType : fullType.substring(pos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private static String shortName(String fullType) {
|
||||
int p = fullType.lastIndexOf('.');
|
||||
if (p == -1) {
|
||||
return fullType;
|
||||
} else {
|
||||
return fullType.substring(p + 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.ebean.querybean.generator;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class UtilTest {
|
||||
|
||||
@Test
|
||||
void packageOf() {
|
||||
assertEquals(Util.packageOf(true, "com.example.Foo.Bar"), "com.example");
|
||||
assertEquals(Util.packageOf(false, "com.example.other.foo.Bar"), "com.example.other.foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shortName() {
|
||||
assertEquals(Util.shortName(true, "com.example.Foo.Bar"), "Foo.Bar");
|
||||
assertEquals(Util.shortName(false, "com.example.foo.Bar"), "Bar");
|
||||
assertEquals(Util.shortName(false, "Bar"), "Bar");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user