Skip to content

Commit

Permalink
Merge pull request #3322 from ebean-orm/fix/3319
Browse files Browse the repository at this point in the history
(fix) Future queries do not trigger flush on BatchedPstmtHolder for #3319
  • Loading branch information
rbygrave authored Feb 9, 2024
2 parents 357af58 + 1f48b3a commit c71971e
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 0 deletions.
10 changes: 10 additions & 0 deletions ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,16 @@ public static TemporalMode of(SpiQuery<?> query) {
*/
ObjectGraphNode parentNode();

/**
* Set that this is a future query that will execute in the background.
*/
void usingFuture();

/**
* Return true if this is a future query.
*/
boolean isUsingFuture();

/**
* Return false when this is a lazy load or refresh query for a bean.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,7 @@ public <T> int update(SpiQuery<T> query) {
@Override
public <T> FutureRowCount<T> findFutureCount(SpiQuery<T> query) {
SpiQuery<T> copy = query.copy();
copy.usingFuture();
boolean createdTransaction = false;
SpiTransaction transaction = query.transaction();
if (transaction == null) {
Expand All @@ -1291,6 +1292,7 @@ public <T> FutureRowCount<T> findFutureCount(SpiQuery<T> query) {
@Override
public <T> FutureIds<T> findFutureIds(SpiQuery<T> query) {
SpiQuery<T> copy = query.copy();
copy.usingFuture();
boolean createdTransaction = false;
SpiTransaction transaction = query.transaction();
if (transaction == null) {
Expand All @@ -1309,6 +1311,7 @@ public <T> FutureIds<T> findFutureIds(SpiQuery<T> query) {
@Override
public <T> FutureList<T> findFutureList(SpiQuery<T> query) {
SpiQuery<T> spiQuery = query.copy();
spiQuery.usingFuture();
// FutureList query always run in it's own persistence content
spiQuery.setPersistenceContext(new DefaultPersistenceContext());
if (!spiQuery.isDisableReadAudit()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public boolean isMultiValueSupported(Class<?> cls) {
* Flushes the jdbc batch by default unless explicitly turned off on the transaction.
*/
private <T> void flushJdbcBatchOnQuery(OrmQueryRequest<T> request) {
if (request.query().isUsingFuture()) {
// future queries never invoke a flush
return;
}
SpiTransaction t = request.transaction();
if (t.isFlushOnQuery()) {
// before we perform a query, we need to flush any
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
private Type type;
private String label;
private Mode mode = Mode.NORMAL;
private boolean usingFuture;
private Object tenantId;
/**
* Holds query in structured form.
Expand Down Expand Up @@ -971,6 +972,16 @@ public final void setMode(Mode mode) {
this.mode = mode;
}

@Override
public final void usingFuture() {
this.usingFuture = true;
}

@Override
public final boolean isUsingFuture() {
return usingFuture;
}

@Override
public final boolean isUsageProfiling() {
return usageProfiling;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,87 @@
import org.tests.model.basic.EBasic;

import java.util.List;
import java.util.concurrent.ExecutionException;

import static org.assertj.core.api.Assertions.assertThat;

class TestFindFutureRowCount extends BaseTestCase {

@Test
void futureCount_doesNotTriggerFlush() throws ExecutionException, InterruptedException {
try (Transaction transaction = DB.beginTransaction()) {
transaction.setBatchMode(true);
transaction.setBatchSize(100);

EBasic basic = new EBasic("count_batched");
DB.save(basic);

FutureRowCount<EBasic> futureCount = DB.find(EBasic.class)
.where().eq("name", "count_batched")
.findFutureCount();

assertThat(futureCount.get()).isEqualTo(0);

transaction.flush();

FutureRowCount<EBasic> futureCountAfter = DB.find(EBasic.class)
.where().eq("name", "count_batched")
.findFutureCount();

assertThat(futureCountAfter.get()).isEqualTo(1);
}
}

@Test
void futureList_doesNotTriggerFlush() throws ExecutionException, InterruptedException {
try (Transaction transaction = DB.beginTransaction()) {
transaction.setBatchMode(true);
transaction.setBatchSize(100);

EBasic basic = new EBasic("list_batched");
DB.save(basic);

FutureList<EBasic> futureList = DB.find(EBasic.class)
.where().eq("name", "list_batched")
.findFutureList();

assertThat(futureList.get()).isEmpty();

transaction.flush();

FutureList<EBasic> futureListAfter = DB.find(EBasic.class)
.where().eq("name", "list_batched")
.findFutureList();

assertThat(futureListAfter.get()).hasSize(1);
}
}

@Test
void futureIds_doesNotTriggerFlush() throws ExecutionException, InterruptedException {
try (Transaction transaction = DB.beginTransaction()) {
transaction.setBatchMode(true);
transaction.setBatchSize(100);

EBasic basic = new EBasic("ids_batched");
DB.save(basic);

FutureIds<EBasic> futureIds = DB.find(EBasic.class)
.where().eq("name", "ids_batched")
.findFutureIds();

assertThat(futureIds.get()).isEmpty();

transaction.flush();

FutureIds<EBasic> futureIdsAfter = DB.find(EBasic.class)
.where().eq("name", "ids_batched")
.findFutureIds();

assertThat(futureIdsAfter.get()).hasSize(1);
}
}

@Test
void count_when_inTransaction() throws Exception {
try (Transaction transaction = DB.beginTransaction()) {
Expand Down

0 comments on commit c71971e

Please sign in to comment.