You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/02/24 07:17:06 UTC
cayenne git commit: CAY-2242 Fix from Matt Watson for multiple
insertion case.
Repository: cayenne
Updated Branches:
refs/heads/master 0c3e3b68c -> 91eb2c0ae
CAY-2242 Fix from Matt Watson for multiple insertion case.
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/91eb2c0a
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/91eb2c0a
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/91eb2c0a
Branch: refs/heads/master
Commit: 91eb2c0aede06162de39ab27f73ccc467b14fc6e
Parents: 0c3e3b6
Author: Nikita Timofeev <st...@gmail.com>
Authored: Fri Feb 24 09:56:29 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Feb 24 09:56:29 2017 +0300
----------------------------------------------------------------------
.../access/DataDomainFlattenedBucket.java | 67 +++++++++++++-------
.../cayenne/access/VerticalInheritanceIT.java | 27 ++++++++
2 files changed, 71 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/91eb2c0a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainFlattenedBucket.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainFlattenedBucket.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainFlattenedBucket.java
index b88a341..900174e 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainFlattenedBucket.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainFlattenedBucket.java
@@ -108,29 +108,53 @@ class DataDomainFlattenedBucket {
List<FlattenedArcKey> flattenedArcKeys = entry.getValue();
DataNode node = parent.getDomain().lookupDataNode(dbEntity.getDataMap());
+
+ // TODO: O(N) lookup
+ InsertBatchQuery existingQuery = findInsertBatchQuery(queries, dbEntity);
InsertBatchQuery newQuery = new InsertBatchQuery(dbEntity, 50);
- boolean newQueryAdded = false;
- // Here can be options with multiple arcs:
- // 1. they can go as different columns in a single row
- // 2. they can go as different rows in one batch
- // 3. mix of both
+ // merge the snapshots of the FAKs by ObjectId for all ToOne relationships in case we have multiple Arcs per Object
+ Map<ObjectId, Map<String, Object>> toOneSnapshots = new HashMap<>();
+
+ // gather the list of the ToMany snapshots (these will actually be their own insert rows)
+ List<Map<String, Object>> toManySnapshots = new ArrayList<>();
+
for (FlattenedArcKey flattenedArcKey : flattenedArcKeys) {
- Map<String, Object> snapshot = flattenedArcKey.buildJoinSnapshotForInsert(node);
- ObjectId objectId = null;
+ Map<String, Object> joinSnapshot = flattenedArcKey.buildJoinSnapshotForInsert(node);
+
+ if (flattenedArcKey.relationship.isToMany()) {
+ toManySnapshots.add(joinSnapshot);
+ } else {
+ ObjectId objectId = flattenedArcKey.id1.getSourceId();
+
+ Map<String, Object> snapshot = toOneSnapshots.get(objectId);
+
+ if (snapshot == null) {
+ toOneSnapshots.put(objectId, joinSnapshot);
+ } else {
+ // merge joinSnapshot data with existing snapshot
+ for (Map.Entry<String, Object> dbValue : joinSnapshot.entrySet()) {
+ snapshot.put(dbValue.getKey(), dbValue.getValue());
+ }
+ }
+ }
+ }
+
+ // apply the merged ToOne snapshots information and possibly merge it with an existing BatchQueryRow
+ for (Map.Entry<ObjectId, Map<String, Object>> flattenedSnapshot : toOneSnapshots.entrySet()) {
+ ObjectId objectId = flattenedSnapshot.getKey();
+ Map<String, Object> snapshot = flattenedSnapshot.getValue();
- // TODO: O(N) lookup
- InsertBatchQuery existingQuery = findInsertBatchQuery(queries, dbEntity);
if (existingQuery != null) {
+
// TODO: O(N) lookup
- BatchQueryRow existingRow = findRowForObjectId(existingQuery.getRows(), flattenedArcKey.id1.getSourceId());
+ BatchQueryRow existingRow = findRowForObjectId(existingQuery.getRows(), objectId);
// todo: do we need to worry about flattenedArcKey.id2 ?
if (existingRow != null) {
- objectId = existingRow.getObjectId();
List<DbAttribute> existingQueryDbAttributes = existingQuery.getDbAttributes();
- for (int i = 0; i < existingQueryDbAttributes.size(); i++) {
+ for(int i=0; i < existingQueryDbAttributes.size(); i++) {
Object value = existingRow.getValue(i);
if (value != null) {
snapshot.put(existingQueryDbAttributes.get(i).getName(), value);
@@ -140,21 +164,18 @@ class DataDomainFlattenedBucket {
}
newQuery.add(snapshot, objectId);
+ }
- if (existingQuery != null) {
- // replace inside arc loop, so next arc know about it
- queries.remove(existingQuery);
- queries.add(newQuery);
- newQueryAdded = true;
- // start clean query for the next arc
- newQuery = new InsertBatchQuery(dbEntity, 50);
- }
+ // apply the ToMany snapshots as new BatchQueryRows
+ for(Map<String, Object> toManySnapshot : toManySnapshots) {
+ newQuery.add(toManySnapshot);
}
- if(!newQueryAdded) {
- // if not replaced existing query already
- queries.add(newQuery);
+ if (existingQuery != null) {
+ queries.remove(existingQuery);
}
+
+ queries.add(newQuery);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/91eb2c0a/cayenne-server/src/test/java/org/apache/cayenne/access/VerticalInheritanceIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/VerticalInheritanceIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/VerticalInheritanceIT.java
index 1f2d512..147e468 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/VerticalInheritanceIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/VerticalInheritanceIT.java
@@ -619,4 +619,31 @@ public class VerticalInheritanceIT extends ServerCase {
assertEquals(other2, impl2.getOther2());
}
+ @Test
+ public void testInsertTwoObjectsWithMultipleAttributeAndMultipleRelationship() {
+ IvOther other1 = context.newObject(IvOther.class);
+ other1.setName("other1");
+
+ IvOther other2 = context.newObject(IvOther.class);
+ other2.setName("other2");
+
+ IvImpl impl1 = context.newObject(IvImpl.class);
+ impl1.setName("Impl 1");
+ impl1.setAttr1("attr1");
+ impl1.setAttr2("attr2");
+ impl1.setOther1(other1);
+ impl1.setOther2(other2);
+
+ IvImpl impl2 = context.newObject(IvImpl.class);
+ impl2.setName("Impl 2");
+ impl2.setAttr1("attr1");
+ impl2.setAttr2("attr2");
+ impl2.setOther1(other1);
+ impl2.setOther2(other2);
+
+ context.commitChanges();
+
+ assertEquals(2, ObjectSelect.query(IvImpl.class).selectCount(context));
+ }
+
}