diff --git a/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/BaseDbRowOp.java b/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/BaseDbRowOp.java index 1602aca399..e5c40198eb 100644 --- a/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/BaseDbRowOp.java +++ b/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/BaseDbRowOp.java @@ -76,4 +76,16 @@ public int hashCode() { public String toString() { return entity.getName() + " " + changeId; } + + protected boolean entitiesHaveSameNameAndDataMap(DbRowOp rowOp) { + return entitiesHaveSameName(rowOp) && entitiesHaveSameDataMap(rowOp); + } + + boolean entitiesHaveSameName(DbRowOp rowOp) { + return rowOp.getEntity().getName().equals(getEntity().getName()); + } + + private boolean entitiesHaveSameDataMap(DbRowOp rowOp) { + return rowOp.getEntity().getDataMap().getName().equals(getEntity().getDataMap().getName()); + } } diff --git a/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/DeleteDbRowOp.java b/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/DeleteDbRowOp.java index fc5328002d..9cc9cc34bb 100644 --- a/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/DeleteDbRowOp.java +++ b/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/DeleteDbRowOp.java @@ -58,7 +58,7 @@ public boolean isSameBatch(DbRowOp rowOp) { if(!(rowOp instanceof DeleteDbRowOp)) { return false; } - if(!rowOp.getEntity().getName().equals(getEntity().getName())) { + if(!entitiesHaveSameNameAndDataMap(rowOp)) { return false; } DeleteDbRowOp other = (DeleteDbRowOp) rowOp; diff --git a/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/InsertDbRowOp.java b/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/InsertDbRowOp.java index e0cd7d2149..f02b8ed04c 100644 --- a/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/InsertDbRowOp.java +++ b/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/InsertDbRowOp.java @@ -61,7 +61,7 @@ public boolean isSameBatch(DbRowOp rowOp) { if(!(rowOp instanceof InsertDbRowOp)) { return false; } - return rowOp.getEntity().getName().equals(getEntity().getName()); + return entitiesHaveSameNameAndDataMap(rowOp); } @Override diff --git a/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/UpdateDbRowOp.java b/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/UpdateDbRowOp.java index badc6ad2be..0dc8f2b926 100644 --- a/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/UpdateDbRowOp.java +++ b/cayenne/src/main/java/org/apache/cayenne/access/flush/operation/UpdateDbRowOp.java @@ -57,7 +57,7 @@ public boolean isSameBatch(DbRowOp rowOp) { if(!(rowOp instanceof UpdateDbRowOp)) { return false; } - if(!rowOp.getEntity().getName().equals(getEntity().getName())) { + if(!entitiesHaveSameNameAndDataMap(rowOp)) { return false; } UpdateDbRowOp other = (UpdateDbRowOp) rowOp; diff --git a/cayenne/src/test/java/org/apache/cayenne/access/flush/DefaultDataDomainFlushActionTest.java b/cayenne/src/test/java/org/apache/cayenne/access/flush/DefaultDataDomainFlushActionTest.java index 29b89a4969..277a2e7fae 100644 --- a/cayenne/src/test/java/org/apache/cayenne/access/flush/DefaultDataDomainFlushActionTest.java +++ b/cayenne/src/test/java/org/apache/cayenne/access/flush/DefaultDataDomainFlushActionTest.java @@ -32,6 +32,7 @@ import org.apache.cayenne.access.flush.operation.DeleteDbRowOp; import org.apache.cayenne.access.flush.operation.InsertDbRowOp; import org.apache.cayenne.access.flush.operation.UpdateDbRowOp; +import org.apache.cayenne.map.DataMap; import org.apache.cayenne.map.DbAttribute; import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.query.DeleteBatchQuery; @@ -168,6 +169,45 @@ public void createQueries() { assertEquals(1, delete2.getRows().size()); } + @Test + public void dontMergeSameTableNameOnDifferentDataMaps() { + DbEntity test1Datamap1 = mockEntity("test1", "datamap1"); + DbEntity test1Datamap2 = mockEntity("test1", "datamap2"); + DbEntity test2Datamap1 = mockEntity("test2", "datamap1"); + DbEntity test2Datamap2 = mockEntity("test2", "datamap2"); + DbEntity test3Datamap1 = mockEntity("test3", "datamap1"); + DbEntity test3Datamap2 = mockEntity("test3", "datamap2"); + + ObjectId id1 = ObjectId.of("test1", "id", 1); + ObjectId id2 = ObjectId.of("test1", "id", 2); + ObjectId id3 = ObjectId.of("test2", "id", 3); + ObjectId id4 = ObjectId.of("test2", "id", 4); + ObjectId id5 = ObjectId.of("test3", "id", 5); + ObjectId id6 = ObjectId.of("test3", "id", 6); + + UpdateDbRowOp update1 = new UpdateDbRowOp(mockObject(id3), test2Datamap1, id3); + update1.getValues().addValue(new DbAttribute("attr"), "abc", false); + update1.getValues().addValue(new DbAttribute("attr"), "abc", false); + + UpdateDbRowOp update2 = new UpdateDbRowOp(mockObject(id4), test2Datamap2, id4); + update2.getValues().addValue(new DbAttribute("attr"), "def", false); + update2.getValues().addValue(new DbAttribute("attr"), "def", false); + List ops = List.of( + new InsertDbRowOp(mockObject(id1), test1Datamap1, id1), + new InsertDbRowOp(mockObject(id2), test1Datamap2, id2), + update1, + update2, + new DeleteDbRowOp(mockObject(id5), test3Datamap1, id5), + new DeleteDbRowOp(mockObject(id6), test3Datamap2, id6) + ); + + DefaultDataDomainFlushAction action = mock(DefaultDataDomainFlushAction.class); + when(action.createQueries((List) any(List.class))).thenCallRealMethod(); + + List queries = action.createQueries(ops); + assertEquals(6, queries.size()); + } + private Persistent mockObject(ObjectId id) { Persistent persistent = mock(Persistent.class); when(persistent.getObjectId()).thenReturn(id); @@ -176,12 +216,17 @@ private Persistent mockObject(ObjectId id) { } private DbEntity mockEntity(String name) { + return mockEntity(name, "defaultMap"); + } + + private DbEntity mockEntity(String name, String datamapName) { DbAttribute attribute1 = new DbAttribute("id"); attribute1.setPrimaryKey(true); DbAttribute attribute2 = new DbAttribute("attr"); DbEntity testEntity = new DbEntity(name); testEntity.addAttribute(attribute1); testEntity.addAttribute(attribute2); + testEntity.setDataMap(new DataMap(datamapName)); return testEntity; } } \ No newline at end of file