Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c15e3b5

Browse files
schaudermp911de
authored andcommitted
Migrate to JSpecify annotations for nullability constraints.
Replace nullability annotations with their JSpecify equivalents. Enable checking this annotations at compile time using Errorprone and NullAway. Closes #1980 Original pull request: #2126
1 parent ca45cd5 commit c15e3b5

File tree

237 files changed

+2202
-2197
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

237 files changed

+2202
-2197
lines changed

‎.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
target/
22
.idea/
3+
.vscode/
34
.settings/
45
*.iml
56
.flattened-pom.xml

‎spring-data-jdbc/src/main/java/org/springframework/data/jdbc/aot/JdbcRuntimeHints.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.Arrays;
1919

20+
import org.jspecify.annotations.Nullable;
2021
import org.springframework.aot.hint.MemberCategory;
2122
import org.springframework.aot.hint.RuntimeHints;
2223
import org.springframework.aot.hint.RuntimeHintsRegistrar;
@@ -30,7 +31,6 @@
3031
import org.springframework.data.relational.core.mapping.event.BeforeConvertCallback;
3132
import org.springframework.data.relational.core.mapping.event.BeforeDeleteCallback;
3233
import org.springframework.data.relational.core.mapping.event.BeforeSaveCallback;
33-
import org.springframework.lang.Nullable;
3434

3535
/**
3636
* {@link RuntimeHintsRegistrar} for JDBC.

‎spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutionContext.java

Lines changed: 36 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,12 @@
1515
*/
1616
package org.springframework.data.jdbc.core;
1717

18-
import java.util.ArrayList;
19-
import java.util.Arrays;
20-
import java.util.Collections;
21-
import java.util.HashMap;
22-
import java.util.HashSet;
23-
import java.util.LinkedHashMap;
24-
import java.util.List;
25-
import java.util.Map;
26-
import java.util.Optional;
27-
import java.util.Set;
18+
import java.util.*;
2819
import java.util.function.BiConsumer;
2920
import java.util.function.Function;
3021
import java.util.stream.Collectors;
3122

23+
import org.jspecify.annotations.Nullable;
3224
import org.springframework.dao.IncorrectUpdateSemanticsDataAccessException;
3325
import org.springframework.dao.OptimisticLockingFailureException;
3426
import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
@@ -48,7 +40,6 @@
4840
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
4941
import org.springframework.data.relational.core.sql.LockMode;
5042
import org.springframework.data.util.Pair;
51-
import org.springframework.lang.Nullable;
5243
import org.springframework.util.Assert;
5344

5445
/**
@@ -82,16 +73,16 @@ class JdbcAggregateChangeExecutionContext {
8273

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

85-
Object id = accessStrategy.insert(insert.getEntity(), insert.getEntityType(), Identifier.empty(),
86-
insert.getIdValueSource());
76+
Object id = accessStrategy.insert(insert.entity(), insert.getEntityType(), Identifier.empty(),
77+
insert.idValueSource());
8778
add(new DbActionExecutionResult(insert, id));
8879
}
8980

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

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

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

10697
Identifier parentKeys = getParentKeys(insert, converter);
107-
Object id = accessStrategy.insert(insert.getEntity(), insert.getEntityType(), parentKeys,
108-
insert.getIdValueSource());
98+
Object id = accessStrategy.insert(insert.entity(), insert.getEntityType(), parentKeys,
99+
insert.idValueSource());
109100
add(new DbActionExecutionResult(insert, id));
110101
}
111102

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

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

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

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

138-
if (delete.getPreviousVersion() != null) {
139-
accessStrategy.deleteWithVersion(delete.getId(), delete.getEntityType(), delete.getPreviousVersion());
129+
if (delete.previousVersion() != null) {
130+
accessStrategy.deleteWithVersion(delete.id(), delete.getEntityType(), delete.previousVersion());
140131
} else {
141-
accessStrategy.delete(delete.getId(), delete.getEntityType());
132+
accessStrategy.delete(delete.id(), delete.getEntityType());
142133
}
143134
}
144135

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

147-
List<Object> rootIds = batchDelete.getActions().stream().map(DbAction.DeleteRoot::getId).toList();
138+
List<Object> rootIds = batchDelete.getActions().stream().map(DbAction.DeleteRoot::id).toList();
148139
accessStrategy.delete(rootIds, batchDelete.getEntityType());
149140
}
150141

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

153-
accessStrategy.delete(delete.getRootId(), delete.getPropertyPath());
144+
accessStrategy.delete(delete.rootId(), delete.propertyPath());
154145
}
155146

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

158-
List<Object> rootIds = batchDelete.getActions().stream().map(DbAction.Delete::getRootId).toList();
149+
List<Object> rootIds = batchDelete.getActions().stream().map(DbAction.Delete::rootId).toList();
159150
accessStrategy.delete(rootIds, batchDelete.getBatchValue());
160151
}
161152

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

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

169-
accessStrategy.deleteAll(delete.getPropertyPath());
160+
accessStrategy.deleteAll(delete.propertyPath());
170161
}
171162

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

186177
Object id = getParentId(action);
187178

188-
AggregatePath aggregatePath = context.getAggregatePath(action.getPropertyPath());
179+
AggregatePath aggregatePath = context.getAggregatePath(action.propertyPath());
189180
JdbcIdentifierBuilder identifier = JdbcIdentifierBuilder //
190181
.forBackReferences(converter, aggregatePath, getIdMapper(id, aggregatePath, converter));
191182

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

202193
RelationalPersistentProperty idProperty = path.getIdDefiningParentPath().getRequiredIdProperty();
203-
RelationalPersistentEntity<?> entity = converter.getMappingContext()
204-
.getPersistentEntity(idProperty);
194+
RelationalPersistentEntity<?> entity = converter.getMappingContext().getPersistentEntity(idProperty);
205195

206196
if (entity == null) {
207197
return aggregatePath -> idValue;
208198
}
209199

210200
PersistentPropertyPathAccessor<Object> propertyPathAccessor = entity.getPropertyPathAccessor(idValue);
211-
return aggregatePath -> propertyPathAccessor.getProperty(aggregatePath.getSubPathBasedOn(idProperty.getActualType()).getRequiredPersistentPropertyPath());
201+
return aggregatePath -> propertyPathAccessor
202+
.getProperty(aggregatePath.getSubPathBasedOn(idProperty.getActualType()).getRequiredPersistentPropertyPath());
212203
}
213204

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

216207
DbAction.WithEntity<?> idOwningAction = getIdOwningAction(action,
217-
context.getAggregatePath(action.getPropertyPath()).getIdDefiningParentPath());
208+
context.getAggregatePath(action.propertyPath()).getIdDefiningParentPath());
218209

219210
return getPotentialGeneratedIdFrom(idOwningAction);
220211
}
@@ -229,16 +220,16 @@ private DbAction.WithEntity<?> getIdOwningAction(DbAction.WithEntity<?> action,
229220
return action;
230221
}
231222

232-
if (idPath.equals(context.getAggregatePath(withDependingOn.getPropertyPath()))) {
223+
if (idPath.equals(context.getAggregatePath(withDependingOn.propertyPath()))) {
233224
return action;
234225
}
235226

236-
return getIdOwningAction(withDependingOn.getDependingOn(), idPath);
227+
return getIdOwningAction(withDependingOn.dependingOn(), idPath);
237228
}
238229

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

241-
if (IdValueSource.GENERATED.equals(idOwningAction.getIdValueSource())) {
232+
if (IdValueSource.GENERATED.equals(idOwningAction.idValueSource())) {
242233

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

258249
RelationalPersistentEntity<?> persistentEntity = getRequiredPersistentEntity(idOwningAction.getEntityType());
259-
Object identifier = persistentEntity.getIdentifierAccessor(idOwningAction.getEntity()).getIdentifier();
250+
Object identifier = persistentEntity.getIdentifierAccessor(idOwningAction.entity()).getIdentifier();
260251

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

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

293-
if (newEntity != action.getEntity()) {
284+
if (newEntity != action.entity()) {
294285

295-
cascadingValues.stage(insert.getDependingOn(), insert.getPropertyPath(), qualifierValue, newEntity);
296-
} else if (insert.getPropertyPath().getLeafProperty().isCollectionLike()) {
286+
cascadingValues.stage(insert.dependingOn(), insert.propertyPath(), qualifierValue, newEntity);
287+
} else if (insert.propertyPath().getLeafProperty().isCollectionLike()) {
297288

298-
cascadingValues.gather(insert.getDependingOn(), insert.getPropertyPath(), qualifierValue, newEntity);
289+
cascadingValues.gather(insert.dependingOn(), insert.propertyPath(), qualifierValue, newEntity);
299290
}
300291
}
301292
}
@@ -315,14 +306,14 @@ <T> List<T> populateIdsIfNecessary() {
315306
private <S> Object setIdAndCascadingProperties(DbAction.WithEntity<S> action, @Nullable Object generatedId,
316307
StagedValues cascadingValues) {
317308

318-
S originalEntity = action.getEntity();
309+
S originalEntity = action.entity();
319310

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

325-
if (IdValueSource.GENERATED.equals(action.getIdValueSource())) {
316+
if (IdValueSource.GENERATED.equals(action.idValueSource())) {
326317
propertyAccessor.setProperty(persistentEntity.getRequiredIdProperty(), generatedId);
327318
}
328319

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

339330
if (action instanceof DbAction.Insert insert) {
340-
return pathToValue.getExtensionForBaseOf(insert.getPropertyPath());
331+
return pathToValue.getExtensionForBaseOf(insert.propertyPath());
341332
}
342333

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

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

361-
if (!accessStrategy.update(update.getEntity(), update.getEntityType())) {
352+
if (!accessStrategy.update(update.entity(), update.getEntityType())) {
362353

363354
throw new IncorrectUpdateSemanticsDataAccessException(
364-
String.format(UPDATE_FAILED, update.getEntity(), getIdFrom(update)));
355+
String.format(UPDATE_FAILED, update.entity(), getIdFrom(update)));
365356
}
366357
}
367358

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

373-
if (!accessStrategy.updateWithVersion(update.getEntity(), update.getEntityType(), previousVersion)) {
364+
if (!accessStrategy.updateWithVersion(update.entity(), update.getEntityType(), previousVersion)) {
374365

375-
throw new OptimisticLockingFailureException(String.format(UPDATE_FAILED_OPTIMISTIC_LOCKING, update.getEntity()));
366+
throw new OptimisticLockingFailureException(String.format(UPDATE_FAILED_OPTIMISTIC_LOCKING, update.entity()));
376367
}
377368
}
378369

‎spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateOperations.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.Optional;
2020
import java.util.stream.Stream;
2121

22+
import org.jspecify.annotations.Nullable;
2223
import org.springframework.dao.IncorrectUpdateSemanticsDataAccessException;
2324
import org.springframework.data.domain.Example;
2425
import org.springframework.data.domain.Page;
@@ -27,7 +28,6 @@
2728
import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
2829
import org.springframework.data.jdbc.core.convert.JdbcConverter;
2930
import org.springframework.data.relational.core.query.Query;
30-
import org.springframework.lang.Nullable;
3131

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

173173
/**
174-
* Loads all entities that match one of the ids passed as an argument to a {@link Stream}.
175-
* It is not guaranteed that the number of ids passed in matches the number of entities returned.
174+
* Loads all entities that match one of the ids passed as an argument to a {@link Stream}. It is not guaranteed that
175+
* the number of ids passed in matches the number of entities returned.
176176
*
177177
* @param ids the Ids of the entities to load. Must not be {@code null}.
178178
* @param domainType the type of entities to load. Must not be {@code null}.

‎spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateTemplate.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.stream.Stream;
2929
import java.util.stream.StreamSupport;
3030

31+
import org.jspecify.annotations.Nullable;
3132
import org.springframework.beans.BeansException;
3233
import org.springframework.context.ApplicationContext;
3334
import org.springframework.context.ApplicationContextAware;
@@ -55,7 +56,6 @@
5556
import org.springframework.data.relational.core.mapping.event.*;
5657
import org.springframework.data.relational.core.query.Query;
5758
import org.springframework.data.support.PageableExecutionUtils;
58-
import org.springframework.lang.Nullable;
5959
import org.springframework.util.Assert;
6060
import org.springframework.util.ClassUtils;
6161

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

307307
@Override
308-
public <T> T findById(Object id, Class<T> domainType) {
308+
public <T> @NullableT findById(Object id, Class<T> domainType) {
309309

310310
Assert.notNull(id, "Id must not be null");
311311
Assert.notNull(domainType, "Domain type must not be null");

‎spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/AggregateReader.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.List;
2424
import java.util.Optional;
2525

26+
import org.jspecify.annotations.Nullable;
2627
import org.springframework.dao.IncorrectResultSizeDataAccessException;
2728
import org.springframework.data.relational.core.dialect.Dialect;
2829
import org.springframework.data.relational.core.mapping.AggregatePath;
@@ -40,7 +41,6 @@
4041
import org.springframework.jdbc.core.ResultSetExtractor;
4142
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
4243
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
43-
import org.springframework.lang.Nullable;
4444

4545
/**
4646
* Reads complete Aggregates from the database, by generating appropriate SQL using a {@link SingleQuerySqlGenerator}
@@ -110,6 +110,7 @@ public <T> T findById(Object id, RelationalPersistentEntity<T> entity) {
110110
* @return the found aggregate root, or {@literal null} if not found.
111111
* @param <T> aggregator type.
112112
*/
113+
@SuppressWarnings("NullAway") // NullAway complains about the ResultSetExtractor returning null, which should be ok.
113114
@Nullable
114115
public <T> T findOne(Query query, RelationalPersistentEntity<T> entity) {
115116
return doFind(query, entity, rs -> extractZeroOrOne(rs, entity));

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /