org.springframework.data.relational.core.conversion.WritingContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spring-data-relational Show documentation
Show all versions of spring-data-relational Show documentation
Spring Data Relational support
/*
* Copyright 2019-2022 the original author or authors.
*
* Licensed 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.springframework.data.relational.core.conversion;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.mapping.PersistentPropertyPaths;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.data.util.Pair;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Holds context information for the current save operation.
*
* @author Jens Schauder
* @author Bastian Wilhelm
* @author Mark Paluch
* @author Myeonghyeon Lee
*/
class WritingContext {
private final RelationalMappingContext context;
private final Object root;
private final Object entity;
private final Class entityType;
private final PersistentPropertyPaths paths;
private final Map> previousActions = new HashMap<>();
private final Map, List> nodesCache = new HashMap<>();
WritingContext(RelationalMappingContext context, Object root, MutableAggregateChange aggregateChange) {
this.context = context;
this.root = root;
this.entity = aggregateChange.getEntity();
this.entityType = aggregateChange.getEntityType();
this.paths = context.findPersistentPropertyPaths(entityType, (p) -> p.isEntity() && !p.isEmbedded());
}
/**
* Leaves out the isNew check as defined in #DATAJDBC-282
*
* @return List of {@link DbAction}s
* @see DAJDBC-282
*/
List> insert() {
List> actions = new ArrayList<>();
actions.add(setRootAction(new DbAction.InsertRoot<>(entity)));
actions.addAll(insertReferenced());
return actions;
}
/**
* Leaves out the isNew check as defined in #DATAJDBC-282 Possible Deadlocks in Execution Order in #DATAJDBC-488
*
* @return List of {@link DbAction}s
* @see DAJDBC-282
* @see DAJDBC-488
*/
List> update() {
List> actions = new ArrayList<>();
actions.add(setRootAction(new DbAction.UpdateRoot<>(entity)));
actions.addAll(deleteReferenced());
actions.addAll(insertReferenced());
return actions;
}
List> save() {
List> actions = new ArrayList<>();
if (isNew(root)) {
actions.add(setRootAction(new DbAction.InsertRoot<>(entity)));
actions.addAll(insertReferenced());
} else {
actions.add(setRootAction(new DbAction.UpdateRoot<>(entity)));
actions.addAll(deleteReferenced());
actions.addAll(insertReferenced());
}
return actions;
}
private boolean isNew(Object o) {
return context.getRequiredPersistentEntity(o.getClass()).isNew(o);
}
//// Operations on all paths
private List> insertReferenced() {
List> actions = new ArrayList<>();
paths.forEach(path -> actions.addAll(insertAll(path)));
return actions;
}
@SuppressWarnings("unchecked")
private List> insertAll(PersistentPropertyPath path) {
List> actions = new ArrayList<>();
from(path).forEach(node -> {
DbAction.WithEntity parentAction = getAction(node.getParent());
DbAction.Insert