Skip to content

Commit b2670f9

Browse files
rbygraverPraml
andauthored
Lazy load pre delete 2 (#3748)
* Lazy load in pre-delete does not work * Re-add deleted beans before lazy-load will happen * Put the contextClear() calls into a finally This should mean that any beans put into the context would be cleared even if there was an issue with the loadBean() call. --------- Co-authored-by: Roland Praml <roland.praml@foconis.de>
1 parent ebc90e0 commit b2670f9

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadBeanContext.java

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ public void loadBean(EntityBeanIntercept ebi) {
227227
// re-add to the batch and lazy load from DB skipping l2 cache
228228
if (loadingStarted.get()) {
229229
if (CoreLog.markedAsDeleted.isLoggable(DEBUG)) {
230-
CoreLog.markedAsDeleted.log(DEBUG, "Adding " + ebi + "to batch " + this + "after loadingStarted(2) ", new RuntimeException("Adding to batch after load(2"));
230+
CoreLog.markedAsDeleted.log(DEBUG, "Adding " + ebi + "to batch " + this + "after loadingStarted(2) ", new RuntimeException("Adding to batch after load(2)"));
231231
}
232232
}
233233
batch.add(ebi);
@@ -239,9 +239,31 @@ public void loadBean(EntityBeanIntercept ebi) {
239239
return;
240240
}
241241
}
242-
243-
context.desc.ebeanServer().loadBean(new LoadBeanRequest(this, ebi, context.hitCache));
244-
batch.clear();
242+
// ensure, that every bean in the batch is in the persistence context.
243+
// this may happen, when bean was previously deleted, but the result is not yet committed.
244+
List<Object> reincarnatedIds = null;
245+
for (EntityBeanIntercept batchEbi : batch) {
246+
Object id = context.desc.getId(batchEbi.owner());
247+
if (id != null && context.desc.contextPutIfAbsent(persistenceContext, id, batchEbi.owner()) == null) {
248+
if (reincarnatedIds == null) {
249+
reincarnatedIds = new ArrayList<>();
250+
}
251+
reincarnatedIds.add(id);
252+
if (CoreLog.markedAsDeleted.isLoggable(DEBUG)) {
253+
CoreLog.markedAsDeleted.log(DEBUG, "Temporary adding " + ebi + "to persistence context", new RuntimeException("Temporary adding bean to persistence context"));
254+
}
255+
}
256+
}
257+
try {
258+
context.desc.ebeanServer().loadBean(new LoadBeanRequest(this, ebi, context.hitCache));
259+
batch.clear();
260+
} finally {
261+
if (reincarnatedIds != null) {
262+
for (Object id : reincarnatedIds) {
263+
context.desc.contextClear(persistenceContext, id);
264+
}
265+
}
266+
}
245267
}
246268
}
247269

ebean-test/src/test/java/io/ebean/xtest/event/BeanPersistControllerTest.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22

33

44
import io.ebean.Database;
5+
import io.ebean.DatabaseBuilder;
56
import io.ebean.DatabaseFactory;
67
import io.ebean.Transaction;
7-
import io.ebean.DatabaseBuilder;
88
import io.ebean.config.DatabaseConfig;
99
import io.ebean.event.BeanDeleteIdRequest;
1010
import io.ebean.event.BeanPersistAdapter;
11+
import io.ebean.event.BeanPersistController;
1112
import io.ebean.event.BeanPersistRequest;
13+
import io.ebean.test.LoggedSql;
1214
import org.junit.jupiter.api.Test;
1315
import org.slf4j.Logger;
1416
import org.slf4j.LoggerFactory;
@@ -139,7 +141,7 @@ public void testInsertUpdateDelete_given_stopPersistingAdapter() {
139141
assertThat(stopPersistingAdapter.methodsCalled).containsExactly("preDeleteById");
140142
stopPersistingAdapter.methodsCalled.clear();
141143

142-
db.deleteAll(EBasicVer.class, Arrays.asList(22,23,24));
144+
db.deleteAll(EBasicVer.class, Arrays.asList(22, 23, 24));
143145
assertThat(stopPersistingAdapter.methodsCalled).hasSize(3);
144146
assertThat(stopPersistingAdapter.methodsCalled).containsExactly("preDeleteById", "preDeleteById", "preDeleteById");
145147
stopPersistingAdapter.methodsCalled.clear();
@@ -202,12 +204,12 @@ public boolean preUpdate(BeanPersistRequest<?> request) {
202204

203205
Object bean = request.bean();
204206
if (bean instanceof UTDetail) {
205-
UTDetail detail = (UTDetail)bean;
207+
UTDetail detail = (UTDetail) bean;
206208
// invoke lazy loading ... which invoke the flush of the jdbc batch
207209
detail.setQty(42);
208210
}
209211
if (bean instanceof UTMaster) {
210-
UTMaster master = (UTMaster)bean;
212+
UTMaster master = (UTMaster) bean;
211213
UTMaster.Journal journal = master.getJournal();
212214
if (journal == null) {
213215
journal = new UTMaster.Journal();

0 commit comments

Comments
 (0)