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-2023 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 static java.util.Arrays.*;
import java.util.ArrayList;
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.relational.core.mapping.PersistentPropertyPathExtension;
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
* @author Chirag Tailor
*/
class WritingContext {
private final RelationalMappingContext context;
private final T root;
private final Class entityType;
private final List> paths;
private final Map> previousActions = new HashMap<>();
private final Map, List> nodesCache = new HashMap<>();
private final IdValueSource rootIdValueSource;
@Nullable private final Number previousVersion;
private final RootAggregateChange aggregateChange;
WritingContext(RelationalMappingContext context, T root, RootAggregateChange aggregateChange) {
this.context = context;
this.root = root;
this.entityType = aggregateChange.getEntityType();
this.previousVersion = aggregateChange.getPreviousVersion();
this.aggregateChange = aggregateChange;
this.rootIdValueSource = IdValueSource.forInstance(root,
context.getRequiredPersistentEntity(aggregateChange.getEntityType()));
this.paths = context.findPersistentPropertyPaths(entityType, (p) -> p.isEntity() && !p.isEmbedded()) //
.filter(PersistentPropertyPathExtension::isWritable).toList();
}
/**
* Leaves out the isNew check as defined in #DATAJDBC-282
*
* @see DAJDBC-282
*/
void insert() {
setRootAction(new DbAction.InsertRoot<>(root, rootIdValueSource));
insertReferenced().forEach(aggregateChange::addAction);
}
/**
* Leaves out the isNew check as defined in #DATAJDBC-282 Possible Deadlocks in Execution Order in #DATAJDBC-488
*
* @see DAJDBC-282
* @see DAJDBC-488
*/
void update() {
setRootAction(new DbAction.UpdateRoot<>(root, previousVersion));
deleteReferenced().forEach(aggregateChange::addAction);
insertReferenced().forEach(aggregateChange::addAction);
}
void save() {
if (isNew(root)) {
setRootAction(new DbAction.InsertRoot<>(root, rootIdValueSource));
insertReferenced().forEach(aggregateChange::addAction);
} else {
setRootAction(new DbAction.UpdateRoot<>(root, previousVersion));
deleteReferenced().forEach(aggregateChange::addAction);
insertReferenced().forEach(aggregateChange::addAction);
}
}
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) {
RelationalPersistentEntity persistentEntity = context
.getRequiredPersistentEntity(path.getLeafProperty());
List> inserts = new ArrayList<>();
from(path).forEach(node -> {
DbAction.WithEntity parentAction = getAction(node.getParent());
Map, Object> qualifiers = new HashMap<>();
Object instance;
if (node.getPath().getLeafProperty().isQualified()) {
Pair