diff --git a/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java b/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java index 0ff175eb4..9671d08cf 100644 --- a/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java +++ b/src/main/java/io/ebeaninternal/server/core/PersistRequestBean.java @@ -187,7 +187,7 @@ public final class PersistRequestBean extends PersistRequest implements BeanP /** * Many to many intersection table changes that are held for later batch processing. */ - private SaveManyBeans saveManyIntersection; + private List saveManyIntersections; public PersistRequestBean(SpiEbeanServer server, T bean, Object parentBean, BeanManager mgr, SpiTransaction t, PersistExecute persistExecute, PersistRequest.Type type, int flags) { @@ -965,8 +965,8 @@ public final class PersistRequestBean extends PersistRequest implements BeanP } private void saveQueuedManyIntersection() { - if (saveManyIntersection != null) { - saveManyIntersection.saveIntersectionBatch(); + if (saveManyIntersections != null) { + saveManyIntersections.forEach(SaveManyBeans::saveIntersectionBatch); } } @@ -1479,7 +1479,10 @@ public final class PersistRequestBean extends PersistRequest implements BeanP /** * The intersection table updates to the batch executed later on postExecute. */ - public void setManyIntersection(SaveManyBeans saveManyIntersection) { - this.saveManyIntersection = saveManyIntersection; + public void addManyIntersection(SaveManyBeans saveManyIntersection) { + if (this.saveManyIntersections == null) { + this.saveManyIntersections = new ArrayList<>(); + } + this.saveManyIntersections.add(saveManyIntersection); } } diff --git a/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java b/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java index 37a98d58a..c67521686 100644 --- a/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java +++ b/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java @@ -247,7 +247,7 @@ public class SaveManyBeans extends SaveManyBase { if (request.isQueueManyIntersection()) { // queue/delay until bean persist request is flushed this.deleteMissing = deleteMissingChildren; - request.setManyIntersection(this); + request.addManyIntersection(this); } else { saveAssocManyIntersection(deleteMissingChildren, false); } diff --git a/src/test/java/org/tests/sp/TestManyToManySaveTwice.java b/src/test/java/org/tests/sp/TestManyToManySaveTwice.java index 87d28e87a..a505a5d54 100644 --- a/src/test/java/org/tests/sp/TestManyToManySaveTwice.java +++ b/src/test/java/org/tests/sp/TestManyToManySaveTwice.java @@ -6,11 +6,13 @@ import io.ebean.Ebean; import io.ebean.Transaction; import org.junit.Test; import org.tests.sp.model.car.Car; +import org.tests.sp.model.car.Door; import org.tests.sp.model.car.Wheel; import java.util.LinkedList; import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -24,15 +26,24 @@ public class TestManyToManySaveTwice extends BaseTestCase { Wheel w0 = new Wheel("wx0"); Wheel w1 = new Wheel("wx1"); + Door d0 = new Door("dx0"); + Door d1 = new Door("dx1"); + List wheels = new LinkedList<>(); wheels.add(w0); wheels.add(w1); + List doors = new LinkedList<>(); + doors.add(d0); + doors.add(d1); + DB.saveAll(wheels); + DB.saveAll(doors); Car c0 = new Car("cx0"); c0.getWheels().add(w0); c0.getWheels().add(w1); + c0.getDoors().add(d0); Car c1 = new Car("cx1"); c1.getWheels().add(w1); @@ -45,6 +56,16 @@ public class TestManyToManySaveTwice extends BaseTestCase { transaction.commit(); } + + c0 = Ebean.find(Car.class, c0.getId()); + c1 = Ebean.find(Car.class, c1.getId()); + + assertThat(c0.getWheels()).hasSize(2); + assertThat(c0.getDoors()).hasSize(1); + + assertThat(c1.getWheels()).hasSize(1); + assertThat(c1.getDoors()).hasSize(0); + } @@ -101,7 +122,9 @@ public class TestManyToManySaveTwice extends BaseTestCase { private void delete() { DB.sqlUpdate("delete from sp_car_car_wheels").execute(); + DB.sqlUpdate("delete from sp_car_car_doors").execute(); DB.sqlUpdate("delete from sp_car_wheel").execute(); + DB.sqlUpdate("delete from sp_car_door").execute(); DB.sqlUpdate("delete from sp_car_car").execute(); } } diff --git a/src/test/java/org/tests/sp/model/car/Car.java b/src/test/java/org/tests/sp/model/car/Car.java index 1c30f5e58..d742444d2 100644 --- a/src/test/java/org/tests/sp/model/car/Car.java +++ b/src/test/java/org/tests/sp/model/car/Car.java @@ -22,6 +22,10 @@ public class Car extends IdEntity { @JoinTable(name = "sp_car_car_wheels", joinColumns = {@JoinColumn(name = "car")}, inverseJoinColumns = {@JoinColumn(name = "wheel")}) private List wheels; + @ManyToMany(cascade = CascadeType.ALL) + @JoinTable(name = "sp_car_car_doors", joinColumns = {@JoinColumn(name = "car")}, inverseJoinColumns = {@JoinColumn(name = "door")}) + private List doors; + public Car(String name) { this.name = name; } @@ -37,4 +41,12 @@ public class Car extends IdEntity { public void setWheels(List wheels) { this.wheels = wheels; } + + public List getDoors() { + return doors; + } + + public void setDoors(List doors) { + this.doors = doors; + } } diff --git a/src/test/java/org/tests/sp/model/car/Door.java b/src/test/java/org/tests/sp/model/car/Door.java new file mode 100644 index 000000000..db8576e65 --- /dev/null +++ b/src/test/java/org/tests/sp/model/car/Door.java @@ -0,0 +1,23 @@ +package org.tests.sp.model.car; + +import org.tests.sp.model.IdEntity; + +import javax.persistence.Entity; +import javax.persistence.Table; + +@Entity +@Table(name = "sp_car_door") +public class Door extends IdEntity { + + private static final long serialVersionUID = 2399600193947163469L; + + private String name; + + public Door(String name) { + this.name = name; + } + + public String getName() { + return name; + } +}