Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
target/
.idea/
.vscode/
.settings/
*.iml
.flattened-pom.xml
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-relational-parent</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.0.0-1980-jspecify-SNAPSHOT</version>
<packaging>pom</packaging>

<name>Spring Data Relational Parent</name>
Expand Down
2 changes: 1 addition & 1 deletion spring-data-jdbc-distribution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-relational-parent</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.0.0-1980-jspecify-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
4 changes: 2 additions & 2 deletions spring-data-jdbc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion>

<artifactId>spring-data-jdbc</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.0.0-1980-jspecify-SNAPSHOT</version>

<name>Spring Data JDBC</name>
<description>Spring Data module for JDBC repositories.</description>
Expand All @@ -15,7 +15,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-relational-parent</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.0.0-1980-jspecify-SNAPSHOT</version>
</parent>

<properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.util.Arrays;

import org.jspecify.annotations.Nullable;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
Expand All @@ -30,7 +31,6 @@
import org.springframework.data.relational.core.mapping.event.BeforeConvertCallback;
import org.springframework.data.relational.core.mapping.event.BeforeDeleteCallback;
import org.springframework.data.relational.core.mapping.event.BeforeSaveCallback;
import org.springframework.lang.Nullable;

/**
* {@link RuntimeHintsRegistrar} for JDBC.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,12 @@
*/
package org.springframework.data.jdbc.core;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.jspecify.annotations.Nullable;
import org.springframework.dao.IncorrectUpdateSemanticsDataAccessException;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
Expand All @@ -48,7 +40,6 @@
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.data.relational.core.sql.LockMode;
import org.springframework.data.util.Pair;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

/**
Expand Down Expand Up @@ -82,16 +73,16 @@ class JdbcAggregateChangeExecutionContext {

<T> void executeInsertRoot(DbAction.InsertRoot<T> insert) {

Object id = accessStrategy.insert(insert.getEntity(), insert.getEntityType(), Identifier.empty(),
insert.getIdValueSource());
Object id = accessStrategy.insert(insert.entity(), insert.getEntityType(), Identifier.empty(),
insert.idValueSource());
add(new DbActionExecutionResult(insert, id));
}

<T> void executeBatchInsertRoot(DbAction.BatchInsertRoot<T> batchInsertRoot) {

List<DbAction.InsertRoot<T>> inserts = batchInsertRoot.getActions();
List<InsertSubject<T>> insertSubjects = inserts.stream()
.map(insert -> InsertSubject.describedBy(insert.getEntity(), Identifier.empty())).collect(Collectors.toList());
.map(insert -> InsertSubject.describedBy(insert.entity(), Identifier.empty())).collect(Collectors.toList());

Object[] ids = accessStrategy.insert(insertSubjects, batchInsertRoot.getEntityType(),
batchInsertRoot.getBatchValue());
Expand All @@ -104,16 +95,16 @@ <T> void executeBatchInsertRoot(DbAction.BatchInsertRoot<T> batchInsertRoot) {
<T> void executeInsert(DbAction.Insert<T> insert) {

Identifier parentKeys = getParentKeys(insert, converter);
Object id = accessStrategy.insert(insert.getEntity(), insert.getEntityType(), parentKeys,
insert.getIdValueSource());
Object id = accessStrategy.insert(insert.entity(), insert.getEntityType(), parentKeys,
insert.idValueSource());
add(new DbActionExecutionResult(insert, id));
}

<T> void executeBatchInsert(DbAction.BatchInsert<T> batchInsert) {

List<DbAction.Insert<T>> inserts = batchInsert.getActions();
List<InsertSubject<T>> insertSubjects = inserts.stream()
.map(insert -> InsertSubject.describedBy(insert.getEntity(), getParentKeys(insert, converter)))
.map(insert -> InsertSubject.describedBy(insert.entity(), getParentKeys(insert, converter)))
.collect(Collectors.toList());

Object[] ids = accessStrategy.insert(insertSubjects, batchInsert.getEntityType(), batchInsert.getBatchValue());
Expand All @@ -135,27 +126,27 @@ <T> void executeUpdateRoot(DbAction.UpdateRoot<T> update) {

<T> void executeDeleteRoot(DbAction.DeleteRoot<T> delete) {

if (delete.getPreviousVersion() != null) {
accessStrategy.deleteWithVersion(delete.getId(), delete.getEntityType(), delete.getPreviousVersion());
if (delete.previousVersion() != null) {
accessStrategy.deleteWithVersion(delete.id(), delete.getEntityType(), delete.previousVersion());
} else {
accessStrategy.delete(delete.getId(), delete.getEntityType());
accessStrategy.delete(delete.id(), delete.getEntityType());
}
}

<T> void executeBatchDeleteRoot(DbAction.BatchDeleteRoot<T> batchDelete) {

List<Object> rootIds = batchDelete.getActions().stream().map(DbAction.DeleteRoot::getId).toList();
List<Object> rootIds = batchDelete.getActions().stream().map(DbAction.DeleteRoot::id).toList();
accessStrategy.delete(rootIds, batchDelete.getEntityType());
}

<T> void executeDelete(DbAction.Delete<T> delete) {

accessStrategy.delete(delete.getRootId(), delete.getPropertyPath());
accessStrategy.delete(delete.rootId(), delete.propertyPath());
}

<T> void executeBatchDelete(DbAction.BatchDelete<T> batchDelete) {

List<Object> rootIds = batchDelete.getActions().stream().map(DbAction.Delete::getRootId).toList();
List<Object> rootIds = batchDelete.getActions().stream().map(DbAction.Delete::rootId).toList();
accessStrategy.delete(rootIds, batchDelete.getBatchValue());
}

Expand All @@ -166,7 +157,7 @@ <T> void executeDeleteAllRoot(DbAction.DeleteAllRoot<T> deleteAllRoot) {

<T> void executeDeleteAll(DbAction.DeleteAll<T> delete) {

accessStrategy.deleteAll(delete.getPropertyPath());
accessStrategy.deleteAll(delete.propertyPath());
}

<T> void executeAcquireLock(DbAction.AcquireLockRoot<T> acquireLock) {
Expand All @@ -185,11 +176,11 @@ private Identifier getParentKeys(DbAction.WithDependingOn<?> action, JdbcConvert

Object id = getParentId(action);

AggregatePath aggregatePath = context.getAggregatePath(action.getPropertyPath());
AggregatePath aggregatePath = context.getAggregatePath(action.propertyPath());
JdbcIdentifierBuilder identifier = JdbcIdentifierBuilder //
.forBackReferences(converter, aggregatePath, getIdMapper(id, aggregatePath, converter));

for (Map.Entry<PersistentPropertyPath<RelationalPersistentProperty>, Object> qualifier : action.getQualifiers()
for (Map.Entry<PersistentPropertyPath<RelationalPersistentProperty>, Object> qualifier : action.qualifiers()
.entrySet()) {
identifier = identifier.withQualifier(context.getAggregatePath(qualifier.getKey()), qualifier.getValue());
}
Expand All @@ -200,21 +191,21 @@ private Identifier getParentKeys(DbAction.WithDependingOn<?> action, JdbcConvert
static Function<AggregatePath, Object> getIdMapper(Object idValue, AggregatePath path, JdbcConverter converter) {

RelationalPersistentProperty idProperty = path.getIdDefiningParentPath().getRequiredIdProperty();
RelationalPersistentEntity<?> entity = converter.getMappingContext()
.getPersistentEntity(idProperty);
RelationalPersistentEntity<?> entity = converter.getMappingContext().getPersistentEntity(idProperty);

if (entity == null) {
return aggregatePath -> idValue;
}

PersistentPropertyPathAccessor<Object> propertyPathAccessor = entity.getPropertyPathAccessor(idValue);
return aggregatePath -> propertyPathAccessor.getProperty(aggregatePath.getSubPathBasedOn(idProperty.getActualType()).getRequiredPersistentPropertyPath());
return aggregatePath -> propertyPathAccessor
.getProperty(aggregatePath.getSubPathBasedOn(idProperty.getActualType()).getRequiredPersistentPropertyPath());
}

private Object getParentId(DbAction.WithDependingOn<?> action) {

DbAction.WithEntity<?> idOwningAction = getIdOwningAction(action,
context.getAggregatePath(action.getPropertyPath()).getIdDefiningParentPath());
context.getAggregatePath(action.propertyPath()).getIdDefiningParentPath());

return getPotentialGeneratedIdFrom(idOwningAction);
}
Expand All @@ -229,16 +220,16 @@ private DbAction.WithEntity<?> getIdOwningAction(DbAction.WithEntity<?> action,
return action;
}

if (idPath.equals(context.getAggregatePath(withDependingOn.getPropertyPath()))) {
if (idPath.equals(context.getAggregatePath(withDependingOn.propertyPath()))) {
return action;
}

return getIdOwningAction(withDependingOn.getDependingOn(), idPath);
return getIdOwningAction(withDependingOn.dependingOn(), idPath);
}

private Object getPotentialGeneratedIdFrom(DbAction.WithEntity<?> idOwningAction) {

if (IdValueSource.GENERATED.equals(idOwningAction.getIdValueSource())) {
if (IdValueSource.GENERATED.equals(idOwningAction.idValueSource())) {

DbActionExecutionResult dbActionExecutionResult = results.get(idOwningAction);
Object generatedId = Optional.ofNullable(dbActionExecutionResult) //
Expand All @@ -256,7 +247,7 @@ private Object getPotentialGeneratedIdFrom(DbAction.WithEntity<?> idOwningAction
private Object getIdFrom(DbAction.WithEntity<?> idOwningAction) {

RelationalPersistentEntity<?> persistentEntity = getRequiredPersistentEntity(idOwningAction.getEntityType());
Object identifier = persistentEntity.getIdentifierAccessor(idOwningAction.getEntity()).getIdentifier();
Object identifier = persistentEntity.getIdentifierAccessor(idOwningAction.entity()).getIdentifier();

Assert.state(identifier != null, () -> "Couldn't obtain a required id value for " + persistentEntity);

Expand Down Expand Up @@ -290,12 +281,12 @@ <T> List<T> populateIdsIfNecessary() {
Pair<?, ?> qualifier = insert.getQualifier();
Object qualifierValue = qualifier == null ? null : qualifier.getSecond();

if (newEntity != action.getEntity()) {
if (newEntity != action.entity()) {

cascadingValues.stage(insert.getDependingOn(), insert.getPropertyPath(), qualifierValue, newEntity);
} else if (insert.getPropertyPath().getLeafProperty().isCollectionLike()) {
cascadingValues.stage(insert.dependingOn(), insert.propertyPath(), qualifierValue, newEntity);
} else if (insert.propertyPath().getLeafProperty().isCollectionLike()) {

cascadingValues.gather(insert.getDependingOn(), insert.getPropertyPath(), qualifierValue, newEntity);
cascadingValues.gather(insert.dependingOn(), insert.propertyPath(), qualifierValue, newEntity);
}
}
}
Expand All @@ -315,14 +306,14 @@ <T> List<T> populateIdsIfNecessary() {
private <S> Object setIdAndCascadingProperties(DbAction.WithEntity<S> action, @Nullable Object generatedId,
StagedValues cascadingValues) {

S originalEntity = action.getEntity();
S originalEntity = action.entity();

RelationalPersistentEntity<S> persistentEntity = (RelationalPersistentEntity<S>) context
.getRequiredPersistentEntity(action.getEntityType());
PersistentPropertyPathAccessor<S> propertyAccessor = converter.getPropertyAccessor(persistentEntity,
originalEntity);

if (IdValueSource.GENERATED.equals(action.getIdValueSource())) {
if (IdValueSource.GENERATED.equals(action.idValueSource())) {
propertyAccessor.setProperty(persistentEntity.getRequiredIdProperty(), generatedId);
}

Expand All @@ -337,7 +328,7 @@ private <S> Object setIdAndCascadingProperties(DbAction.WithEntity<S> action, @N
private PersistentPropertyPath<?> getRelativePath(DbAction<?> action, PersistentPropertyPath<?> pathToValue) {

if (action instanceof DbAction.Insert insert) {
return pathToValue.getExtensionForBaseOf(insert.getPropertyPath());
return pathToValue.getExtensionForBaseOf(insert.propertyPath());
}

if (action instanceof DbAction.InsertRoot) {
Expand All @@ -358,10 +349,10 @@ private <T> RelationalPersistentEntity<T> getRequiredPersistentEntity(Class<T> t

private <T> void updateWithoutVersion(DbAction.UpdateRoot<T> update) {

if (!accessStrategy.update(update.getEntity(), update.getEntityType())) {
if (!accessStrategy.update(update.entity(), update.getEntityType())) {

throw new IncorrectUpdateSemanticsDataAccessException(
String.format(UPDATE_FAILED, update.getEntity(), getIdFrom(update)));
String.format(UPDATE_FAILED, update.entity(), getIdFrom(update)));
}
}

Expand All @@ -370,9 +361,9 @@ private <T> void updateWithVersion(DbAction.UpdateRoot<T> update) {
Number previousVersion = update.getPreviousVersion();
Assert.notNull(previousVersion, "The root aggregate cannot be updated because the version property is null");

if (!accessStrategy.updateWithVersion(update.getEntity(), update.getEntityType(), previousVersion)) {
if (!accessStrategy.updateWithVersion(update.entity(), update.getEntityType(), previousVersion)) {

throw new OptimisticLockingFailureException(String.format(UPDATE_FAILED_OPTIMISTIC_LOCKING, update.getEntity()));
throw new OptimisticLockingFailureException(String.format(UPDATE_FAILED_OPTIMISTIC_LOCKING, update.entity()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Optional;
import java.util.stream.Stream;

import org.jspecify.annotations.Nullable;
import org.springframework.dao.IncorrectUpdateSemanticsDataAccessException;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
Expand All @@ -27,7 +28,6 @@
import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.relational.core.query.Query;
import org.springframework.lang.Nullable;

/**
* Specifies operations one can perform on a database, based on an <em>Domain Type</em>.
Expand Down Expand Up @@ -171,8 +171,8 @@ public interface JdbcAggregateOperations {
<T> List<T> findAllById(Iterable<?> ids, Class<T> domainType);

/**
* Loads all entities that match one of the ids passed as an argument to a {@link Stream}.
* It is not guaranteed that the number of ids passed in matches the number of entities returned.
* Loads all entities that match one of the ids passed as an argument to a {@link Stream}. It is not guaranteed that
* the number of ids passed in matches the number of entities returned.
*
* @param ids the Ids of the entities to load. Must not be {@code null}.
* @param domainType the type of entities to load. Must not be {@code null}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import org.jspecify.annotations.Nullable;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
Expand Down Expand Up @@ -55,7 +56,6 @@
import org.springframework.data.relational.core.mapping.event.*;
import org.springframework.data.relational.core.query.Query;
import org.springframework.data.support.PageableExecutionUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

Expand Down Expand Up @@ -305,7 +305,7 @@ public <T> boolean existsById(Object id, Class<T> domainType) {
}

@Override
public <T> T findById(Object id, Class<T> domainType) {
public <T> @Nullable T findById(Object id, Class<T> domainType) {

Assert.notNull(id, "Id must not be null");
Assert.notNull(domainType, "Domain type must not be null");
Expand Down
Loading