Merge pull request #3220 from ebean-orm/feature/3216

#3216 - Fix querybean generation for @Embedded beans (fix for 13.22.0…
This commit is contained in:
Rob Bygrave
2023-09-11 23:06:31 +12:00
committed by GitHub
5 changed files with 163 additions and 28 deletions
@@ -0,0 +1,40 @@
package org.example.domain;
import javax.persistence.*;
@Entity
public class CaoBean {
@Id
private CaoKey key;
private String description;
@Version
private long version;
public CaoKey getKey() {
return key;
}
public void setKey(CaoKey key) {
this.key = key;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
}
@@ -0,0 +1,42 @@
package org.example.domain;
import javax.persistence.Embeddable;
@Embeddable
public class CaoKey {
private final int customer;
private final int type;
public CaoKey(int customer, int type) {
this.customer = customer;
this.type = type;
}
public int customer() {
return customer;
}
public int type() {
return type;
}
@Override
public int hashCode() {
int hc = 31 * 7 + customer;
hc = 31 * hc + type;
return hc;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o instanceof CaoKey) {
CaoKey k = (CaoKey) o;
return k.customer == customer && k.type == type;
}
return false;
}
}
@@ -0,0 +1,44 @@
package org.querytest;
import io.ebean.DB;
import org.example.domain.CaoBean;
import org.example.domain.CaoKey;
import org.example.domain.query.QCaoBean;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class QueryCaoBeanTest {
@Test
void withEmbeddedId() {
insertTestData();
List<CaoBean> list = new QCaoBean()
.key.type.eq(3)
.findList();
assertThat(list).hasSize(2);
for (CaoBean caoBean : list) {
assertThat(caoBean.getKey().type()).isEqualTo(3);
}
}
private static void insertTestData() {
var key = new CaoKey(42, 3);
var bean = new CaoBean();
bean.setKey(key);
bean.setDescription("hi");
DB.save(bean);
var key2 = new CaoKey(43, 3);
var bean2 = new CaoBean();
bean2.setKey(key2);
bean2.setDescription("hi2");
DB.save(bean2);
}
}
@@ -22,6 +22,7 @@ interface Constants {
String TQROOTBEAN = "io.ebean.typequery.TQRootBean";
String TQASSOCBEAN = "io.ebean.typequery.TQAssocBean";
String TQASSOC = "io.ebean.typequery.TQAssoc";
String TYPEQUERYBEAN = "io.ebean.typequery.TypeQueryBean";
String DATABASE = "io.ebean.Database";
String DB = "io.ebean.DB";
@@ -77,16 +77,21 @@ class SimpleQueryBeanWriter {
private void gatherPropertyDetails() {
importTypes.add(Constants.GENERATED);
importTypes.add(beanFullName);
importTypes.add(Constants.TQASSOCBEAN);
importTypes.add(Constants.TQROOTBEAN);
importTypes.add(Constants.TYPEQUERYBEAN);
importTypes.add(Constants.DATABASE);
importTypes.add(Constants.FETCHGROUP);
importTypes.add(Constants.QUERY);
importTypes.add(Constants.TRANSACTION);
importTypes.add(Constants.CONSUMER);
importTypes.add(Constants.EXPR);
importTypes.add(Constants.EXPRESSIONLIST);
if (embeddable) {
importTypes.add(Constants.TQASSOC);
} else {
importTypes.add(Constants.TQASSOCBEAN);
importTypes.add(Constants.TQROOTBEAN);
importTypes.add(Constants.DATABASE);
importTypes.add(Constants.FETCHGROUP);
importTypes.add(Constants.QUERY);
importTypes.add(Constants.TRANSACTION);
importTypes.add(Constants.CONSUMER);
importTypes.add(Constants.EXPR);
importTypes.add(Constants.EXPRESSIONLIST);
}
if (implementsInterface != null) {
implementsInterfaceFullName = implementsInterface.getQualifiedName().toString();
boolean nested = implementsInterface.getNestingKind().isNested();
@@ -122,24 +127,20 @@ class SimpleQueryBeanWriter {
*/
void writeRootBean() throws IOException {
gatherPropertyDetails();
if (isEmbeddable()) {
processingContext.addEntity(beanFullName, dbName);
} else if (isEntity()) {
processingContext.addEntity(beanFullName, dbName);
writer = new Append(createFileWriter());
writePackage();
writeImports();
writeClass();
processingContext.addEntity(beanFullName, dbName);
writer = new Append(createFileWriter());
writePackage();
writeImports();
writeClass();
if (isEntity()) {
writeAlias();
writeFields();
writeConstructors();
writeStaticAliasClass();
writeAssocClass();
writeClassEnd();
writer.close();
}
writeAssocClass();
writeClassEnd();
writer.close();
}
/**
@@ -237,8 +238,12 @@ class SimpleQueryBeanWriter {
writer.append(" * THIS IS A GENERATED OBJECT, DO NOT MODIFY THIS CLASS.").eol();
writer.append(" */").eol();
writer.append(Constants.AT_GENERATED).eol();
writer.append(Constants.AT_TYPEQUERYBEAN).eol();
writer.append("public final class Q%s extends TQRootBean<%1$s,Q%1$s> {", shortName).eol();
if (embeddable) {
writer.append("public final class Q%s {", shortName).eol();
} else {
writer.append(Constants.AT_TYPEQUERYBEAN).eol();
writer.append("public final class Q%s extends TQRootBean<%1$s,Q%1$s> {", shortName).eol();
}
writer.eol();
}
@@ -276,9 +281,9 @@ class SimpleQueryBeanWriter {
writer.append(" ").append(Constants.AT_GENERATED).eol();
writer.append(" ").append(Constants.AT_TYPEQUERYBEAN).eol();
if (embeddable) {
writer.append(" public static final class Assoc<R> extends TQAssoc<%s,R> {", shortName, shortInnerName).eol();
writer.append(" public static final class Assoc<R> extends TQAssoc<%s,R> {", shortInnerName).eol();
} else {
writer.append(" public static final class Assoc<R> extends TQAssocBean<%s,R,Q%s> {", shortName, shortInnerName, origShortName).eol();
writer.append(" public static final class Assoc<R> extends TQAssocBean<%s,R,Q%s> {", shortName, shortInnerName).eol();
}
for (PropertyMeta property : properties) {
writer.append(" ");
@@ -287,12 +292,15 @@ class SimpleQueryBeanWriter {
}
writer.eol();
writeAssocBeanConstructor();
writeAssocFilterMany();
writeAssocBeanFetch();
if (!embeddable) {
writeAssocFilterMany();
writeAssocBeanFetch();
}
writer.append(" }").eol();
}
private void writeAssocFilterMany() {
writer.eol();
writer.append(" public final R filterMany(Consumer<Q%s> apply) {", shortName).eol();
writer.append(" final ExpressionList list = Expr.factory().expressionList();", shortName).eol();
writer.append(" final var qb = new Q%s(list);", shortName).eol();