Polishing.

Simplify POM setup. Reformat code.

See #3745
Original pull request: #3781
This commit is contained in:
Mark Paluch
2025-02-20 13:23:29 +01:00
parent 59e9f3459c
commit 047fa2bc38
15 changed files with 62 additions and 221 deletions

View File

@@ -343,7 +343,7 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<annotationProcessorPaths combine.children="append">
<path>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
@@ -424,130 +424,4 @@
</plugins>
</build>
<profiles>
<profile>
<id>all-dbs</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>mysql-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<includes>
<include>**/MySql*IntegrationTests.java</include>
</includes>
</configuration>
</execution>
<execution>
<id>postgres-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<includes>
<include>**/Postgres*IntegrationTests.java
</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<profiles>
<profile>
<id>nullaway</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl}</version>
<classifier>jakarta</classifier>
</path>
<path>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>${hibernate}</version>
</path>
<path>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate}</version>
</path>
<path>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh}</version>
</path>
<path>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>${jakarta-persistence-api}</version>
</path>
<path>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_core</artifactId>
<version>${errorprone}</version>
</path>
<path>
<groupId>com.uber.nullaway</groupId>
<artifactId>nullaway</artifactId>
<version>${nullaway}</version>
</path>
</annotationProcessorPaths>
</configuration>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<compilerArgs>
<arg>-XDcompilePolicy=simple</arg>
<arg>--should-stop=ifError=FLOW</arg>
<arg>-Xplugin:ErrorProne -XepDisableAllChecks -Xep:NullAway:ERROR -XepOpt:NullAway:OnlyNullMarked=true -XepOpt:NullAway:TreatGeneratedAsUnannotated=true -XepOpt:NullAway:CustomContractAnnotations=org.springframework.lang.Contract</arg>
</compilerArgs>
</configuration>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -25,9 +25,9 @@ import java.io.Serializable;
import java.util.Arrays;
import java.util.stream.StreamSupport;
import org.springframework.lang.CheckReturnValue;
import org.jspecify.annotations.Nullable;
import org.springframework.lang.CheckReturnValue;
import org.springframework.lang.Contract;
import org.springframework.util.Assert;
@@ -232,6 +232,6 @@ public interface Specification<T> extends Serializable {
* @return a {@link Predicate}, may be {@literal null}.
*/
@Nullable
Predicate toPredicate(Root<T> root, @Nullable CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder);
Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder);
}

View File

@@ -61,7 +61,7 @@ class SpecificationComposition {
}
private static <T> @Nullable Predicate toPredicate(@Nullable Specification<T> specification, Root<T> root,
@Nullable CriteriaQuery<?> query, CriteriaBuilder builder) {
CriteriaQuery<?> query, CriteriaBuilder builder) {
return specification == null ? null : specification.toPredicate(root, query, builder);
}

View File

@@ -33,9 +33,9 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.springframework.aot.generate.GenerationContext;
import org.jspecify.annotations.Nullable;
import org.springframework.aot.generate.GenerationContext;
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
@@ -117,7 +117,7 @@ public class JpaRepositoryConfigExtension extends RepositoryConfigurationExtensi
Optional<String> transactionManagerRef = source.getAttribute("transactionManagerRef");
builder.addPropertyValue("transactionManager", transactionManagerRef.orElse(DEFAULT_TRANSACTION_MANAGER_BEAN_NAME));
if(entityManagerRefs.containsKey(source)) {
if (entityManagerRefs.containsKey(source)) {
builder.addPropertyReference("entityManager", entityManagerRefs.get(source));
}
builder.addPropertyValue(ESCAPE_CHARACTER_PROPERTY, getEscapeCharacter(source).orElse('\\'));

View File

@@ -38,7 +38,6 @@ import net.sf.jsqlparser.statement.select.SelectItem;
import net.sf.jsqlparser.statement.select.SetOperationList;
import net.sf.jsqlparser.statement.select.Values;
import net.sf.jsqlparser.statement.update.Update;
import org.jspecify.annotations.Nullable;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -52,6 +51,8 @@ import java.util.StringJoiner;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.Sort;
import org.springframework.data.util.Predicates;
import org.springframework.util.Assert;
@@ -81,7 +82,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
private final String projection;
private final Set<String> joinAliases;
private final Set<String> selectAliases;
private final byte @Nullable[] serialized;
private final byte @Nullable [] serialized;
/**
* @param query the query we want to enhance. Must not be {@literal null}.
@@ -98,7 +99,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
this.selectAliases = Collections.unmodifiableSet(getSelectionAliases(this.statement));
this.joinAliases = Collections.unmodifiableSet(getJoinAliases(this.statement));
byte[] tmp = SerializationUtils.serialize(this.statement);
// this.serialized = tmp != null ? tmp : new byte[0];
// this.serialized = tmp != null ? tmp : new byte[0];
this.serialized = SerializationUtils.serialize(this.statement);
}
@@ -374,7 +375,7 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
return applySortingToSetOperationList(setOperationList, sort);
}
doWithPlainSelect(selectStatement, it -> {
doWithPlainSelect (selectStatement , it -> {
List<OrderByElement> orderByElements = new ArrayList<>(16);
for (Sort.Order order : sort) {
@@ -572,8 +573,8 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
* @param bytes a serialized object
* @return the result of deserializing the bytes
*/
private static @Nullable Object deserialize(byte @Nullable[] bytes) {
if(ObjectUtils.isEmpty(bytes)) {
private static @Nullable Object deserialize(byte @Nullable [] bytes) {
if (ObjectUtils.isEmpty(bytes)) {
return null;
}
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
@@ -585,9 +586,9 @@ public class JSqlParserQueryEnhancer implements QueryEnhancer {
}
}
private static <T> T deserializeRequired(byte @Nullable[] bytes, Class<T> type) {
private static <T> T deserializeRequired(byte @Nullable [] bytes, Class<T> type) {
Object deserialize = deserialize(bytes);
if(deserialize != null) {
if (deserialize != null) {
return type.cast(deserialize);
}
throw new IllegalStateException("Failed to deserialize object type");

View File

@@ -17,9 +17,9 @@ package org.springframework.data.jpa.repository.query;
import static org.springframework.data.jpa.repository.query.QueryTokens.*;
import org.springframework.data.jpa.repository.query.QueryRenderer.QueryRendererBuilder;
import org.jspecify.annotations.Nullable;
import org.springframework.data.jpa.repository.query.QueryRenderer.QueryRendererBuilder;
import org.springframework.data.jpa.repository.query.QueryTransformers.CountSelectionTokenStream;
import org.springframework.util.StringUtils;
@@ -82,7 +82,7 @@ class JpqlCountQueryTransformer extends JpqlQueryRenderer {
if (usesDistinct) {
nested.append(QueryTokens.expression(ctx.DISTINCT()));
nested.append(getDistinctCountSelection(QueryTokenStream.concat(ctx.select_item(), this::visit, TOKEN_COMMA)));
} else if(StringUtils.hasText(primaryFromAlias)) {
} else if (StringUtils.hasText(primaryFromAlias)) {
nested.append(QueryTokens.token(primaryFromAlias));
} else {
throw new IllegalStateException("No primary alias present");

View File

@@ -25,23 +25,25 @@ import jakarta.persistence.metamodel.PluralAttribute;
import java.util.Objects;
import org.springframework.data.mapping.PropertyPath;
import org.jspecify.annotations.Nullable;
import org.springframework.data.mapping.PropertyPath;
import org.springframework.util.StringUtils;
/**
* Utilities to create JPQL expressions, derived from {@link QueryUtils}.
*
* @author Mark Paluch
*/
class JpqlUtils {
static JpqlQueryBuilder.PathExpression toExpressionRecursively(@Nullable Metamodel metamodel, JpqlQueryBuilder.Origin source,
Bindable<?> from, PropertyPath property) {
static JpqlQueryBuilder.PathExpression toExpressionRecursively(@Nullable Metamodel metamodel,
JpqlQueryBuilder.Origin source, Bindable<?> from, PropertyPath property) {
return toExpressionRecursively(metamodel, source, from, property, false);
}
static JpqlQueryBuilder.PathExpression toExpressionRecursively(@Nullable Metamodel metamodel, JpqlQueryBuilder.Origin source,
Bindable<?> from, PropertyPath property, boolean isForSelection) {
static JpqlQueryBuilder.PathExpression toExpressionRecursively(@Nullable Metamodel metamodel,
JpqlQueryBuilder.Origin source, Bindable<?> from, PropertyPath property, boolean isForSelection) {
return toExpressionRecursively(metamodel, source, from, property, isForSelection, false);
}
@@ -54,8 +56,9 @@ class JpqlUtils {
* @param hasRequiredOuterJoin has a parent already required an outer join?
* @return the expression
*/
static JpqlQueryBuilder.PathExpression toExpressionRecursively(@Nullable Metamodel metamodel, JpqlQueryBuilder.Origin source,
Bindable<?> from, PropertyPath property, boolean isForSelection, boolean hasRequiredOuterJoin) {
static JpqlQueryBuilder.PathExpression toExpressionRecursively(@Nullable Metamodel metamodel,
JpqlQueryBuilder.Origin source, Bindable<?> from, PropertyPath property, boolean isForSelection,
boolean hasRequiredOuterJoin) {
String segment = property.getSegment();
@@ -81,7 +84,7 @@ class JpqlUtils {
ManagedType<?> managedTypeForModel = QueryUtils.getManagedTypeForModel(from);
Attribute<?, ?> nextAttribute = getModelForPath(metamodel, property, managedTypeForModel, from);
if(nextAttribute == null) {
if (nextAttribute == null) {
throw new IllegalStateException("Binding property is null");
}
@@ -144,7 +147,7 @@ class JpqlUtils {
}
}
if(metamodel != null) {
if (metamodel != null) {
Class<?> fallbackType = fallback.getBindableJavaType();
try {

View File

@@ -26,9 +26,9 @@ import jakarta.persistence.metamodel.Metamodel;
import java.util.List;
import org.springframework.data.domain.KeysetScrollPosition;
import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.KeysetScrollPosition;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
@@ -68,7 +68,8 @@ public record KeysetScrollSpecification<T>(KeysetScrollPosition position, Sort s
}
@Override
public @Nullable Predicate toPredicate(Root<T> root, @Nullable CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
public @Nullable Predicate toPredicate(Root<T> root, @Nullable CriteriaQuery<?> query,
CriteriaBuilder criteriaBuilder) {
return createPredicate(root, criteriaBuilder);
}
@@ -78,7 +79,6 @@ public record KeysetScrollSpecification<T>(KeysetScrollPosition position, Sort s
return delegate.createPredicate(position, sort, new CriteriaBuilderStrategy(root, criteriaBuilder));
}
public JpqlQueryBuilder.@Nullable Predicate createJpqlPredicate(Bindable<?> from, JpqlQueryBuilder.Entity entity,
ParameterFactory factory) {
@@ -108,9 +108,9 @@ public record KeysetScrollSpecification<T>(KeysetScrollPosition position, Sort s
@Override
public Predicate compare(Order order, Expression<Comparable> propertyExpression, @Nullable Object value) {
if(value instanceof Comparable compareValue) {
if (value instanceof Comparable compareValue) {
return order.isAscending() ? cb.greaterThan(propertyExpression, compareValue)
: cb.lessThan(propertyExpression, compareValue);
: cb.lessThan(propertyExpression, compareValue);
}
return order.isAscending() ? cb.isNull(propertyExpression) : cb.isNotNull(propertyExpression);
@@ -139,12 +139,13 @@ public record KeysetScrollSpecification<T>(KeysetScrollPosition position, Sort s
private final ParameterFactory factory;
private final @Nullable Metamodel metamodel;
public JpqlStrategy(@Nullable Metamodel metamodel, Bindable<?> from, JpqlQueryBuilder.Entity entity, ParameterFactory factory) {
public JpqlStrategy(@Nullable Metamodel metamodel, Bindable<?> from, JpqlQueryBuilder.Entity entity,
ParameterFactory factory) {
this.from = from;
this.entity = entity;
this.factory = factory;
this.metamodel = metamodel;
this.metamodel = metamodel;
}
@Override
@@ -159,7 +160,7 @@ public record KeysetScrollSpecification<T>(KeysetScrollPosition position, Sort s
@Nullable Object value) {
JpqlQueryBuilder.WhereStep where = JpqlQueryBuilder.where(propertyExpression);
if(value == null) {
if (value == null) {
return order.isAscending() ? where.isNull() : where.isNotNull();
}
return order.isAscending() ? where.gt(factory.capture(value)) : where.lt(factory.capture(value));

View File

@@ -46,9 +46,9 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.springframework.core.annotation.AnnotationUtils;
import org.jspecify.annotations.Nullable;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
@@ -875,7 +875,7 @@ public abstract class QueryUtils {
}
Annotation annotation = AnnotationUtils.getAnnotation(annotatedMember, associationAnnotation);
if(annotation == null) {
if (annotation == null) {
return defaultValue;
}

View File

@@ -62,11 +62,13 @@ abstract class EntityGraphFactory {
if (path.hasNext()) {
if(current == null) {
current = existingSubgraphs.computeIfAbsent(currentFullPath, k -> entityGraph.addSubgraph(path.getSegment()));
if (current == null) {
current = existingSubgraphs.computeIfAbsent(currentFullPath,
k -> entityGraph.addSubgraph(path.getSegment()));
} else {
final Subgraph<Object> finalCurrent = current;
current = existingSubgraphs.computeIfAbsent(currentFullPath, k -> finalCurrent.addSubgraph(path.getSegment()));
current = existingSubgraphs.computeIfAbsent(currentFullPath,
k -> finalCurrent.addSubgraph(path.getSegment()));
}
continue;
}

View File

@@ -29,8 +29,6 @@ import java.util.stream.Stream;
import org.jspecify.annotations.Nullable;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
@@ -227,7 +225,7 @@ class FetchableFluentQueryBySpecification<S, R> extends FluentQuerySupport<S, R>
private Slice<R> readSlice(Pageable pageable) {
TypedQuery<S> pagedQuery = createSortedAndProjectedQuery();
TypedQuery<S> pagedQuery = createSortedAndProjectedQuery(pageable.getSort());
if (pageable.isPaged()) {
pagedQuery.setFirstResult(PageableUtils.getOffsetAsInteger(pageable));

View File

@@ -226,13 +226,14 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport {
}
@Override
protected ProjectionFactory getProjectionFactory(@Nullable ClassLoader classLoader, @Nullable BeanFactory beanFactory) {
protected ProjectionFactory getProjectionFactory(@Nullable ClassLoader classLoader,
@Nullable BeanFactory beanFactory) {
CollectionAwareProjectionFactory factory = new CollectionAwareProjectionFactory();
if(classLoader != null) {
if (classLoader != null) {
factory.setBeanClassLoader(classLoader);
}
if(beanFactory != null) {
if (beanFactory != null) {
factory.setBeanFactory(beanFactory);
}
@@ -243,11 +244,9 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport {
protected Optional<QueryLookupStrategy> getQueryLookupStrategy(@Nullable Key key,
ValueExpressionDelegate valueExpressionDelegate) {
return Optional.of(JpaQueryLookupStrategy.create(entityManager, queryMethodFactory, key,
new CachingValueExpressionDelegate(valueExpressionDelegate),
queryRewriterProvider, escapeCharacter));
new CachingValueExpressionDelegate(valueExpressionDelegate), queryRewriterProvider, escapeCharacter));
}
@Override
@SuppressWarnings("unchecked")
public <T, ID> JpaEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {

View File

@@ -23,6 +23,8 @@ import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import org.jspecify.annotations.Nullable;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.KeysetScrollPosition;
@@ -59,7 +61,6 @@ import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.jpa.JPQLQuery;
import com.querydsl.jpa.impl.AbstractJPAQuery;
import org.jspecify.annotations.Nullable;
/**
* Querydsl specific fragment for extending {@link SimpleJpaRepository} with an implementation of
@@ -376,7 +377,7 @@ public class QuerydslJpaPredicateExecutor<T> implements QuerydslPredicateExecuto
@Override
public BooleanExpression compare(Order order, Expression<?> propertyExpression, @Nullable Object value) {
if(value == null) {
if (value == null) {
return Expressions.booleanOperation(order.isAscending() ? Ops.IS_NULL : Ops.IS_NOT_NULL, propertyExpression);
}

View File

@@ -40,9 +40,9 @@ import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Function;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.jspecify.annotations.Nullable;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.KeysetScrollPosition;
import org.springframework.data.domain.OffsetScrollPosition;

View File

@@ -2801,44 +2801,6 @@ class UserRepositoryTests {
assertThat(page0.getTotalElements()).isEqualTo(3L);
}
@Test // GH-2274
void findByFluentSpecificationSlice() {
flushTestUsers();
Slice<User> slice = repository.findBy(userHasFirstnameLike("v"),
q -> q.sortBy(Sort.by("firstname")).slice(PageRequest.of(0, 2)));
assertThat(slice).isNotInstanceOf(Page.class);
assertThat(slice.getContent()).containsExactly(thirdUser, firstUser);
assertThat(slice.hasNext()).isTrue();
slice = repository.findBy(userHasFirstnameLike("v"),
q -> q.sortBy(Sort.by("firstname")).slice(PageRequest.of(0, 3)));
assertThat(slice).isNotInstanceOf(Page.class);
assertThat(slice).hasSize(3);
assertThat(slice.hasNext()).isFalse();
}
@Test // GH-3727
void findByFluentSpecificationPageCustomCountSpec() {
flushTestUsers();
Page<User> page0 = repository.findBy(userHasFirstnameLike("v"),
q -> q.sortBy(Sort.by("firstname")).page(PageRequest.of(0, 2), (root, query, criteriaBuilder) -> null));
assertThat(page0.getContent()).containsExactly(thirdUser, firstUser);
assertThat(page0.getTotalElements()).isEqualTo(4L);
page0 = repository.findBy(userHasFirstnameLike("v"),
q -> q.sortBy(Sort.by("firstname")).page(PageRequest.of(0, 2)));
assertThat(page0.getContent()).containsExactly(thirdUser, firstUser);
assertThat(page0.getTotalElements()).isEqualTo(3L);
}
@Test // GH-2274, GH-3716
void findByFluentSpecificationWithInterfaceBasedProjection() {