This is an automated email from the ASF dual-hosted git repository.

ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit 4e1bd02c6c0a4ca42321b4d1f5688cf460829f92
Author: Nikita Timofeev <stari...@gmail.com>
AuthorDate: Thu Jun 30 18:00:18 2022 +0300

    CAY-2737 Cayenne 4.3: cleanup deprecated code
     - delete LegacyDataDomainFlushAction
---
 .../cayenne/access/DataDomainDBDiffBuilder.java    | 252 --------------
 .../cayenne/access/DataDomainDeleteBucket.java     | 128 --------
 .../cayenne/access/DataDomainFlattenedBucket.java  | 208 ------------
 .../cayenne/access/DataDomainFlushObserver.java    | 162 ---------
 .../access/DataDomainIndirectDiffBuilder.java      | 178 ----------
 .../cayenne/access/DataDomainInsertBucket.java     | 237 --------------
 .../cayenne/access/DataDomainSyncBucket.java       | 278 ----------------
 .../cayenne/access/DataDomainUpdateBucket.java     | 157 ---------
 .../access/DataNodeSyncQualifierDescriptor.java    | 162 ---------
 .../java/org/apache/cayenne/access/DbArcId.java    |  96 ------
 .../cayenne/access/DbEntityClassDescriptor.java    | 111 -------
 .../org/apache/cayenne/access/FlattenedArcKey.java | 362 ---------------------
 .../access/LegacyDataDomainFlushAction.java        | 271 ---------------
 .../access/LegacyDataDomainFlushActionFactory.java |  45 ---
 14 files changed, 2647 deletions(-)

diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainDBDiffBuilder.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainDBDiffBuilder.java
deleted file mode 100644
index 013a201f8..000000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainDBDiffBuilder.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.access.DataDomainSyncBucket.PropagatedValueFactory;
-import org.apache.cayenne.exp.parser.ASTDbPath;
-import org.apache.cayenne.graph.ArcId;
-import org.apache.cayenne.graph.GraphChangeHandler;
-import org.apache.cayenne.graph.GraphDiff;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbJoin;
-import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.map.ObjAttribute;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.map.ObjRelationship;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Processes object diffs, generating DB diffs. Can be used for both UPDATE and
- * INSERT.
- * 
- * @since 1.2
- * @deprecated since 4.2 as part of deprecated {@link 
LegacyDataDomainFlushAction}
- */
-@Deprecated
-class DataDomainDBDiffBuilder implements GraphChangeHandler {
-
-    private ObjEntity objEntity;
-    private DbEntity dbEntity;
-
-    // diff snapshot expressed in terms of object properties.
-    private Map<Object, Object> currentPropertyDiff;
-    private Map<Object, Object> currentArcDiff;
-    private Object currentId;
-
-    /**
-     * Resets the builder to process a new combination of objEntity/dbEntity.
-     */
-    void reset(DbEntityClassDescriptor descriptor) {
-        this.objEntity = descriptor.getEntity();
-        this.dbEntity = descriptor.getDbEntity();
-    }
-
-    /**
-     * Resets the builder to process a new object for the previously set
-     * combination of objEntity/dbEntity.
-     */
-    private void reset() {
-        currentPropertyDiff = null;
-        currentArcDiff = null;
-        currentId = null;
-    }
-
-    /**
-     * Processes GraphDiffs of a single object, converting them to DB diff.
-     */
-    Map<String, Object> buildDBDiff(GraphDiff singleObjectDiff) {
-
-        reset();
-        singleObjectDiff.apply(this);
-
-        if (currentPropertyDiff == null && currentArcDiff == null && currentId 
== null) {
-            return null;
-        }
-
-        Map<String, Object> dbDiff = new HashMap<>();
-
-        appendSimpleProperties(dbDiff);
-        appendForeignKeys(dbDiff);
-        appendPrimaryKeys(dbDiff);
-
-        return dbDiff.isEmpty() ? null : dbDiff;
-    }
-
-    private void appendSimpleProperties(Map<String, Object> dbDiff) {
-        // populate changed columns
-        if (currentPropertyDiff != null) {
-            for (final Map.Entry<Object, Object> entry : 
currentPropertyDiff.entrySet()) {
-                ObjAttribute attribute = 
objEntity.getAttribute(entry.getKey().toString());
-
-                // In case of a flattened attribute, ensure that it belongs to 
this bucket...
-                DbAttribute dbAttribute = attribute.getDbAttribute();
-                if (dbAttribute.getEntity() == dbEntity) {
-                    dbDiff.put(dbAttribute.getName(), entry.getValue());
-                }
-            }
-        }
-    }
-
-    private void appendForeignKeys(Map<String, Object> dbDiff) {
-        // populate changed FKs
-        if (currentArcDiff != null) {
-            for (Entry<Object, Object> entry : currentArcDiff.entrySet()) {
-
-                DbRelationship dbRelation;
-
-                String arcIdString = entry.getKey().toString();
-                ObjRelationship relation = 
objEntity.getRelationship(arcIdString);
-                if (relation == null) {
-                    dbRelation = 
dbEntity.getRelationship(arcIdString.substring(ASTDbPath.DB_PREFIX.length()));
-                } else {
-                    dbRelation = 
relation.getDbRelationships().get(relation.getDbRelationships().size() - 1);
-                }
-
-                // In case of a vertical inheritance, ensure that it belongs 
to this bucket...
-                if (dbRelation.getSourceEntity() == dbEntity) {
-                    ObjectId targetId = (ObjectId) entry.getValue();
-                    for (DbJoin join : dbRelation.getJoins()) {
-                        Object value = (targetId != null)
-                                ? new PropagatedValueFactory(targetId, 
join.getTargetName())
-                                : null;
-
-                        dbDiff.put(join.getSourceName(), value);
-                    }
-                }
-            }
-        }
-    }
-
-    private void appendPrimaryKeys(Map<String, Object> dbDiff) {
-
-        // populate changed PKs; note that we might end up overriding some
-        // values taken
-        // from the object (e.g. zero PK's).
-        if (currentId != null) {
-            dbDiff.putAll(((ObjectId) currentId).getIdSnapshot());
-        }
-    }
-
-    // ==================================================
-    // GraphChangeHandler methods.
-    // ==================================================
-
-    @Override
-    public void nodePropertyChanged(Object nodeId, String property, Object 
oldValue, Object newValue) {
-        // note - no checking for phantom mod... assuming there is no phantom
-        // diffs
-
-        if (currentPropertyDiff == null) {
-            currentPropertyDiff = new HashMap<>();
-        }
-
-        currentPropertyDiff.put(property, newValue);
-    }
-
-    @Override
-    public void arcCreated(Object nodeId, Object targetNodeId, ArcId arcId) {
-        String arcIdString = arcId.toString();
-        ObjRelationship relationship = objEntity.getRelationship(arcIdString);
-
-        if (relationship == null) {
-            // phantom FK
-            if (arcIdString.startsWith(ASTDbPath.DB_PREFIX)) {
-                String relName = 
arcIdString.substring(ASTDbPath.DB_PREFIX.length());
-                DbRelationship dbRelationship = 
dbEntity.getRelationship(relName);
-                if (!dbRelationship.isSourceIndependentFromTargetChange()) {
-                    doArcCreated(targetNodeId, arcId);
-                }
-            } else {
-                throw new IllegalArgumentException("Bad arcId: " + arcId);
-            }
-
-        } else {
-            if (!relationship.isToMany() && relationship.isToPK()) {
-                doArcCreated(targetNodeId, arcId);
-            }
-        }
-    }
-
-    private void doArcCreated(Object targetNodeId, ArcId arcId) {
-        if (currentArcDiff == null) {
-            currentArcDiff = new HashMap<>();
-        }
-        currentArcDiff.put(arcId, targetNodeId);
-    }
-
-    @Override
-    public void arcDeleted(Object nodeId, Object targetNodeId, ArcId arcId) {
-
-        String arcIdString = arcId.toString();
-        ObjRelationship relationship = objEntity.getRelationship(arcIdString);
-
-        if (relationship == null) {
-            // phantom FK
-            if (arcIdString.startsWith(ASTDbPath.DB_PREFIX)) {
-
-                DbRelationship dbRelationship = 
dbEntity.getRelationship(arcIdString.substring(ASTDbPath.DB_PREFIX
-                        .length()));
-                if (!dbRelationship.isSourceIndependentFromTargetChange()) {
-                    doArcDeleted(targetNodeId, arcId);
-                }
-            } else {
-                throw new IllegalArgumentException("Bad arcId: " + arcId);
-            }
-
-        } else if (!relationship.isSourceIndependentFromTargetChange()) {
-            doArcDeleted(targetNodeId, arcId);
-        }
-    }
-
-    private void doArcDeleted(Object targetNodeId, ArcId arcId) {
-        if (currentArcDiff == null) {
-            currentArcDiff = new HashMap<>();
-            currentArcDiff.put(arcId, null);
-        } else {
-            // skip deletion record if a substitute arc was created prior to
-            // deleting the old arc...
-            Object existingTargetId = currentArcDiff.get(arcId);
-            if (existingTargetId == null || 
targetNodeId.equals(existingTargetId)) {
-                currentArcDiff.put(arcId, null);
-            }
-        }
-    }
-
-    @Override
-    public void nodeCreated(Object nodeId) {
-        // need to append PK columns
-        this.currentId = nodeId;
-    }
-
-    @Override
-    public void nodeRemoved(Object nodeId) {
-        // noop
-    }
-
-    @Override
-    public void nodeIdChanged(Object nodeId, Object newId) {
-        // noop
-    }
-}
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainDeleteBucket.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainDeleteBucket.java
deleted file mode 100644
index 755c01b59..000000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainDeleteBucket.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.EntitySorter;
-import org.apache.cayenne.query.DeleteBatchQuery;
-import org.apache.cayenne.query.Query;
-
-/**
- * @since 1.2
- * @deprecated since 4.2 as part of deprecated {@link 
LegacyDataDomainFlushAction}
- */
-@Deprecated
-class DataDomainDeleteBucket extends DataDomainSyncBucket {
-
-    DataDomainDeleteBucket(LegacyDataDomainFlushAction parent) {
-        super(parent);
-    }
-
-    @Override
-    void postprocess() {
-
-        if (!objectsByDescriptor.isEmpty()) {
-
-            Collection<ObjectId> deletedIds = parent.getResultDeletedIds();
-
-            for (List<Persistent> objects : objectsByDescriptor.values()) {
-                for (Persistent object : objects) {
-                    deletedIds.add(object.getObjectId());
-                }
-            }
-        }
-    }
-
-    @Override
-    void appendQueriesInternal(Collection<Query> queries) {
-
-        DataNodeSyncQualifierDescriptor qualifierBuilder = new 
DataNodeSyncQualifierDescriptor();
-
-        EntitySorter sorter = parent.getDomain().getEntitySorter();
-        sorter.sortDbEntities(dbEntities, true);
-
-        for (DbEntity dbEntity : dbEntities) {
-            Collection<DbEntityClassDescriptor> descriptors = 
descriptorsByDbEntity
-                    .get(dbEntity);
-            Map<Object, Query> batches = new LinkedHashMap<>();
-
-            for (DbEntityClassDescriptor descriptor : descriptors) {
-
-                qualifierBuilder.reset(descriptor);
-
-                boolean isRootDbEntity = descriptor.isMaster();
-
-                // remove object set for dependent entity, so that it does not 
show up
-                // on post processing
-                List<Persistent> objects = objectsByDescriptor.get(descriptor
-                        .getClassDescriptor());
-                if (objects.isEmpty()) {
-                    continue;
-                }
-
-                checkReadOnly(descriptor.getEntity());
-
-                if (isRootDbEntity) {
-                    sorter.sortObjectsForEntity(descriptor.getEntity(), 
objects, true);
-                }
-
-                for (Persistent o : objects) {
-                    ObjectDiff diff = parent.objectDiff(o.getObjectId());
-
-                    Map<String, Object> qualifierSnapshot = qualifierBuilder
-                            .createQualifierSnapshot(diff);
-
-                    // organize batches by the nulls in qualifier
-                    Set<String> nullQualifierNames = new HashSet<String>();
-                    for (Map.Entry<String, ?> entry : 
qualifierSnapshot.entrySet()) {
-                        if (entry.getValue() == null) {
-                            nullQualifierNames.add(entry.getKey());
-                        }
-                    }
-
-                    Object batchKey = Arrays.asList(nullQualifierNames);
-
-                    DeleteBatchQuery batch = (DeleteBatchQuery) 
batches.get(batchKey);
-                    if (batch == null) {
-                        batch = new DeleteBatchQuery(dbEntity, qualifierBuilder
-                                .getAttributes(), nullQualifierNames, 27);
-                        batch.setUsingOptimisticLocking(qualifierBuilder
-                                .isUsingOptimisticLocking());
-                        batches.put(batchKey, batch);
-                    }
-
-                    batch.add(qualifierSnapshot);
-                }
-            }
-
-            queries.addAll(batches.values());
-        }
-    }
-}
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
deleted file mode 100644
index 488affd0c..000000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainFlattenedBucket.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.query.BatchQueryRow;
-import org.apache.cayenne.query.DeleteBatchQuery;
-import org.apache.cayenne.query.InsertBatchQuery;
-import org.apache.cayenne.query.Query;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A sync bucket that holds flattened queries.
- * 
- * @since 1.2
- * @deprecated since 4.2 as part of deprecated {@link 
LegacyDataDomainFlushAction}
- */
-@Deprecated
-class DataDomainFlattenedBucket {
-
-    final LegacyDataDomainFlushAction parent;
-    final Map<DbEntity, List<FlattenedArcKey>> insertArcKeys;
-    final Map<DbEntity, DeleteBatchQuery> flattenedDeleteQueries;
-
-    DataDomainFlattenedBucket(LegacyDataDomainFlushAction parent) {
-        this.parent = parent;
-        this.insertArcKeys = new HashMap<>();
-        this.flattenedDeleteQueries = new HashMap<>();
-    }
-
-    boolean isEmpty() {
-        return insertArcKeys.isEmpty() && flattenedDeleteQueries.isEmpty();
-    }
-
-    void addInsertArcKey(DbEntity flattenedEntity, FlattenedArcKey 
flattenedArcKey) {
-        List<FlattenedArcKey> arcKeys = insertArcKeys.get(flattenedEntity);
-
-        if (arcKeys == null) {
-            arcKeys = new ArrayList<>();
-            insertArcKeys.put(flattenedEntity, arcKeys);
-        }
-
-        arcKeys.add(flattenedArcKey);
-    }
-
-    void addFlattenedDelete(DbEntity flattenedEntity, FlattenedArcKey 
flattenedDeleteInfo) {
-
-        DeleteBatchQuery relationDeleteQuery = 
flattenedDeleteQueries.get(flattenedEntity);
-        if (relationDeleteQuery == null) {
-            Collection<DbAttribute> pk = flattenedEntity.getPrimaryKeys();
-            List<DbAttribute> pkList = pk instanceof List ? 
(List<DbAttribute>) pk : new ArrayList<>(pk);
-            relationDeleteQuery = new DeleteBatchQuery(flattenedEntity, 
pkList, Collections.<String> emptySet(), 50);
-            relationDeleteQuery.setUsingOptimisticLocking(false);
-            flattenedDeleteQueries.put(flattenedEntity, relationDeleteQuery);
-        }
-
-        DataNode node = 
parent.getDomain().lookupDataNode(flattenedEntity.getDataMap());
-        List<Map<String, Object>> flattenedSnapshots = 
flattenedDeleteInfo.buildJoinSnapshotsForDelete(node);
-        if (!flattenedSnapshots.isEmpty()) {
-            for (Map<String, Object> flattenedSnapshot : flattenedSnapshots) {
-                relationDeleteQuery.add(flattenedSnapshot);
-            }
-        }
-    }
-
-    /**
-     * responsible for adding the flattened Insert Queries. Its possible an 
insert query for the same DbEntity/ObjectId
-     * already has been added from the insert bucket queries if that Object 
also has an attribute. So we want to merge
-     * the data for each insert into a single insert.
-     */
-    void appendInserts(Collection<Query> queries) {
-
-        // TODO: see "O(N) lookups" TODO's below. The first is relatively 
benign, as N is the number of DbEntities in the
-        // preceeding DataDomainInsertBucket processing. The second nested one 
is potentially much worse, as it may
-        // result in a linear scan of thousands of objects. E.g. it will 
affect cases with vertical inheritance with
-        // relationships in subclasses...
-
-        // The fix to the above is to merge this code into 
DataDomainInsertBucket, so that we can combine regular and
-        // flattened snapshots at the point of InsertBatchQuery creation.
-
-        for (Map.Entry<DbEntity, List<FlattenedArcKey>> entry : 
insertArcKeys.entrySet()) {
-            DbEntity dbEntity = entry.getKey();
-            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);
-
-            // 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> 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();
-
-                if (existingQuery != null) {
-
-                    // TODO: O(N) lookup
-                    BatchQueryRow existingRow = 
findRowForObjectId(existingQuery.getRows(), objectId);
-                    // todo: do we need to worry about flattenedArcKey.id2 ?
-
-                    if (existingRow != null) {
-                        List<DbAttribute> existingQueryDbAttributes = 
existingQuery.getDbAttributes();
-
-                        for(int i=0; i < existingQueryDbAttributes.size(); 
i++) {
-                            Object value = existingRow.getValue(i);
-                            if (value != null) {
-                                
snapshot.put(existingQueryDbAttributes.get(i).getName(), value);
-                            }
-                        }
-                    }
-                }
-
-                newQuery.add(snapshot, objectId);
-            }
-
-            // apply the ToMany snapshots as new BatchQueryRows
-            for(Map<String, Object> toManySnapshot : toManySnapshots) {
-                newQuery.add(toManySnapshot);
-            }
-
-            if (existingQuery != null) {
-                queries.remove(existingQuery);
-            }
-
-            queries.add(newQuery);
-        }
-    }
-
-    void appendDeletes(Collection<Query> queries) {
-        if (!flattenedDeleteQueries.isEmpty()) {
-            queries.addAll(flattenedDeleteQueries.values());
-        }
-    }
-
-    private InsertBatchQuery findInsertBatchQuery(Collection<Query> queries, 
DbEntity dbEntity) {
-        for(Query query : queries) {
-            if (query instanceof InsertBatchQuery) {
-                InsertBatchQuery insertBatchQuery = (InsertBatchQuery)query;
-                if (insertBatchQuery.getDbEntity().equals(dbEntity)) {
-                    return insertBatchQuery;
-                }
-            }
-        }
-        return null;
-    }
-
-    private BatchQueryRow findRowForObjectId(List<BatchQueryRow> rows, 
ObjectId objectId) {
-        for (BatchQueryRow row : rows) {
-            if (row.getObjectId().equals(objectId)) {
-                return row;
-            }
-        }
-        return null;
-    }
-}
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainFlushObserver.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainFlushObserver.java
deleted file mode 100644
index e99a546bf..000000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainFlushObserver.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import java.util.List;
-
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.DataRow;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.ResultIterator;
-import org.apache.cayenne.log.JdbcEventLogger;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.query.BatchQuery;
-import org.apache.cayenne.query.InsertBatchQuery;
-import org.apache.cayenne.query.Query;
-import org.apache.cayenne.util.Util;
-
-/**
- * Used as an observer for DataContext commit operations.
- * 
- * @since 1.2
- * @deprecated since 4.2 as part of deprecated {@link 
LegacyDataDomainFlushAction}
- */
-@Deprecated
-class DataDomainFlushObserver implements OperationObserver {
-
-    /**
-     * @since 3.1
-     */
-    private JdbcEventLogger logger;
-
-    DataDomainFlushObserver(JdbcEventLogger logger) {
-        this.logger = logger;
-    }
-
-    @Override
-    public void nextQueryException(Query query, Exception ex) {
-        throw new CayenneRuntimeException("Raising from query exception.", 
Util.unwindException(ex));
-    }
-
-    @Override
-    public void nextGlobalException(Exception ex) {
-        throw new CayenneRuntimeException("Raising from underlyingQueryEngine 
exception.", Util.unwindException(ex));
-    }
-
-    /**
-     * Processes generated keys.
-     * 
-     * @since 1.2
-     */
-    @Override
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    public void nextGeneratedRows(Query query, ResultIterator<?> keysIterator, 
List<ObjectId> idsToUpdate) {
-
-        // read and close the iterator before doing anything else
-        List<DataRow> keys;
-        try {
-            keys = (List<DataRow>) keysIterator.allRows();
-        } finally {
-            keysIterator.close();
-        }
-
-        if (!(query instanceof InsertBatchQuery)) {
-            throw new CayenneRuntimeException("Generated keys only supported 
for InsertBatchQuery, instead got %s", query);
-        }
-
-        if (keys.size() != idsToUpdate.size()) {
-            throw new CayenneRuntimeException("Mismatching number of generated 
PKs: expected %d, instead got %d", idsToUpdate.size(), keys.size());
-        }
-        
-        for (int i = 0; i < keys.size(); i++) {
-               DataRow key = keys.get(i);
-       
-               // empty key?
-               if (key.size() == 0) {
-                   throw new CayenneRuntimeException("Empty key generated.");
-               }
-       
-               ObjectId idToUpdate = idsToUpdate.get(i);
-               if (idToUpdate == null || !idToUpdate.isTemporary()) {
-                   // why would this happen?
-                   return;
-               }
-
-               BatchQuery batch = (BatchQuery) query;
-               for (DbAttribute attribute : 
batch.getDbEntity().getGeneratedAttributes()) {
-       
-                   // batch can have generated attributes that are not PKs, 
e.g.
-                   // columns with
-                   // DB DEFAULT values. Ignore those.
-                   if (attribute.isPrimaryKey()) {
-                       
-                       Object value = key.get(attribute.getName());
-                       
-                       // As of now (01/2005) many tested drivers don't 
provide decent
-                       // descriptors of
-                       // identity result sets, so a data row may contain 
garbage labels.
-                       if (value == null) {
-                               value = key.values().iterator().next();
-                       }
-                       
-                       // Log the generated PK
-                       logger.logGeneratedKey(attribute, value);
-       
-                       // I guess we should override any existing value,
-                       // as generated key is the latest thing that exists in 
the DB.
-                       
idToUpdate.getReplacementIdMap().put(attribute.getName(), value);
-                       break;
-                   }
-               }
-        }
-    }
-
-    public void setJdbcEventLogger(JdbcEventLogger logger) {
-        this.logger = logger;
-    }
-
-    public JdbcEventLogger getJdbcEventLogger() {
-        return this.logger;
-    }
-
-    @Override
-    public void nextBatchCount(Query query, int[] resultCount) {
-    }
-
-    @Override
-    public void nextCount(Query query, int resultCount) {
-    }
-
-    @Override
-    public void nextRows(Query query, List<?> dataRows) {
-    }
-
-    @Override
-    @SuppressWarnings("rawtypes")
-    public void nextRows(Query q, ResultIterator it) {
-        throw new UnsupportedOperationException(
-                "'nextDataRows(Query,ResultIterator)' is unsupported (and 
unexpected) on commit.");
-    }
-
-    @Override
-    public boolean isIteratedResult() {
-        return false;
-    }
-}
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainIndirectDiffBuilder.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainIndirectDiffBuilder.java
deleted file mode 100644
index ae1574e54..000000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainIndirectDiffBuilder.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import java.util.Collection;
-import java.util.HashSet;
-
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.graph.ArcId;
-import org.apache.cayenne.graph.GraphChangeHandler;
-import org.apache.cayenne.graph.GraphDiff;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.EntityResolver;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.map.ObjRelationship;
-
-/**
- * A processor of ObjectStore indirect changes, such as flattened relationships
- * and to-many relationships.
- * 
- * @since 1.2
- * @deprecated since 4.2 as part of deprecated {@link 
LegacyDataDomainFlushAction}
- */
-@Deprecated
-final class DataDomainIndirectDiffBuilder implements GraphChangeHandler {
-
-    private final LegacyDataDomainFlushAction parent;
-    private final EntityResolver resolver;
-    private final Collection<ObjectId> indirectModifications;
-    private final Collection<FlattenedArcKey> flattenedInserts;
-    private final Collection<FlattenedArcKey> flattenedDeletes;
-
-    DataDomainIndirectDiffBuilder(LegacyDataDomainFlushAction parent) {
-        this.parent = parent;
-        this.indirectModifications = parent.getResultIndirectlyModifiedIds();
-        this.resolver = parent.getDomain().getEntityResolver();
-        this.flattenedInserts = new HashSet<>();
-        this.flattenedDeletes = new HashSet<>();
-    }
-
-    void processIndirectChanges(GraphDiff allChanges) {
-        // extract flattened and indirect changes and remove duplicate 
changes...
-        allChanges.apply(this);
-
-        if (!flattenedInserts.isEmpty()) {
-            for (final FlattenedArcKey key : flattenedInserts) {
-                DbEntity entity = key.getJoinEntity();
-                parent.addFlattenedInsert(entity, key);
-            }
-        }
-
-        if (!flattenedDeletes.isEmpty()) {
-            for (final FlattenedArcKey key : flattenedDeletes) {
-                DbEntity entity = key.getJoinEntity();
-                parent.addFlattenedDelete(entity, key);
-            }
-        }
-    }
-
-    @Override
-    public void arcCreated(Object nodeId, Object targetNodeId, ArcId arcId) {
-        ObjEntity entity = resolver.getObjEntity(((ObjectId) 
nodeId).getEntityName());
-        ObjRelationship relationship = 
entity.getRelationship(arcId.toString());
-
-        if (relationship.isSourceIndependentFromTargetChange()) {
-
-            ObjectId nodeObjectId = (ObjectId) nodeId;
-            if (!nodeObjectId.isTemporary()) {
-                indirectModifications.add(nodeObjectId);
-            }
-
-            if (relationship.isFlattened()) {
-                if (relationship.isReadOnly()) {
-                    throw new CayenneRuntimeException("Cannot set the 
read-only flattened relationship '%s' in ObjEntity '%s'."
-                            , relationship.getName(), 
relationship.getSourceEntity().getName());
-                }
-
-                // build path without last segment
-                StringBuilder path = new StringBuilder();
-                for(int i=0; i<relationship.getDbRelationships().size() - 1; 
i++) {
-                    if(path.length() > 0) {
-                        path.append('.');
-                    }
-                    
path.append(relationship.getDbRelationships().get(i).getName());
-                }
-
-                
if(!parent.getContext().getObjectStore().hasFlattenedPath(nodeObjectId, 
path.toString())) {
-                    // Register this combination (so we can remove it later if 
an insert occurs before commit)
-                    FlattenedArcKey key = new FlattenedArcKey(nodeObjectId, 
(ObjectId) targetNodeId, relationship);
-
-                    // If this combination has already been deleted, simply 
undelete it.
-                    if (!flattenedDeletes.remove(key)) {
-                        flattenedInserts.add(key);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public void arcDeleted(Object nodeId, Object targetNodeId, ArcId arcId) {
-
-        ObjEntity entity = resolver.getObjEntity(((ObjectId) 
nodeId).getEntityName());
-        ObjRelationship relationship = 
entity.getRelationship(arcId.toString());
-
-        if (relationship.isSourceIndependentFromTargetChange()) {
-            // do not record temporary id mods...
-            ObjectId nodeObjectId = (ObjectId) nodeId;
-            if (!nodeObjectId.isTemporary()) {
-                indirectModifications.add(nodeObjectId);
-            }
-
-            if (relationship.isFlattened()) {
-                if (relationship.isReadOnly()) {
-                    throw new CayenneRuntimeException("Cannot unset the 
read-only flattened relationship %s"
-                            , relationship.getName());
-                }
-
-                // build path without last segment
-                StringBuilder path = new StringBuilder();
-                for(int i=0; i<relationship.getDbRelationships().size() - 1; 
i++) {
-                    if(path.length() > 0) {
-                        path.append('.');
-                    }
-                    
path.append(relationship.getDbRelationships().get(i).getName());
-                }
-
-                
if(!parent.getContext().getObjectStore().hasFlattenedPath(nodeObjectId, 
path.toString())) {
-                    // Register this combination (so we can remove it later if 
an insert occurs before commit)
-                    FlattenedArcKey key = new FlattenedArcKey(nodeObjectId, 
(ObjectId) targetNodeId, relationship);
-
-                    // If this combination has already been inserted, simply 
"uninsert" it also do not delete it twice
-                    if (!flattenedInserts.remove(key)) {
-                        flattenedDeletes.add(key);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public void nodeIdChanged(Object nodeId, Object newId) {
-        // noop
-    }
-
-    @Override
-    public void nodeCreated(Object nodeId) {
-        // noop
-    }
-
-    @Override
-    public void nodeRemoved(Object nodeId) {
-        // noop
-    }
-
-    @Override
-    public void nodePropertyChanged(Object nodeId, String property, Object 
oldValue, Object newValue) {
-        // noop
-    }
-}
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainInsertBucket.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainInsertBucket.java
deleted file mode 100644
index d3b59278f..000000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainInsertBucket.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.dba.PkGenerator;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbJoin;
-import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.map.EntitySorter;
-import org.apache.cayenne.map.ObjAttribute;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.query.InsertBatchQuery;
-import org.apache.cayenne.query.Query;
-
-/**
- * @since 1.2
- * @deprecated since 4.2 as part of deprecated {@link 
LegacyDataDomainFlushAction}
- */
-@Deprecated
-class DataDomainInsertBucket extends DataDomainSyncBucket {
-
-    List<FlattenedInsert> flattenedInserts;
-
-    DataDomainInsertBucket(LegacyDataDomainFlushAction parent) {
-        super(parent);
-    }
-
-    @Override
-    void appendQueriesInternal(Collection<Query> queries) {
-
-        DataDomainDBDiffBuilder diffBuilder = new DataDomainDBDiffBuilder();
-
-        EntitySorter sorter = parent.getDomain().getEntitySorter();
-        sorter.sortDbEntities(dbEntities, false);
-
-        for (DbEntity dbEntity : dbEntities) {
-
-            Collection<DbEntityClassDescriptor> descriptors = 
descriptorsByDbEntity.get(dbEntity);
-
-            InsertBatchQuery batch = new InsertBatchQuery(dbEntity, 27);
-            for (DbEntityClassDescriptor descriptor : descriptors) {
-
-                diffBuilder.reset(descriptor);
-
-                List<Persistent> objects = 
objectsByDescriptor.get(descriptor.getClassDescriptor());
-                if (objects.isEmpty()) {
-                    continue;
-                }
-
-                checkReadOnly(descriptor.getEntity());
-                createPermIds(descriptor, objects);
-                sorter.sortObjectsForEntity(descriptor.getEntity(), objects, 
false);
-
-                for (Persistent o : objects) {
-                    Map<String, Object> snapshot = 
diffBuilder.buildDBDiff(parent.objectDiff(o.getObjectId()));
-
-                    // we need to insert even if there is no changes to default
-                    // values so creating an empty changes map
-                    if (snapshot == null) {
-                        snapshot = new HashMap<>();
-                    }
-
-                    batch.add(snapshot, o.getObjectId());
-                    if(!descriptor.isMaster()) {
-                        trackFlattenedInsert(descriptor, o);
-                    }
-                }
-            }
-
-            queries.add(batch);
-        }
-    }
-
-    void createPermIds(DbEntityClassDescriptor descriptor, 
Collection<Persistent> objects) {
-
-        if (objects.isEmpty()) {
-            return;
-        }
-
-        ObjEntity objEntity = descriptor.getEntity();
-        DbEntity entity = descriptor.getDbEntity();
-
-        DataNode node = parent.getDomain().lookupDataNode(entity.getDataMap());
-        boolean supportsGeneratedKeys = 
node.getAdapter().supportsGeneratedKeys();
-
-        PkGenerator pkGenerator = node.getAdapter().getPkGenerator();
-
-        for (Persistent object : objects) {
-            ObjectId id = object.getObjectId();
-            if (id == null || !id.isTemporary()) {
-                continue;
-            }
-
-            // modify replacement id directly...
-            Map<String, Object> idMap = id.getReplacementIdMap();
-
-            boolean autoPkDone = false;
-
-            for (DbAttribute dbAttr : entity.getPrimaryKeys()) {
-                String dbAttrName = dbAttr.getName();
-
-                if (idMap.containsKey(dbAttrName)) {
-                    continue;
-                }
-
-                // handle meaningful PK
-                ObjAttribute objAttr = 
objEntity.getAttributeForDbAttribute(dbAttr);
-                if (objAttr != null) {
-
-                    Object value = 
descriptor.getClassDescriptor().getProperty(objAttr.getName())
-                            .readPropertyDirectly(object);
-
-                    if (value != null) {
-                        Class<?> javaClass = objAttr.getJavaClass();
-                        if (javaClass.isPrimitive() && value instanceof Number 
&& ((Number) value).intValue() == 0) {
-                            // primitive 0 has to be treated as NULL, or
-                            // otherwise we can't generate PK for POJO's
-                        } else {
-                            idMap.put(dbAttrName, value);
-                            continue;
-                        }
-                    }
-                }
-
-                // skip db-generated
-                if (supportsGeneratedKeys && dbAttr.isGenerated()) {
-                    continue;
-                }
-
-                // skip propagated
-                if (isPropagated(dbAttr)) {
-                    continue;
-                }
-
-                // only a single key can be generated from DB... if this is 
done
-                // already in this loop, we must bail out.
-                if (autoPkDone) {
-                    throw new CayenneRuntimeException("Primary Key 
autogeneration only works for a single attribute.");
-                }
-
-                // finally, use database generation mechanism
-                try {
-                    Object pkValue = pkGenerator.generatePk(node, dbAttr);
-                    idMap.put(dbAttrName, pkValue);
-                    autoPkDone = true;
-                } catch (Exception ex) {
-                    throw new CayenneRuntimeException("Error generating PK: 
%s", ex,  ex.getMessage());
-                }
-            }
-        }
-    }
-
-    // TODO, andrus 4/12/2006 - move to DbAttribute in 2.0+
-    boolean isPropagated(DbAttribute attribute) {
-
-        for (DbRelationship dbRel : attribute.getEntity().getRelationships()) {
-            if (!dbRel.isToMasterPK()) {
-                continue;
-            }
-
-            for (DbJoin join : dbRel.getJoins()) {
-                if (attribute.getName().equals(join.getSourceName())) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    void trackFlattenedInsert(DbEntityClassDescriptor descriptor, Persistent 
object) {
-        if(flattenedInserts == null) {
-            flattenedInserts = new LinkedList<>();
-        }
-
-        StringBuilder sb = new StringBuilder();
-        for(DbRelationship rel : descriptor.getPathFromMaster()) {
-            if(sb.length() > 0) {
-                sb.append('.');
-            }
-            sb.append(rel.getName());
-         }
-
-        flattenedInserts.add(new FlattenedInsert(sb.toString(), object));
-    }
-
-    @Override
-    void postprocess() {
-        super.postprocess();
-        if(flattenedInserts != null) {
-            for(FlattenedInsert insert : flattenedInserts) {
-                insert.register(parent.getContext().getObjectStore());
-            }
-        }
-    }
-
-    private static class FlattenedInsert {
-        private final String path;
-        private final Persistent object;
-
-        private FlattenedInsert(String path, Persistent object) {
-            this.path = path;
-            this.object = object;
-        }
-
-        private void register(ObjectStore objectStore) {
-            objectStore.markFlattenedPath(object.getObjectId(), path, 
ObjectId.of("tmp"));
-        }
-    }
-}
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainSyncBucket.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainSyncBucket.java
deleted file mode 100644
index 23dc5c295..000000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainSyncBucket.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.DataObject;
-import org.apache.cayenne.DataRow;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.graph.CompoundDiff;
-import org.apache.cayenne.graph.NodeIdChangeOperation;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.ObjAttribute;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.query.Query;
-import org.apache.cayenne.reflect.ArcProperty;
-import org.apache.cayenne.reflect.AttributeProperty;
-import org.apache.cayenne.reflect.ClassDescriptor;
-import org.apache.cayenne.reflect.PropertyException;
-import org.apache.cayenne.reflect.ToManyMapProperty;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Supplier;
-
-/**
- * A superclass of batch query wrappers.
- * 
- * @since 1.2
- * @deprecated since 4.2 as part of deprecated {@link 
LegacyDataDomainFlushAction}
- */
-@Deprecated
-abstract class DataDomainSyncBucket {
-
-    final Map<ClassDescriptor, List<Persistent>> objectsByDescriptor;
-    final LegacyDataDomainFlushAction parent;
-
-    List<DbEntity> dbEntities;
-    Map<DbEntity, Collection<DbEntityClassDescriptor>> descriptorsByDbEntity;
-
-    DataDomainSyncBucket(LegacyDataDomainFlushAction parent) {
-        this.objectsByDescriptor = new HashMap<>();
-        this.parent = parent;
-    }
-
-    boolean isEmpty() {
-        return objectsByDescriptor.isEmpty();
-    }
-
-    abstract void appendQueriesInternal(Collection<Query> queries);
-
-    /**
-     * Appends all queries originated in the bucket to provided collection.
-     */
-    void appendQueries(Collection<Query> queries) {
-
-        if (!objectsByDescriptor.isEmpty()) {
-            groupObjEntitiesBySpannedDbEntities();
-            appendQueriesInternal(queries);
-        }
-    }
-
-    void checkReadOnly(ObjEntity entity) throws CayenneRuntimeException {
-
-        if (entity == null) {
-            throw new NullPointerException("Entity must not be null.");
-        }
-
-        if (entity.isReadOnly()) {
-            throw new CayenneRuntimeException("Attempt to modify object(s) 
mapped to a read-only entity: '%s'. " +
-                    "Can't commit changes.", entity.getName());
-        }
-    }
-
-    private void groupObjEntitiesBySpannedDbEntities() {
-
-        dbEntities = new ArrayList<>(objectsByDescriptor.size());
-        descriptorsByDbEntity = new HashMap<>(objectsByDescriptor.size() * 2);
-
-        for (ClassDescriptor descriptor : objectsByDescriptor.keySet()) {
-            addSpannedDbEntities(descriptor);
-        }
-    }
-
-    void addSpannedDbEntities(ClassDescriptor descriptor) {
-        // root DbEntity
-        addDescriptor(descriptor, new DbEntityClassDescriptor(descriptor));
-
-        // secondary DbEntities...
-        // Note that this logic won't allow flattened attributes to span 
multiple databases...
-        for (ObjAttribute objAttribute : 
descriptor.getEntity().getAttributes()) {
-            if (objAttribute.isFlattened()) {
-                addDescriptor(descriptor, new 
DbEntityClassDescriptor(descriptor, objAttribute));
-            }
-        }
-    }
-
-    void addDescriptor(ClassDescriptor descriptor, DbEntityClassDescriptor 
dbEntityDescriptor) {
-        DbEntity dbEntity = dbEntityDescriptor.getDbEntity();
-        Collection<DbEntityClassDescriptor> descriptors = 
descriptorsByDbEntity.get(dbEntity);
-
-        if (descriptors == null) {
-            descriptors = new ArrayList<>(1);
-            dbEntities.add(dbEntity);
-            descriptorsByDbEntity.put(dbEntity, descriptors);
-        }
-
-        if (!containsClassDescriptor(descriptors, descriptor)) {
-            descriptors.add(dbEntityDescriptor);
-        }
-    }
-
-    private boolean containsClassDescriptor(
-            Collection<DbEntityClassDescriptor> descriptors,
-            ClassDescriptor classDescriptor) {
-        for (DbEntityClassDescriptor descriptor : descriptors) {
-            if (classDescriptor.equals(descriptor.getClassDescriptor())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    void addDirtyObject(Persistent object, ClassDescriptor descriptor) {
-        objectsByDescriptor.computeIfAbsent(descriptor, k -> new 
ArrayList<>()).add(object);
-    }
-
-    void postprocess() {
-
-        if (!objectsByDescriptor.isEmpty()) {
-
-            CompoundDiff result = parent.getResultDiff();
-            Map<ObjectId, DataRow> modifiedSnapshots = parent
-                    .getResultModifiedSnapshots();
-            Collection<ObjectId> deletedIds = parent.getResultDeletedIds();
-
-            for (Map.Entry<ClassDescriptor, List<Persistent>> entry : 
objectsByDescriptor.entrySet()) {
-
-                ClassDescriptor descriptor = entry.getKey();
-
-                for (Persistent object : entry.getValue()) {
-                    ObjectId id = object.getObjectId();
-
-                    ObjectId finalId;
-
-                    // record id change and update attributes for generated ids
-                    if (id.isReplacementIdAttached()) {
-
-                        Map<String, Object> replacement = 
id.getReplacementIdMap();
-                        for (AttributeProperty property : 
descriptor.getIdProperties()) {
-
-                            Object value = replacement.get(property
-                                    .getAttribute()
-                                    .getDbAttributeName());
-
-                            // TODO: andrus, 11/28/2006: this operation may be 
redundant
-                            // if the id wasn't generated. We may need to 
optimize it...
-                            if (value != null) {
-                                property.writePropertyDirectly(object, null, 
value);
-                            }
-                        }
-
-                        ObjectId replacementId = id.createReplacementId();
-
-                        result.add(new NodeIdChangeOperation(id, 
replacementId));
-
-                        // classify replaced permanent ids as "deleted", as
-                        // DataRowCache has no notion of replaced id...
-                        if (!id.isTemporary()) {
-                            deletedIds.add(id);
-                        }
-
-                        finalId = replacementId;
-                    } else if (id.isTemporary()) {
-                        throw new CayenneRuntimeException("Temporary ID hasn't 
been replaced on commit: %s", object);
-                    } else {
-                        finalId = id;
-                    }
-
-                    // do not take the snapshot until generated columns are 
processed (see code above)
-                    DataRow dataRow = 
parent.getContext().currentSnapshot(object);
-
-                    if (object instanceof DataObject) {
-                        DataObject dataObject = (DataObject) object;
-                        
dataRow.setReplacesVersion(dataObject.getSnapshotVersion());
-                        dataObject.setSnapshotVersion(dataRow.getVersion());
-                    }
-
-                    modifiedSnapshots.put(finalId, dataRow);
-
-                    // update Map reverse relationships
-                    for (ArcProperty arc : descriptor.getMapArcProperties()) {
-                        ToManyMapProperty reverseArc = (ToManyMapProperty) 
arc.getComplimentaryReverseArc();
-
-                        // must resolve faults... hopefully for to-one this 
will not cause extra fetches...
-                        Object source = arc.readProperty(object);
-                        if (source != null && !reverseArc.isFault(source)) {
-                            remapTarget(reverseArc, source, object);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private void remapTarget(
-            ToManyMapProperty property,
-            Object source,
-            Object target) throws PropertyException {
-
-        Map<Object, Object> map = (Map<Object, Object>) 
property.readProperty(source);
-        Object newKey = property.getMapKey(target);
-        Object currentValue = map.get(newKey);
-
-        if (currentValue == target) {
-            // nothing to do
-            return;
-        }
-        // else - do not check for conflicts here (i.e. another object mapped 
for the same
-        // key), as we have no control of the order in which this method is 
called, so
-        // another object may be remapped later by the caller
-
-        // must do a slow map scan to ensure the object is not mapped under a 
different key...
-        Iterator<Map.Entry<Object, Object>> it = map.entrySet().iterator();
-        while (it.hasNext()) {
-            Map.Entry<Object, Object> e = it.next();
-            if (e.getValue() == target) {
-                it.remove();
-                break;
-            }
-        }
-
-        map.put(newKey, target);
-    }
-
-    // a factory for extracting PKs generated on commit.
-    final static class PropagatedValueFactory implements Supplier {
-
-        ObjectId masterID;
-        String masterKey;
-
-        PropagatedValueFactory(ObjectId masterID, String masterKey) {
-            this.masterID = masterID;
-            this.masterKey = masterKey;
-        }
-
-        public Object get() {
-            Object value = masterID.getIdSnapshot().get(masterKey);
-            if (value == null) {
-                throw new CayenneRuntimeException("Can't extract a master key. 
"
-                        + "Missing key (%s), master ID (%s)", masterKey, 
masterID);
-            }
-
-            return value;
-        }
-    }
-}
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainUpdateBucket.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainUpdateBucket.java
deleted file mode 100644
index 55d426ca6..000000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomainUpdateBucket.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.map.Attribute;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.map.ObjRelationship;
-import org.apache.cayenne.query.Query;
-import org.apache.cayenne.query.UpdateBatchQuery;
-import org.apache.cayenne.reflect.ClassDescriptor;
-
-/**
- * @since 1.2
- * @deprecated since 4.2 as part of deprecated {@link 
LegacyDataDomainFlushAction}
- */
-@Deprecated
-class DataDomainUpdateBucket extends DataDomainSyncBucket {
-
-    DataDomainUpdateBucket(LegacyDataDomainFlushAction parent) {
-        super(parent);
-    }
-
-    @Override
-    void addSpannedDbEntities(ClassDescriptor descriptor) {
-        super.addSpannedDbEntities(descriptor);
-        // for update we need to add entities for flattened toOne relationships
-        for(ObjRelationship objRelationship : 
descriptor.getEntity().getRelationships()) {
-            if(objRelationship.isFlattened() && !objRelationship.isToMany()) {
-                addDescriptor(descriptor, new 
DbEntityClassDescriptor(descriptor, objRelationship));
-            }
-        }
-    }
-
-    @Override
-    void appendQueriesInternal(Collection<Query> queries) {
-
-        DataDomainDBDiffBuilder diffBuilder = new DataDomainDBDiffBuilder();
-        DataNodeSyncQualifierDescriptor qualifierBuilder = new 
DataNodeSyncQualifierDescriptor();
-
-        for (DbEntity dbEntity : dbEntities) {
-
-            Collection<DbEntityClassDescriptor> descriptors = 
descriptorsByDbEntity.get(dbEntity);
-            Map<Object, Query> batches = new LinkedHashMap<>();
-
-            for (DbEntityClassDescriptor descriptor : descriptors) {
-                ObjEntity entity = descriptor.getEntity();
-
-                diffBuilder.reset(descriptor);
-                qualifierBuilder.reset(descriptor);
-                boolean isRootDbEntity = entity.getDbEntity() == dbEntity;
-
-                for (Persistent o : 
objectsByDescriptor.get(descriptor.getClassDescriptor())) {
-                    ObjectDiff diff = parent.objectDiff(o.getObjectId());
-
-                    Map<String, Object> snapshot = 
diffBuilder.buildDBDiff(diff);
-
-                    // check whether MODIFIED object has real db-level 
modifications
-                    if (snapshot == null) {
-                        continue;
-                    }
-
-                    // after we filtered out "fake" modifications, check if an
-                    // attempt is made to modify a read only entity
-                    checkReadOnly(entity);
-
-                    Map<String, Object> qualifierSnapshot = 
qualifierBuilder.createQualifierSnapshot(diff);
-
-                    // organize batches by the updated columns + nulls in 
qualifier
-                    Set<String> snapshotSet = snapshot.keySet();
-                    Set<String> nullQualifierNames = new HashSet<>();
-                    for (Map.Entry<String, Object> entry : 
qualifierSnapshot.entrySet()) {
-                        if (entry.getValue() == null) {
-                            nullQualifierNames.add(entry.getKey());
-                        }
-                    }
-
-                    List<Set<String>> batchKey = Arrays.asList(snapshotSet, 
nullQualifierNames);
-
-                    UpdateBatchQuery batch = (UpdateBatchQuery) 
batches.get(batchKey);
-                    if (batch == null) {
-                        batch = new UpdateBatchQuery(
-                                dbEntity,
-                                qualifierBuilder.getAttributes(),
-                                updatedAttributes(dbEntity, snapshot),
-                                nullQualifierNames,
-                                10);
-
-                        
batch.setUsingOptimisticLocking(qualifierBuilder.isUsingOptimisticLocking());
-                        batches.put(batchKey, batch);
-                    }
-
-                    batch.add(qualifierSnapshot, snapshot, o.getObjectId());
-
-                    // update replacement id with meaningful PK changes
-                    if (isRootDbEntity) {
-                        Map<String, Object> replacementId = o
-                                .getObjectId()
-                                .getReplacementIdMap();
-
-                        for (DbAttribute pk : dbEntity.getPrimaryKeys()) {
-                            String name = pk.getName();
-                            if (snapshot.containsKey(name)
-                                    && !replacementId.containsKey(name)) {
-                                replacementId.put(name, snapshot.get(name));
-                            }
-                        }
-                    }
-                }
-            }
-
-            queries.addAll(batches.values());
-        }
-    }
-
-    /**
-     * Creates a list of DbAttributes that are updated in a snapshot
-     */
-    private List<DbAttribute> updatedAttributes(DbEntity entity, Map<String, 
Object> updatedSnapshot) {
-        List<DbAttribute> attributes = new ArrayList<>(updatedSnapshot.size());
-        Map<String, ? extends Attribute> entityAttributes = 
entity.getAttributeMap();
-
-        for (String name : updatedSnapshot.keySet()) {
-            attributes.add((DbAttribute)entityAttributes.get(name));
-        }
-
-        return attributes;
-    }
-}
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataNodeSyncQualifierDescriptor.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/DataNodeSyncQualifierDescriptor.java
deleted file mode 100644
index 49c225b03..000000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DataNodeSyncQualifierDescriptor.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbJoin;
-import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.map.ObjAttribute;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.map.ObjRelationship;
-
-/**
- * Builds update qualifier snapshots, including optimistic locking.
- * 
- * @since 1.2
- * @deprecated since 4.2 as part of deprecated {@link 
LegacyDataDomainFlushAction}
- */
-@Deprecated
-class DataNodeSyncQualifierDescriptor {
-
-       private List<DbAttribute> attributes;
-       private List<Function<ObjectDiff, Object>> valueTransformers;
-       private boolean usingOptimisticLocking;
-
-       public boolean isUsingOptimisticLocking() {
-               return usingOptimisticLocking;
-       }
-
-       List<DbAttribute> getAttributes() {
-               return attributes;
-       }
-
-       Map<String, Object> createQualifierSnapshot(ObjectDiff diff) {
-               int len = attributes.size();
-
-               Map<String, Object> map = new HashMap<>(len * 2);
-               for (int i = 0; i < len; i++) {
-                       DbAttribute attribute = attributes.get(i);
-                       if (!map.containsKey(attribute.getName())) {
-                               Object value = 
valueTransformers.get(i).apply(diff);
-                               map.put(attribute.getName(), value);
-                       }
-               }
-
-               return map;
-       }
-
-       void reset(DbEntityClassDescriptor descriptor) {
-
-               attributes = new ArrayList<>(3);
-               valueTransformers = new ArrayList<>(3);
-               usingOptimisticLocking = descriptor.getEntity().getLockType() 
== ObjEntity.LOCK_TYPE_OPTIMISTIC;
-
-               // master PK columns
-               if (descriptor.isMaster()) {
-                       for (final DbAttribute attribute : 
descriptor.getDbEntity().getPrimaryKeys()) {
-                               attributes.add(attribute);
-                               valueTransformers.add(input -> {
-                    ObjectId id = (ObjectId) input.getNodeId();
-                    return id.getIdSnapshot().get(attribute.getName());
-                });
-                       }
-               } else {
-
-                       // TODO: andrus 12/23/2007 - only one step relationship 
is supported...
-                       if (descriptor.getPathFromMaster().size() != 1) {
-                               throw new CayenneRuntimeException(
-                                       "Only single step dependent 
relationships are currently supported. Actual path length: %d"
-                        , descriptor.getPathFromMaster().size());
-                       }
-
-                       DbRelationship masterDependentDbRel = 
descriptor.getPathFromMaster().get(0);
-
-                       if (masterDependentDbRel != null) {
-                               for (final DbJoin dbAttrPair : 
masterDependentDbRel.getJoins()) {
-                                       DbAttribute dbAttribute = 
dbAttrPair.getTarget();
-                                       if (!attributes.contains(dbAttribute)) {
-
-                                               attributes.add(dbAttribute);
-                                               valueTransformers.add(input -> {
-                            ObjectId id = (ObjectId) input.getNodeId();
-                            return 
id.getIdSnapshot().get(dbAttrPair.getTargetName());
-                        });
-                    }
-                }
-            }
-        }
-
-               if (descriptor.isMaster() && usingOptimisticLocking) {
-
-                       for (final ObjAttribute attribute : 
descriptor.getEntity().getAttributes()) {
-
-                               if (attribute.isUsedForLocking() && 
!attribute.isFlattened()) {
-                                       // only care about first step in a 
flattened attribute
-                                       DbAttribute dbAttribute = (DbAttribute) 
attribute.getDbPathIterator().next();
-
-                                       // only use qualifier if dbEntities 
match
-                                       if 
(dbAttribute.getEntity().equals(descriptor.getDbEntity()) && 
!attributes.contains(dbAttribute)) {
-                                               attributes.add(dbAttribute);
-                                               valueTransformers.add(input -> 
input.getSnapshotValue(attribute.getName()));
-                                       }
-                               }
-                       }
-
-                       for (final ObjRelationship relationship : 
descriptor.getEntity().getRelationships()) {
-
-                               if (relationship.isUsedForLocking()) {
-                                       // only care about the first 
DbRelationship
-                                       DbRelationship dbRelationship = 
relationship.getDbRelationships().get(0);
-
-                                       for (final DbJoin dbAttrPair : 
dbRelationship.getJoins()) {
-                                               DbAttribute dbAttribute = 
dbAttrPair.getSource();
-
-                                               // relationship transformers 
override attribute transformers for meaningful FK's...
-                                               // why meaningful FKs can go 
out of sync is another story (CAY-595)
-                                               int index = 
attributes.indexOf(dbAttribute);
-                                               if (index >= 0 && 
!dbAttribute.isForeignKey()) {
-                                                       continue;
-                                               }
-
-                                               Function<ObjectDiff, Object> 
transformer = input -> {
-                            ObjectId targetId = 
input.getArcSnapshotValue(relationship.getName());
-                            return targetId != null ? 
targetId.getIdSnapshot().get(dbAttrPair.getTargetName()) : null;
-                        };
-
-                                               if (index < 0) {
-                                                       
attributes.add(dbAttribute);
-                                                       
valueTransformers.add(transformer);
-                                               } else {
-                                                       
valueTransformers.set(index, transformer);
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-}
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DbArcId.java 
b/cayenne-server/src/main/java/org/apache/cayenne/access/DbArcId.java
deleted file mode 100644
index a18626f8d..000000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/DbArcId.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-package org.apache.cayenne.access;
-
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.util.EqualsBuilder;
-import org.apache.cayenne.util.HashCodeBuilder;
-
-/**
- * An id similar to ObjectId that identifies a DbEntity snapshot for implicit
- * DbEntities of flattened attributes or relationships. Provides 'equals' and
- * 'hashCode' implementations adequate for use as a map key.
- * 
- * @since 4.0
- * @deprecated since 4.2 as part of deprecated {@link 
LegacyDataDomainFlushAction}
- */
-@Deprecated
-final class DbArcId {
-
-    private int hashCode;
-
-    private ObjectId sourceId;
-    private DbRelationship incomingArc;
-
-    private DbEntity entity;
-
-    DbArcId(ObjectId sourceId, DbRelationship incomingArc) {
-        this.sourceId = sourceId;
-        this.incomingArc = incomingArc;
-    }
-
-    DbEntity getEntity() {
-        if (entity == null) {
-            entity = (DbEntity) incomingArc.getTargetEntity();
-        }
-
-        return entity;
-    }
-
-    ObjectId getSourceId() {
-        return sourceId;
-    }
-
-    DbRelationship getIncominArc() {
-        return incomingArc;
-    }
-
-    @Override
-    public int hashCode() {
-
-        if (this.hashCode == 0) {
-            HashCodeBuilder builder = new HashCodeBuilder(3, 5);
-            builder.append(sourceId);
-            builder.append(incomingArc.getName());
-            this.hashCode = builder.toHashCode();
-        }
-
-        return hashCode;
-    }
-
-    @Override
-    public boolean equals(Object object) {
-
-        if (this == object) {
-            return true;
-        }
-
-        if (!(object instanceof DbArcId)) {
-            return false;
-        }
-
-        DbArcId id = (DbArcId) object;
-
-        return new EqualsBuilder().append(sourceId, id.sourceId)
-                .append(incomingArc.getName(), id.incomingArc.getName())
-                .isEquals();
-    }
-}
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DbEntityClassDescriptor.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/DbEntityClassDescriptor.java
deleted file mode 100644
index 496a968bf..000000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/DbEntityClassDescriptor.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-package org.apache.cayenne.access;
-
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.map.ObjAttribute;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.map.ObjRelationship;
-import org.apache.cayenne.reflect.ClassDescriptor;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * A descriptor of a primary or secondary DbEntity for a given persistent 
class during
- * commit.
- * 
- * @since 3.0
- * @deprecated since 4.2 as part of deprecated {@link 
LegacyDataDomainFlushAction}
- */
-@Deprecated
-class DbEntityClassDescriptor {
-
-    private ClassDescriptor classDescriptor;
-    private List<DbRelationship> pathFromMaster;
-    private DbEntity dbEntity;
-
-    DbEntityClassDescriptor(ClassDescriptor classDescriptor) {
-        this.classDescriptor = classDescriptor;
-        this.dbEntity = classDescriptor.getEntity().getDbEntity();
-    }
-
-    DbEntityClassDescriptor(ClassDescriptor classDescriptor, ObjAttribute 
masterAttribute) {
-        this.classDescriptor = classDescriptor;
-
-        Iterator<?> it = masterAttribute.getDbPathIterator();
-
-        if (masterAttribute.isFlattened()) {
-
-            while (it.hasNext()) {
-                Object object = it.next();
-                if (object instanceof DbRelationship) {
-
-                    if (pathFromMaster == null) {
-                        pathFromMaster = new ArrayList<>(1);
-                    }
-
-                    pathFromMaster.add((DbRelationship) object);
-                }
-                else if (object instanceof DbAttribute) {
-                    this.dbEntity = ((DbAttribute) object).getEntity();
-                }
-            }
-        }
-
-        if (dbEntity == null) {
-            dbEntity = classDescriptor.getEntity().getDbEntity();
-        }
-    }
-
-    DbEntityClassDescriptor(ClassDescriptor classDescriptor, ObjRelationship 
masterRelationship) {
-        if(masterRelationship.getDbRelationships().size() > 2) {
-            throw new CayenneRuntimeException("Only two step flattened 
relationships are supported, " + masterRelationship.getDbRelationshipPath());
-        }
-        this.classDescriptor = classDescriptor;
-        DbRelationship pathRelationship = 
masterRelationship.getDbRelationships().get(0);
-        pathFromMaster = new ArrayList<>(1);
-        pathFromMaster.add(pathRelationship);
-        dbEntity = pathRelationship.getTargetEntity();
-    }
-
-    boolean isMaster() {
-        return pathFromMaster == null;
-    }
-
-    ClassDescriptor getClassDescriptor() {
-        return classDescriptor;
-    }
-
-    List<DbRelationship> getPathFromMaster() {
-        return pathFromMaster;
-    }
-
-    DbEntity getDbEntity() {
-        return dbEntity;
-    }
-
-    ObjEntity getEntity() {
-        return classDescriptor.getEntity();
-    }
-}
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/FlattenedArcKey.java 
b/cayenne-server/src/main/java/org/apache/cayenne/access/FlattenedArcKey.java
deleted file mode 100644
index 64e410c1d..000000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/FlattenedArcKey.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.DataRow;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.access.DataDomainSyncBucket.PropagatedValueFactory;
-import org.apache.cayenne.access.util.DefaultOperationObserver;
-import org.apache.cayenne.dba.DbAdapter;
-import org.apache.cayenne.dba.QuotingStrategy;
-import org.apache.cayenne.dba.TypesMapping;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbJoin;
-import org.apache.cayenne.map.DbRelationship;
-import org.apache.cayenne.map.ObjRelationship;
-import org.apache.cayenne.query.Query;
-import org.apache.cayenne.query.SQLTemplate;
-import org.apache.cayenne.util.HashCodeBuilder;
-import org.apache.cayenne.util.Util;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A holder of flattened relationship modification data.
- * 
- * @since 1.2
- * @deprecated since 4.2 as part of deprecated {@link 
LegacyDataDomainFlushAction}
- */
-@Deprecated
-final class FlattenedArcKey {
-
-       ObjRelationship relationship;
-
-       DbArcId id1;
-       DbArcId id2;
-
-       FlattenedArcKey(ObjectId sourceId, ObjectId destinationId, 
ObjRelationship relationship) {
-
-               this.relationship = relationship;
-
-               List<DbRelationship> dbRelationships = 
relationship.getDbRelationships();
-               if (dbRelationships.size() != 2) {
-                       throw new CayenneRuntimeException(
-                                       "Only single-step flattened 
relationships are supported in this operation, whereas the relationship '%s' 
has %s",
-                                       relationship, dbRelationships.size());
-               }
-
-               DbRelationship r1 = dbRelationships.get(0);
-               DbRelationship r2 = 
dbRelationships.get(1).getReverseRelationship();
-
-               if (r2 == null) {
-                       throw new IllegalStateException("No reverse 
relationship for DbRelationship " + dbRelationships.get(1));
-               }
-
-               id1 = new DbArcId(sourceId, r1);
-               id2 = new DbArcId(destinationId, r2);
-       }
-
-       /**
-        * Returns a join DbEntity for the single-step flattened relationship.
-        */
-       DbEntity getJoinEntity() {
-               return id1.getEntity();
-       }
-
-       /**
-        * Returns a snapshot for join record for the single-step flattened
-        * relationship, generating value for the primary key column if it is 
not
-        * propagated via the relationships.
-        */
-       Map<String, Object> buildJoinSnapshotForInsert(DataNode node) {
-               Map<String, Object> snapshot = lazyJoinSnapshot();
-
-               boolean autoPkDone = false;
-               DbEntity joinEntity = getJoinEntity();
-
-               for (DbAttribute dbAttr : joinEntity.getPrimaryKeys()) {
-                       String dbAttrName = dbAttr.getName();
-                       if (snapshot.containsKey(dbAttrName)) {
-                               continue;
-                       }
-
-                       DbAdapter adapter = node.getAdapter();
-
-                       // skip db-generated... looks like we don't care about 
the actual PK
-                       // value here, so no need to retrieve db-generated pk 
back to Java.
-                       if (adapter.supportsGeneratedKeys() && 
dbAttr.isGenerated()) {
-                               continue;
-                       }
-
-                       if (autoPkDone) {
-                               throw new CayenneRuntimeException("Primary Key 
autogeneration only works for a single attribute.");
-                       }
-
-                       // finally, use database generation mechanism
-                       try {
-                               Object pkValue = 
adapter.getPkGenerator().generatePk(node, dbAttr);
-                               snapshot.put(dbAttrName, pkValue);
-                               autoPkDone = true;
-                       } catch (Exception ex) {
-                               throw new CayenneRuntimeException("Error 
generating PK: %s", ex,  ex.getMessage());
-                       }
-               }
-
-               return snapshot;
-       }
-
-       /**
-        * Returns pk snapshots for join records for the single-step flattened
-        * relationship. Multiple joins between the same pair of objects are
-        * theoretically possible, so the return value is a list.
-        */
-       List buildJoinSnapshotsForDelete(DataNode node) {
-               Map<String, Object> snapshot = eagerJoinSnapshot();
-
-               DbEntity joinEntity = getJoinEntity();
-
-               boolean fetchKey = false;
-               for (DbAttribute dbAttr : joinEntity.getPrimaryKeys()) {
-                       String dbAttrName = dbAttr.getName();
-                       if (!snapshot.containsKey(dbAttrName)) {
-                               fetchKey = true;
-                               break;
-                       }
-               }
-
-               if (!fetchKey) {
-                       return Collections.singletonList(snapshot);
-               }
-
-               // ok, the key is not included in snapshot, must do the fetch...
-               // TODO: this should be optimized in the future, but now
-               // DeleteBatchQuery
-               // expects a PK snapshot, so we must provide it.
-
-               QuotingStrategy quoter = node.getAdapter().getQuotingStrategy();
-
-               StringBuilder sql = new StringBuilder("SELECT ");
-               Collection<DbAttribute> pk = joinEntity.getPrimaryKeys();
-               final List<DbAttribute> pkList = pk instanceof List ? 
(List<DbAttribute>) pk : new ArrayList<>(pk);
-
-               for (int i = 0; i < pkList.size(); i++) {
-
-                       if (i > 0) {
-                               sql.append(", ");
-                       }
-
-                       DbAttribute attribute = pkList.get(i);
-
-                       sql.append("#result('");
-                       sql.append(quoter.quotedName(attribute));
-
-                       // since the name of the column can potentially be 
quoted and
-                       // use reserved keywords as name, let's specify 
generated column
-                       // name parameters to ensure the query doesn't explode
-                       sql.append("' 
'").append(TypesMapping.getJavaBySqlType(attribute));
-                       sql.append("' '").append("pk").append(i);
-                       sql.append("')");
-               }
-
-               sql.append(" FROM 
").append(quoter.quotedFullyQualifiedName(joinEntity)).append(" WHERE ");
-               int i = snapshot.size();
-               for (Object key : snapshot.keySet()) {
-                       sql.append(quoter.quotedIdentifier(joinEntity, 
String.valueOf(key))).append(" #bindEqual($").append(key)
-                                       .append(")");
-
-                       if (--i > 0) {
-                               sql.append(" AND ");
-                       }
-               }
-
-               SQLTemplate query = new SQLTemplate(joinEntity.getDataMap(), 
sql.toString(), true);
-               query.setParams(snapshot);
-
-               final List[] result = new List[1];
-
-               node.performQueries(Collections.singleton((Query) query), new 
DefaultOperationObserver() {
-
-                       @Override
-                       public void nextRows(Query query, List<?> dataRows) {
-
-                               if (!dataRows.isEmpty()) {
-                                       // decode results...
-
-                                       List<DataRow> fixedRows = new 
ArrayList<>(dataRows.size());
-                                       for (Object o : dataRows) {
-                                               DataRow row = (DataRow) o;
-
-                                               DataRow fixedRow = new 
DataRow(2);
-
-                                               for (int i = 0; i < 
pkList.size(); i++) {
-                                                       DbAttribute attribute = 
pkList.get(i);
-                                                       
fixedRow.put(attribute.getName(), row.get("pk" + i));
-                                               }
-
-                                               fixedRows.add(fixedRow);
-                                       }
-
-                                       dataRows = fixedRows;
-                               }
-
-                               result[0] = dataRows;
-                       }
-
-                       @Override
-                       public void nextQueryException(Query query, Exception 
ex) {
-                               throw new CayenneRuntimeException("Raising from 
query exception.", Util.unwindException(ex));
-                       }
-
-                       @Override
-                       public void nextGlobalException(Exception ex) {
-                               throw new CayenneRuntimeException("Raising from 
underlyingQueryEngine exception.", Util
-                                               .unwindException(ex));
-                       }
-               });
-
-               return result[0];
-       }
-
-       @Override
-       public int hashCode() {
-               // order ids in array for hashcode consistency purposes. The 
actual
-               // order direction is not important, as long as it
-               // is consistent across invocations
-
-               int compare = 
id1.getSourceId().getEntityName().compareTo(id2.getSourceId().getEntityName());
-
-               if (compare == 0) {
-                       compare = 
id1.getIncominArc().getName().compareTo(id2.getIncominArc().getName());
-
-                       if (compare == 0) {
-                               // since ordering is mostly important for 
detecting equivalent
-                               // FlattenedArc keys coming from 2 opposite 
directions, the name
-                               // of ObjRelationship can be a good criteria
-
-                               ObjRelationship or2 = 
relationship.getReverseRelationship();
-                               compare = or2 != null ? 
relationship.getName().compareTo(or2.getName()) : 1;
-
-                               // TODO: if(compare == 0) ??
-                       }
-               }
-
-               DbArcId[] ordered;
-               if (compare < 0) {
-                       ordered = new DbArcId[] { id1, id2 };
-               } else {
-                       ordered = new DbArcId[] { id2, id1 };
-               }
-
-               return new HashCodeBuilder().append(ordered).toHashCode();
-       }
-
-       /**
-        * Defines equal based on whether the relationship is bidirectional.
-        */
-       @Override
-       public boolean equals(Object object) {
-
-               if (this == object) {
-                       return true;
-               }
-
-               if (!(object instanceof FlattenedArcKey)) {
-                       return false;
-               }
-
-               FlattenedArcKey key = (FlattenedArcKey) object;
-
-               // ignore id order in comparison
-               if (id1.equals(key.id1)) {
-                       return id2.equals(key.id2);
-               } else if (id1.equals(key.id2)) {
-                       return id2.equals(key.id1);
-               }
-
-               return false;
-       }
-
-       private Map<String, Object> eagerJoinSnapshot() {
-
-               List<DbRelationship> relList = 
relationship.getDbRelationships();
-               if (relList.size() != 2) {
-                       throw new CayenneRuntimeException(
-                                       "Only single-step flattened 
relationships are supported in this operation: %s", relationship);
-               }
-
-               DbRelationship firstDbRel = relList.get(0);
-               DbRelationship secondDbRel = relList.get(1);
-
-               // here ordering of ids is determined by 'relationship', so use 
id1, id2
-               // instead of orderedIds
-               Map<String, ?> sourceId = id1.getSourceId().getIdSnapshot();
-               Map<String, ?> destinationId = 
id2.getSourceId().getIdSnapshot();
-
-               Map<String, Object> snapshot = new HashMap<>(sourceId.size() + 
destinationId.size(), 1);
-               for (DbJoin join : firstDbRel.getJoins()) {
-                       snapshot.put(join.getTargetName(), 
sourceId.get(join.getSourceName()));
-               }
-
-               for (DbJoin join : secondDbRel.getJoins()) {
-                       snapshot.put(join.getSourceName(), 
destinationId.get(join.getTargetName()));
-               }
-
-               return snapshot;
-       }
-
-       private Map<String, Object> lazyJoinSnapshot() {
-
-               List<DbRelationship> relList = 
relationship.getDbRelationships();
-               if (relList.size() != 2) {
-                       throw new CayenneRuntimeException(
-                                       "Only single-step flattened 
relationships are supported in this operation: %s", relationship);
-               }
-
-               DbRelationship firstDbRel = relList.get(0);
-               DbRelationship secondDbRel = relList.get(1);
-
-               List<DbJoin> fromSourceJoins = firstDbRel.getJoins();
-               List<DbJoin> toTargetJoins = secondDbRel.getJoins();
-
-               Map<String, Object> snapshot = new 
HashMap<>(fromSourceJoins.size() + toTargetJoins.size(), 1);
-
-               // here ordering of ids is determined by 'relationship', so use 
id1, id2
-               // instead of orderedIds
-
-               for (DbJoin join : fromSourceJoins) {
-                       Object value = new 
PropagatedValueFactory(id1.getSourceId(), join.getSourceName());
-                       snapshot.put(join.getTargetName(), value);
-               }
-
-               for (DbJoin join : toTargetJoins) {
-                       Object value = new 
PropagatedValueFactory(id2.getSourceId(), join.getTargetName());
-                       snapshot.put(join.getSourceName(), value);
-               }
-
-               return snapshot;
-       }
-}
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/LegacyDataDomainFlushAction.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/LegacyDataDomainFlushAction.java
deleted file mode 100644
index a461f1393..000000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/LegacyDataDomainFlushAction.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.DataRow;
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.PersistenceState;
-import org.apache.cayenne.Persistent;
-import org.apache.cayenne.access.flush.DefaultDataDomainFlushAction;
-import org.apache.cayenne.graph.CompoundDiff;
-import org.apache.cayenne.graph.GraphDiff;
-import org.apache.cayenne.log.JdbcEventLogger;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.query.BatchQuery;
-import org.apache.cayenne.query.Query;
-import org.apache.cayenne.reflect.ClassDescriptor;
-import org.apache.cayenne.tx.BaseTransaction;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A stateful commit handler used by DataContext to perform commit operation.
- * DataContextCommitAction resolves primary key dependencies, referential 
integrity
- * dependencies (including multi-reflexive entities), generates primary keys, 
creates
- * batches for massive data modifications, assigns operations to data nodes.
- *
- * @since 1.2
- * @deprecated this implementation is deprecated since 4.2, {@link 
DefaultDataDomainFlushAction} is used
- */
-@Deprecated
-public class LegacyDataDomainFlushAction implements 
org.apache.cayenne.access.flush.DataDomainFlushAction {
-
-    private final DataDomain domain;
-    private DataContext context;
-    private Map<Object, ObjectDiff> changesByObjectId;
-
-    private CompoundDiff resultDiff;
-    private Collection<ObjectId> resultDeletedIds;
-    private Map<ObjectId, DataRow> resultModifiedSnapshots;
-    private Collection<ObjectId> resultIndirectlyModifiedIds;
-
-    private DataDomainInsertBucket insertBucket;
-    private DataDomainUpdateBucket updateBucket;
-    private DataDomainDeleteBucket deleteBucket;
-    private DataDomainFlattenedBucket flattenedBucket;
-
-    private List<Query> queries;
-
-    private JdbcEventLogger logger;
-
-    public LegacyDataDomainFlushAction(DataDomain domain) {
-        this.domain = domain;
-    }
-
-    DataDomain getDomain() {
-        return domain;
-    }
-
-    DataContext getContext() {
-        return context;
-    }
-
-    Collection<ObjectId> getResultDeletedIds() {
-        return resultDeletedIds;
-    }
-
-    CompoundDiff getResultDiff() {
-        return resultDiff;
-    }
-
-    Collection<ObjectId> getResultIndirectlyModifiedIds() {
-        return resultIndirectlyModifiedIds;
-    }
-
-    Map<ObjectId, DataRow> getResultModifiedSnapshots() {
-        return resultModifiedSnapshots;
-    }
-
-    public void setJdbcEventLogger(JdbcEventLogger logger) {
-        this.logger = logger;
-    }
-
-    public JdbcEventLogger getJdbcEventLogger() {
-        return this.logger;
-    }
-
-    ObjectDiff objectDiff(Object objectId) {
-        return changesByObjectId.get(objectId);
-    }
-
-    void addFlattenedInsert(DbEntity flattenedEntity, FlattenedArcKey 
flattenedInsertInfo) {
-        flattenedBucket.addInsertArcKey(flattenedEntity, flattenedInsertInfo);
-    }
-
-    void addFlattenedDelete(DbEntity flattenedEntity, FlattenedArcKey 
flattenedDeleteInfo) {
-        flattenedBucket.addFlattenedDelete(flattenedEntity, 
flattenedDeleteInfo);
-    }
-
-    public GraphDiff flush(DataContext context, GraphDiff changes) {
-
-        if (changes == null) {
-            return new CompoundDiff();
-        }
-
-        // TODO: Andrus, 3/13/2006 - support categorizing an arbitrary diff
-        if (!(changes instanceof ObjectStoreGraphDiff)) {
-            throw new IllegalArgumentException("Expected 
'ObjectStoreGraphDiff', got: " + changes.getClass().getName());
-        }
-
-        this.context = context;
-
-        // ObjectStoreGraphDiff contains changes already categorized by 
objectId...
-        this.changesByObjectId = ((ObjectStoreGraphDiff) 
changes).getChangesByObjectId();
-        this.insertBucket = new DataDomainInsertBucket(this);
-        this.deleteBucket = new DataDomainDeleteBucket(this);
-        this.updateBucket = new DataDomainUpdateBucket(this);
-        this.flattenedBucket = new DataDomainFlattenedBucket(this);
-
-        this.queries = new ArrayList<>();
-        this.resultIndirectlyModifiedIds = new HashSet<>();
-
-        preprocess(context, changes);
-
-        if (queries.isEmpty()) {
-            return new CompoundDiff();
-        }
-
-        this.resultDiff = new CompoundDiff();
-        this.resultDeletedIds = new ArrayList<>();
-        this.resultModifiedSnapshots = new HashMap<>();
-
-        runQueries();
-
-        postprocess(context);
-        return resultDiff;
-    }
-
-    private void preprocess(DataContext context, GraphDiff changes) {
-
-        // categorize dirty objects by state
-
-        ObjectStore objectStore = context.getObjectStore();
-
-        for (Object o : changesByObjectId.keySet()) {
-            ObjectId id = (ObjectId) o;
-            Persistent object = (Persistent) objectStore.getNode(id);
-            ClassDescriptor descriptor = 
context.getEntityResolver().getClassDescriptor(id.getEntityName());
-
-            switch (object.getPersistenceState()) {
-                case PersistenceState.NEW:
-                    insertBucket.addDirtyObject(object, descriptor);
-                    break;
-                case PersistenceState.MODIFIED:
-                    updateBucket.addDirtyObject(object, descriptor);
-                    break;
-                case PersistenceState.DELETED:
-                    deleteBucket.addDirtyObject(object, descriptor);
-                    break;
-            }
-        }
-
-        new 
DataDomainIndirectDiffBuilder(this).processIndirectChanges(changes);
-
-        insertBucket.appendQueries(queries);
-
-        // TODO: the following line depends on the "queries" collection filled 
by insertBucket.. Moreover it may
-        // potentially remove values from the passed collection. Replace with 
something with fewer unobvious
-        // side-effects...
-        flattenedBucket.appendInserts(queries);
-
-        updateBucket.appendQueries(queries);
-        flattenedBucket.appendDeletes(queries);
-        deleteBucket.appendQueries(queries);
-    }
-
-    private void runQueries() {
-        DataDomainFlushObserver observer = new DataDomainFlushObserver(
-                domain.getJdbcEventLogger());
-
-        // split query list by spanned nodes and run each single node range 
individually.
-        // Since connections are reused per node within an open transaction, 
there should
-        // not be much overhead in accessing the same node multiple times (may 
happen due
-        // to imperfect sorting)
-
-        try {
-
-            DataNode lastNode = null;
-            DbEntity lastEntity = null;
-            int rangeStart = 0;
-            int len = queries.size();
-
-            for (int i = 0; i < len; i++) {
-
-                BatchQuery query = (BatchQuery) queries.get(i);
-                if (query.getDbEntity() != lastEntity) {
-                    lastEntity = query.getDbEntity();
-
-                    DataNode node = 
domain.lookupDataNode(lastEntity.getDataMap());
-                    if (node != lastNode) {
-
-                        if (i - rangeStart > 0) {
-                            
lastNode.performQueries(queries.subList(rangeStart, i), observer);
-                        }
-
-                        rangeStart = i;
-                        lastNode = node;
-                    }
-                }
-            }
-
-            // process last segment of the query list...
-            lastNode.performQueries(queries.subList(rangeStart, len), 
observer);
-        } catch (Throwable th) {
-            BaseTransaction.getThreadTransaction().setRollbackOnly();
-            throw new CayenneRuntimeException("Transaction was rolledback.", 
th);
-        }
-    }
-
-    /*
-     * Sends notification of changes to the DataRowStore, returns GraphDiff 
with replaced
-     * ObjectIds.
-     */
-    private void postprocess(DataContext context) {
-
-        deleteBucket.postprocess();
-        updateBucket.postprocess();
-        insertBucket.postprocess();
-
-        // notify cache...
-        if (!resultDeletedIds.isEmpty()
-                || !resultModifiedSnapshots.isEmpty()
-                || !resultIndirectlyModifiedIds.isEmpty()) {
-
-            context
-                    .getObjectStore()
-                    .getDataRowCache()
-                    .processSnapshotChanges(
-                            context.getObjectStore(),
-                            resultModifiedSnapshots,
-                            resultDeletedIds,
-                            Collections.<ObjectId>emptyList(),
-                            resultIndirectlyModifiedIds);
-        }
-
-        context.getObjectStore().postprocessAfterCommit(resultDiff);
-    }
-}
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/LegacyDataDomainFlushActionFactory.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/LegacyDataDomainFlushActionFactory.java
deleted file mode 100644
index 5ac9b2c05..000000000
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/LegacyDataDomainFlushActionFactory.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import org.apache.cayenne.access.flush.DataDomainFlushAction;
-import org.apache.cayenne.access.flush.DataDomainFlushActionFactory;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.log.JdbcEventLogger;
-
-/**
- * Factory for {@link LegacyDataDomainFlushAction}.
- * A fallback factory to use deprecated implementation if absolutely needed.
- *
- * @since 4.2
- */
-@Deprecated
-public class LegacyDataDomainFlushActionFactory implements 
DataDomainFlushActionFactory {
-
-    @Inject
-    private JdbcEventLogger jdbcEventLogger;
-
-    @Override
-    public DataDomainFlushAction createFlushAction(DataDomain dataDomain) {
-        LegacyDataDomainFlushAction action = new 
LegacyDataDomainFlushAction(dataDomain);
-        action.setJdbcEventLogger(jdbcEventLogger);
-        return action;
-    }
-}

Reply via email to