diff --git a/ebean-api/src/main/java/io/ebean/ExpressionList.java b/ebean-api/src/main/java/io/ebean/ExpressionList.java index f02ccd44e..8e53e856d 100644 --- a/ebean-api/src/main/java/io/ebean/ExpressionList.java +++ b/ebean-api/src/main/java/io/ebean/ExpressionList.java @@ -1730,4 +1730,8 @@ public interface ExpressionList { */ ExpressionList endNot(); + /** + * Clears the current expression list. + */ + ExpressionList clear(); } diff --git a/ebean-bom/pom.xml b/ebean-bom/pom.xml index 293dc1070..194809f1c 100644 --- a/ebean-bom/pom.xml +++ b/ebean-bom/pom.xml @@ -193,12 +193,6 @@ - - io.ebean - ebean-all - 13.11.3-SNAPSHOT - - io.ebean ebean-clickhouse @@ -223,12 +217,6 @@ 13.11.3-SNAPSHOT - - io.ebean - ebean-hsqldb - 13.11.3-SNAPSHOT - - io.ebean ebean-mariadb @@ -259,12 +247,6 @@ 13.11.3-SNAPSHOT - - io.ebean - ebean-sqlanywhere - 13.11.3-SNAPSHOT - - io.ebean ebean-sqlite diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java index 3759ce9b0..d47988865 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java @@ -1268,4 +1268,10 @@ public class DefaultExpressionList implements SpiExpressionList { } return null; } + + @Override + public ExpressionList clear() { + list.clear(); + return this; + } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java index 3e202e99e..2f8dea86f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java @@ -1068,4 +1068,9 @@ final class JunctionExpression implements SpiJunction, SpiExpression, Expr } return null; } + + @Override + public ExpressionList clear() { + return exprList.clear(); + } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java index f78e11ea8..f8b1f3381 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java @@ -861,7 +861,7 @@ public final class DefaultPersister implements Persister { SpiTransaction t = request.transaction(); EntityBean orphanForRemoval = request.importedOrphanForRemoval(); if (orphanForRemoval != null) { - delete(orphanForRemoval, request.transaction(), true); + delete(orphanForRemoval, request.transaction(), false); } // exported ones with cascade save @@ -1079,7 +1079,7 @@ public final class DefaultPersister implements Persister { private void deleteOrphan(PersistRequestBean request, BeanPropertyAssocOne prop) { Object origValue = request.getOrigValue(prop); if (origValue instanceof EntityBean) { - delete((EntityBean) origValue, request.transaction(), true); + delete((EntityBean) origValue, request.transaction(), false); } } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/expression/DefaultExpressionListTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/expression/DefaultExpressionListTest.java index b89590936..69f9c8e43 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/expression/DefaultExpressionListTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/expression/DefaultExpressionListTest.java @@ -99,6 +99,14 @@ public class DefaultExpressionListTest extends BaseExpressionTest { .isSameByBind(spi(exp().eq("a", 10).eq("b", 20)))).isFalse(); } + @Test + public void isSameWithClear() { + DefaultExpressionList exp1 = spi(exp().eq("a", 10).eq("b", 20).clear().eq("c", 30)); + DefaultExpressionList exp2 = spi(exp().eq("c", 30)); + same(exp1, exp2); + assertThat(exp1.isSameByBind(exp2)).isTrue(); + } + @SuppressWarnings("unchecked") @Test void copy() { diff --git a/ebean-test/src/test/java/org/tests/o2m/StatefulO2MSoftDelete.java b/ebean-test/src/test/java/org/tests/o2m/StatefulO2MSoftDelete.java new file mode 100644 index 000000000..ab44e37d6 --- /dev/null +++ b/ebean-test/src/test/java/org/tests/o2m/StatefulO2MSoftDelete.java @@ -0,0 +1,43 @@ +package org.tests.o2m; + +import io.ebean.DB; +import io.ebean.test.LoggedSql; +import io.ebean.xtest.BaseTestCase; +import org.junit.jupiter.api.Test; +import org.tests.o2m.dm.GoodsEntity; +import org.tests.o2m.dm.WorkflowEntity; +import org.tests.o2m.dm.WorkflowOperationEntity; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class StatefulO2MSoftDelete extends BaseTestCase { + @Test + void statefulUpdateShouldntDelete() { + var bomGoods = new GoodsEntity(); + DB.save(bomGoods); + + var goods = new GoodsEntity(); + var workflow = new WorkflowEntity(); + var operation1 = new WorkflowOperationEntity(); + operation1.setName("operation 1"); + goods.setWorkflowEntity(workflow); + workflow.setOperations(List.of(operation1)); + + DB.save(goods); + + LoggedSql.start(); + // replace workflow entity + var goodsFromDB = DB.find(GoodsEntity.class, goods.getId()); + goodsFromDB.setWorkflowEntity(new WorkflowEntity()); + + DB.update(goodsFromDB); + var updateSql = LoggedSql.stop(); + updateSql.forEach(sql -> assertThat(sql).doesNotContain("delete from workflow_entity")); + if (isH2()) { + assertThat(updateSql.get(4)).contains("update workflow_operation_entity set deleted=true where workflow_id = ?"); + assertThat(updateSql.get(6)).contains("update workflow_entity set when_modified=?, deleted=? where id=?"); + } + } +}