diff --git a/ebean-api/src/test/java/io/ebean/util/TestAnnotationUtil.java b/ebean-api/src/test/java/io/ebean/util/TestAnnotationUtil.java new file mode 100644 index 000000000..7d7519c03 --- /dev/null +++ b/ebean-api/src/test/java/io/ebean/util/TestAnnotationUtil.java @@ -0,0 +1,28 @@ +package io.ebean.util; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import io.ebean.annotation.Formula; + +public class TestAnnotationUtil { + + @Formula(select = "x") + @Formula(select = "y") + private static class TestObject { + + } + + @Test + public void testRepeatableAnnotation() { + + Set list = AnnotationUtil.typeGetAll(TestObject.class, Formula.class); + assertThat(list).hasSize(2); + + } + +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java index b1ca1686e..6ff7e5acb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java @@ -36,7 +36,6 @@ public final class OrmQueryRequest extends BeanRequest implements SpiOrmQuery private final Boolean readOnly; private LoadContext loadContext; private PersistenceContext persistenceContext; - private JsonReadOptions jsonRead; private HashQuery cacheKey; private CQueryPlanKey queryPlanKey; private SpiQuerySecondary secondaryQueries; @@ -259,7 +258,7 @@ public final class OrmQueryRequest extends BeanRequest implements SpiOrmQuery if (query.getPersistenceContext() == null) { query.setPersistenceContext(persistenceContext); } - jsonRead = new JsonReadOptions(); + JsonReadOptions jsonRead = new JsonReadOptions(); jsonRead.setPersistenceContext(persistenceContext); if (!query.isDisableLazyLoading()) { loadContext = new DLoadContext(this, secondaryQueries); @@ -534,7 +533,7 @@ public final class OrmQueryRequest extends BeanRequest implements SpiOrmQuery @SuppressWarnings({"rawtypes"}) private void mergeCacheHitsToMap(BeanCollection result) { - BeanMap map = (BeanMap)result; + BeanMap map = (BeanMap) result; ElPropertyValue property = mapProperty(); for (T bean : cacheBeans) { map.internalPut(property.pathGet(bean), bean); @@ -562,22 +561,18 @@ public final class OrmQueryRequest extends BeanRequest implements SpiOrmQuery @SuppressWarnings("unchecked") private Map cacheBeansToMap() { ElPropertyValue property = mapProperty(); - Map map = new LinkedHashMap<>(); + Map map = new LinkedHashMap<>(); for (T bean : cacheBeans) { - map.put((K)property.pathGet(bean), bean); + map.put((K) property.pathGet(bean), bean); } return map; } private ElPropertyValue mapProperty() { - ElPropertyValue property; - if (query.getMapKey() == null) { - property = beanDescriptor.idProperty(); - } else { - property = beanDescriptor.elGetValue(query.getMapKey()); - } + final String key = query.getMapKey(); + final ElPropertyValue property = key == null ? beanDescriptor.idProperty() : beanDescriptor.elGetValue(key); if (property == null) { - throw new IllegalStateException("Unknown map key property " + query.getMapKey()); + throw new IllegalStateException("Unknown map key property " + key); } return property; } @@ -639,7 +634,7 @@ public final class OrmQueryRequest extends BeanRequest implements SpiOrmQuery if (cached != null && isAuditReads() && readAuditQueryType()) { if (cached instanceof BeanCollection) { // raw sql can't use L2 cache so normal queries only in here - Collection actualDetails = ((BeanCollection)cached).getActualDetails(); + Collection actualDetails = ((BeanCollection) cached).getActualDetails(); List ids = new ArrayList<>(actualDetails.size()); for (T bean : actualDetails) { ids.add(beanDescriptor.idForJson(bean)); @@ -650,13 +645,13 @@ public final class OrmQueryRequest extends BeanRequest implements SpiOrmQuery if (Boolean.FALSE.equals(query.isReadOnly())) { // return shallow copies if readonly is explicitly set to false if (cached instanceof BeanCollection) { - cached = ((BeanCollection)cached).getShallowCopy(); + cached = ((BeanCollection) cached).getShallowCopy(); } else if (cached instanceof List) { - cached = new CopyOnFirstWriteList<>((List)cached); + cached = new CopyOnFirstWriteList<>((List) cached); } else if (cached instanceof Set) { - cached = new LinkedHashSet<>((Set)cached); + cached = new LinkedHashSet<>((Set) cached); } else if (cached instanceof Map) { - cached = new LinkedHashMap<>((Map)cached); + cached = new LinkedHashMap<>((Map) cached); } } return cached; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefInherit.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefInherit.java index 6ca843258..b797c5a0c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefInherit.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefInherit.java @@ -32,16 +32,14 @@ final class AssocOneHelpRefInherit extends AssocOneHelp { // read discriminator to determine the type InheritInfo rowInheritInfo = inherit.readType(ctx); BeanDescriptor desc; - if (rowInheritInfo == null) { - if(!inherit.hasChildren()) { - desc = inherit.desc(); - } else { - // ignore the id property - property.targetIdBinder.loadIgnore(ctx); - return null; - } - } else { + if (rowInheritInfo != null) { desc = rowInheritInfo.desc(); + } else if (!inherit.hasChildren()) { + desc = inherit.desc(); + } else { + // ignore the id property + property.targetIdBinder.loadIgnore(ctx); + return null; } Object id = property.targetIdBinder.read(ctx); if (id == null) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index 8d047e88e..325213933 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -3038,10 +3038,6 @@ public class BeanDescriptor implements BeanType, STreeType, SpiBeanType { return ebi.isReference() || referenceIdPropertyOnly(ebi); } - boolean hasIdPropertyOnly(EntityBeanIntercept ebi) { - return propertiesBaseScalar.length > 0 && ebi.hasIdOnly(idPropertyIndex); - } - public boolean referenceIdPropertyOnly(EntityBeanIntercept ebi) { return idOnlyReference && ebi.hasIdOnly(idPropertyIndex); } @@ -3060,7 +3056,7 @@ public class BeanDescriptor implements BeanType, STreeType, SpiBeanType { } void setReferenceIfIdOnly(EntityBeanIntercept ebi) { - if (hasIdPropertyOnly(ebi)) { + if (referenceIdPropertyOnly(ebi)) { ebi.setReference(idPropertyIndex); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPropertiesParser.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPropertiesParser.java index fef064e98..6a75b82a9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPropertiesParser.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPropertiesParser.java @@ -39,8 +39,8 @@ final class OrmQueryPropertiesParser { } final Set included = splitRawSelect(rawProperties); if (included.contains("*")) { - return ALL; - } + return ALL; + } return new Response(false, included); } diff --git a/ebean-test/src/test/java/org/tests/lazyforeignkeys/MainEntityRelation.java b/ebean-test/src/test/java/org/tests/lazyforeignkeys/MainEntityRelation.java index 5da5ffdbf..19d2bfd48 100644 --- a/ebean-test/src/test/java/org/tests/lazyforeignkeys/MainEntityRelation.java +++ b/ebean-test/src/test/java/org/tests/lazyforeignkeys/MainEntityRelation.java @@ -3,6 +3,9 @@ package org.tests.lazyforeignkeys; import io.ebean.annotation.DbForeignKey; import javax.persistence.*; + +import org.tests.model.basic.Cat; + import java.util.UUID; @@ -22,6 +25,11 @@ public class MainEntityRelation { @JoinColumn(name = "id2") @DbForeignKey(noConstraint = true) private MainEntity entity2; + + @ManyToOne + @JoinColumn(name = "cat_id") + @DbForeignKey(noConstraint = true) + private Cat cat; private String attr1; @@ -41,6 +49,14 @@ public class MainEntityRelation { this.entity2 = entity2; } + public Cat getCat() { + return cat; + } + + public void setCat(Cat cat) { + this.cat = cat; + } + public String getAttr1() { return attr1; } diff --git a/ebean-test/src/test/java/org/tests/lazyforeignkeys/TestLazyForeignKeys.java b/ebean-test/src/test/java/org/tests/lazyforeignkeys/TestLazyForeignKeys.java index 9d88e84ed..7fb3fcc05 100644 --- a/ebean-test/src/test/java/org/tests/lazyforeignkeys/TestLazyForeignKeys.java +++ b/ebean-test/src/test/java/org/tests/lazyforeignkeys/TestLazyForeignKeys.java @@ -8,6 +8,7 @@ import io.ebean.text.PathProperties; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.tests.model.basic.Cat; import java.util.List; @@ -56,7 +57,7 @@ public class TestLazyForeignKeys extends BaseTestCase { List sql = LoggedSql.stop(); assertThat(sql).hasSize(3); - assertSql(sql.get(0)).contains("select t0.id, t0.attr1, t0.id1, t0.id2 from main_entity_relation"); + assertSql(sql.get(0)).contains("select t0.id, t0.attr1, t0.id1, t0.id2, t1.species, t0.cat_id from main_entity_relation t0 left join animal t1 on t1.id = t0.cat_id"); if (isSqlServer() || isOracle()) { assertSql(sql.get(1)).contains("select t0.id, t0.attr1, t0.attr2, CASE WHEN t0.id is null THEN 1 ELSE 0 END from main_entity t0"); } else { @@ -86,4 +87,17 @@ public class TestLazyForeignKeys extends BaseTestCase { assertFalse(rel1.getEntity1().isDeleted()); assertTrue(rel1.getEntity2().isDeleted()); } + + @Test + public void testGetWithDbForeignKey() { + MainEntityRelation relation = DB.find(MainEntityRelation.class).findOne(); + Cat cat = new Cat(); + cat.setId(123L); + relation.setCat(cat); + DB.save(relation); + + relation = DB.find(MainEntityRelation.class).findOne(); + + assertNotNull(relation.getCat()); + } }