mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
git push origin masterMerge branch 'FOCONIS-bug-refresh-one-to-many'
This commit is contained in:
@@ -613,8 +613,12 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollection<?> createReferenceIfNull(EntityBean parentBean) {
|
||||
public BeanCollection<?> createReference(EntityBean localBean, boolean forceNewReference) {
|
||||
return forceNewReference ? createReference(localBean) : createReferenceIfNull(localBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollection<?> createReferenceIfNull(EntityBean parentBean) {
|
||||
Object v = getValue(parentBean);
|
||||
if (v instanceof BeanCollection<?>) {
|
||||
BeanCollection<?> bc = (BeanCollection<?>) v;
|
||||
@@ -627,7 +631,6 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
}
|
||||
|
||||
public BeanCollection<?> createReference(EntityBean parentBean) {
|
||||
|
||||
BeanCollection<?> ref = help.createReference(parentBean);
|
||||
setValue(parentBean, ref);
|
||||
return ref;
|
||||
|
||||
@@ -22,6 +22,11 @@ public interface STreePropertyAssocMany extends STreePropertyAssoc {
|
||||
*/
|
||||
BeanCollection<?> createReferenceIfNull(EntityBean localBean);
|
||||
|
||||
/**
|
||||
* Return a reference collection forcing a new reference on REFRESH query.
|
||||
*/
|
||||
BeanCollection<?> createReference(EntityBean localBean, boolean forceNewReference);
|
||||
|
||||
/**
|
||||
* Return true if the property has a join table.
|
||||
*/
|
||||
|
||||
@@ -376,7 +376,7 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
||||
if (!lazyLoadMany && localBean != null) {
|
||||
ctx.setCurrentPrefix(prefix, pathMap);
|
||||
if (readId && !temporalVersions) {
|
||||
createListProxies(localDesc, ctx, localBean, disableLazyLoad);
|
||||
createListProxies();
|
||||
}
|
||||
if (temporalMode == SpiQuery.TemporalMode.DRAFT) {
|
||||
localDesc.setDraft(localBean);
|
||||
@@ -413,6 +413,30 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create lazy loading proxies for the Many's except for the one that is
|
||||
* included in the actual query.
|
||||
*/
|
||||
private void createListProxies() {
|
||||
STreePropertyAssocMany fetchedMany = ctx.getManyProperty();
|
||||
boolean forceNewReference = queryMode == Mode.REFRESH_BEAN;
|
||||
// load the List/Set/Map proxy objects (deferred fetching of lists)
|
||||
for (STreePropertyAssocMany many : localDesc.propsMany()) {
|
||||
if (many != fetchedMany) {
|
||||
// create a proxy for the many (deferred fetching)
|
||||
BeanCollection<?> ref = many.createReference(localBean, forceNewReference);
|
||||
if (ref != null) {
|
||||
if (disableLazyLoad) {
|
||||
ref.setDisableLazyLoad(true);
|
||||
}
|
||||
if (!ref.isRegisteredWithLoadContext()) {
|
||||
ctx.register(many.getName(), ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setBeanToParent() {
|
||||
if (parentBean != null) {
|
||||
// set this back to the parentBean
|
||||
@@ -463,32 +487,6 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
||||
return load.complete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create lazy loading proxies for the Many's except for the one that is
|
||||
* included in the actual query.
|
||||
*/
|
||||
private void createListProxies(STreeType localDesc, DbReadContext ctx, EntityBean localBean, boolean disableLazyLoad) {
|
||||
|
||||
STreePropertyAssocMany fetchedMany = ctx.getManyProperty();
|
||||
|
||||
// load the List/Set/Map proxy objects (deferred fetching of lists)
|
||||
for (STreePropertyAssocMany many : localDesc.propsMany()) {
|
||||
|
||||
if (fetchedMany == null || !fetchedMany.equals(many)) {
|
||||
// create a proxy for the many (deferred fetching)
|
||||
BeanCollection<?> ref = many.createReferenceIfNull(localBean);
|
||||
if (ref != null) {
|
||||
if (disableLazyLoad) {
|
||||
ref.setDisableLazyLoad(true);
|
||||
}
|
||||
if (!ref.isRegisteredWithLoadContext()) {
|
||||
ctx.register(many.getName(), ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendGroupBy(DbSqlContext ctx, boolean subQuery) {
|
||||
|
||||
|
||||
@@ -3,12 +3,14 @@ package io.ebean;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.basic.EBasic;
|
||||
import org.tests.model.basic.Order;
|
||||
import org.tests.model.basic.OrderDetail;
|
||||
import org.tests.model.basic.ResetBasicData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class EbeanServer_refresh {
|
||||
@@ -77,4 +79,77 @@ public class EbeanServer_refresh {
|
||||
Ebean.refresh(order);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void refresh_on_details_new() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
Order order = Ebean.find(Order.class, 1);
|
||||
|
||||
DB.refresh(order); // call refresh BEFORE first access on "getDetail";
|
||||
|
||||
assertThat(order.getDetails()).hasSize(3);
|
||||
|
||||
OrderDetail detail = new OrderDetail();
|
||||
detail.setOrder(order);
|
||||
DB.save(detail);
|
||||
|
||||
try {
|
||||
|
||||
assertThat(order.getDetails()).hasSize(3);
|
||||
|
||||
DB.refresh(order);
|
||||
|
||||
assertThat(order.getDetails()).hasSize(4);
|
||||
|
||||
} finally {
|
||||
DB.delete(detail); // restore old state
|
||||
}
|
||||
|
||||
DB.refresh(order);
|
||||
|
||||
assertThat(order.getDetails()).hasSize(3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void refresh_on_details_changed() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
Order order = Ebean.find(Order.class, 1);
|
||||
|
||||
DB.refresh(order); // call refresh BEFORE first access on "getDetail"
|
||||
// this changes the loader of the details-bean collection from DefaultServer to DLoadManyContext$LoadBuffer
|
||||
// if this refresh is commented out, the test will pass
|
||||
|
||||
assertThat(order.getDetails().get(0).getOrderQty()).isEqualTo(5);
|
||||
|
||||
// search the detail in the DB and change qty to 42
|
||||
OrderDetail detail = DB.find(OrderDetail.class, order.getDetails().get(0).getId());
|
||||
assertThat(order.getDetails().get(0)).isEqualTo(detail).isNotSameAs(detail);
|
||||
detail.setOrderQty(42);
|
||||
DB.save(detail);
|
||||
|
||||
try {
|
||||
assertThat(order.getDetails().get(0).getOrderQty()).isEqualTo(5);
|
||||
|
||||
DB.refresh(order);
|
||||
|
||||
assertThat(order.getDetails().get(0).getOrderQty()).isEqualTo(42);
|
||||
|
||||
} finally {
|
||||
// restore old value
|
||||
detail.setOrderQty(5);
|
||||
DB.save(detail);
|
||||
}
|
||||
|
||||
DB.refresh(order);
|
||||
|
||||
assertThat(order.getDetails().get(0).getOrderQty()).isEqualTo(5);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user