From 93ae5f2b7c0461358f8ef2c0f202bdfd3b31c272 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 30 Jan 2024 22:32:49 +1300 Subject: [PATCH] ToMany collections that are not loaded on freeze are marked unloaded They are marked as unloaded which means accessing the collection will throw a PersistenceException. e.g. customer.getOrders() will throw PersistenceException rather than return an empty list. --- ebean-api/src/main/java/io/ebean/common/BeanList.java | 3 ++- ebean-api/src/main/java/io/ebean/common/BeanMap.java | 3 ++- ebean-api/src/main/java/io/ebean/common/BeanSet.java | 3 ++- .../server/deploy/BeanPropertyAssocMany.java | 4 ++++ .../test/java/org/tests/query/TestQueryOrderById.java | 11 ++++++++--- 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/common/BeanList.java b/ebean-api/src/main/java/io/ebean/common/BeanList.java index 05e0e01bf..7b550d9c4 100644 --- a/ebean-api/src/main/java/io/ebean/common/BeanList.java +++ b/ebean-api/src/main/java/io/ebean/common/BeanList.java @@ -46,7 +46,8 @@ public final class BeanList extends AbstractBeanCollection implements List @Override public Object freeze() { - return list == null ? Collections.emptyList() : Collections.unmodifiableList(list); + // null -> illegal to access reference collection + return list == null ? null : Collections.unmodifiableList(list); } @Override diff --git a/ebean-api/src/main/java/io/ebean/common/BeanMap.java b/ebean-api/src/main/java/io/ebean/common/BeanMap.java index a0e92b9cc..03f959e20 100644 --- a/ebean-api/src/main/java/io/ebean/common/BeanMap.java +++ b/ebean-api/src/main/java/io/ebean/common/BeanMap.java @@ -39,7 +39,8 @@ public final class BeanMap extends AbstractBeanCollection implements Ma @Override public Object freeze() { - return map == null ? Collections.emptyMap() : Collections.unmodifiableMap(map); + // null -> illegal to access reference collection + return map == null ? null : Collections.unmodifiableMap(map); } @Override diff --git a/ebean-api/src/main/java/io/ebean/common/BeanSet.java b/ebean-api/src/main/java/io/ebean/common/BeanSet.java index c8abb6989..c58a375f3 100644 --- a/ebean-api/src/main/java/io/ebean/common/BeanSet.java +++ b/ebean-api/src/main/java/io/ebean/common/BeanSet.java @@ -42,7 +42,8 @@ public final class BeanSet extends AbstractBeanCollection implements Set illegal to access reference collection + return set == null ? null : Collections.unmodifiableSet(set); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java index 181150380..17df1462d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java @@ -1140,6 +1140,10 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc implements ST if (value instanceof BeanCollection) { BeanCollection bc = (BeanCollection) value; setValue(entityBean, bc.freeze()); + if (bc.isReference()) { + // make it an error to access the collection (no lazy loading allowed) + entityBean._ebean_getIntercept().setPropertyUnloaded(propertyIndex); + } } } } diff --git a/ebean-test/src/test/java/org/tests/query/TestQueryOrderById.java b/ebean-test/src/test/java/org/tests/query/TestQueryOrderById.java index 68f2fb5ba..e53f5707e 100644 --- a/ebean-test/src/test/java/org/tests/query/TestQueryOrderById.java +++ b/ebean-test/src/test/java/org/tests/query/TestQueryOrderById.java @@ -42,9 +42,13 @@ public class TestQueryOrderById extends BaseTestCase { for (Order order : orders) { Customer customer = order.getCustomer(); if (cachedCustomerIds.contains(customer.getId())) { - List orders1 = customer.getOrders(); - assertThat(orders1).isEmpty(); - assertThat(orders1).isSameAs(Collections.EMPTY_LIST); + // Illegal to access customer.orders as that was not loaded and no lazy loading is allowed + // List orders1 = customer.getOrders(); + // assertThat(orders1).isEmpty(); + // assertThat(orders1).isSameAs(Collections.EMPTY_LIST); + + List contacts = customer.getContacts(); + assertThat(contacts).isNotNull(); // customer.setContacts(new ArrayList<>()); // customer.setName("modified"); @@ -118,6 +122,7 @@ public class TestQueryOrderById extends BaseTestCase { // perform some lazy loading if we desire for (Customer customer : list) { + customer.getContacts().size(); Address billingAddress = customer.getBillingAddress(); if (billingAddress != null) { Country country = billingAddress.getCountry();