From c150ddcf4f3b1fadb4c105b23affad69a37102c0 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Thu, 19 Dec 2024 14:07:53 +0100 Subject: [PATCH] Polishing. A round of minor code style improvements. Original Pull Request: #3695 --- .../data/jpa/domain/JpaSort.java | 4 +-- .../mapping/JpaPersistentPropertyImpl.java | 10 +++---- .../data/jpa/projection/package-info.java | 5 ++++ .../query/AbstractStringBasedJpaQuery.java | 4 +-- .../query/JSqlParserQueryEnhancer.java | 5 ++-- .../query/JpaQueryLookupStrategy.java | 3 ++- .../repository/query/JpqlQueryBuilder.java | 4 +-- .../query/KeysetScrollDelegate.java | 2 +- .../repository/query/ParameterBinding.java | 2 +- .../query/ParameterMetadataProvider.java | 17 +++++------- .../query/QueryParameterSetterFactory.java | 2 -- .../repository/query/QueryTokenStream.java | 5 ++++ .../jpa/repository/query/SimpleJpaQuery.java | 26 ++++++------------- .../jpa/repository/query/StringQuery.java | 26 +++++++------------ ...hScanningPersistenceUnitPostProcessor.java | 2 +- 15 files changed, 48 insertions(+), 69 deletions(-) create mode 100644 spring-data-jpa/src/main/java/org/springframework/data/jpa/projection/package-info.java diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/domain/JpaSort.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/domain/JpaSort.java index a28bf8a390..99b29715ec 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/domain/JpaSort.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/domain/JpaSort.java @@ -281,14 +281,14 @@ public , U> Path dot(A attribute) { * @return */ public

, U> Path dot(P attribute) { - return new Path(add(attribute)); + return new Path<>(add(attribute)); } private List> add(Attribute attribute) { Assert.notNull(attribute, "Attribute must not be null"); - List> newAttributes = new ArrayList>(attributes.size() + 1); + List> newAttributes = new ArrayList<>(attributes.size() + 1); newAttributes.addAll(attributes); newAttributes.add(attribute); return newAttributes; diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImpl.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImpl.java index 501d3a6444..d2bd3039ad 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImpl.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/mapping/JpaPersistentPropertyImpl.java @@ -57,13 +57,9 @@ class JpaPersistentPropertyImpl extends AnnotationBasedPersistentProperty> annotations = new HashSet<>(); - annotations.add(OneToMany.class); - annotations.add(OneToOne.class); - annotations.add(ManyToMany.class); - annotations.add(ManyToOne.class); + Set> annotations; - ASSOCIATION_ANNOTATIONS = Collections.unmodifiableSet(annotations); + ASSOCIATION_ANNOTATIONS = Set.of(OneToMany.class, OneToOne.class, ManyToMany.class, ManyToOne.class); annotations = new HashSet<>(); annotations.add(Id.class); @@ -107,7 +103,7 @@ public JpaPersistentPropertyImpl(JpaMetamodel metamodel, Property property, this.associationTargetType = detectAssociationTargetType(); this.updateable = detectUpdatability(); - this.isIdProperty = Lazy.of(() -> ID_ANNOTATIONS.stream().anyMatch(it -> isAnnotationPresent(it)) // + this.isIdProperty = Lazy.of(() -> ID_ANNOTATIONS.stream().anyMatch(this::isAnnotationPresent) // || metamodel.isSingleIdAttribute(getOwner().getType(), getName(), getType())); this.isEntity = Lazy.of(() -> metamodel.isMappedType(getActualType())); } diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/projection/package-info.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/projection/package-info.java new file mode 100644 index 0000000000..4f85f48a62 --- /dev/null +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/projection/package-info.java @@ -0,0 +1,5 @@ +/** + * JPA specific support projection support. + */ +@org.springframework.lang.NonNullApi +package org.springframework.data.jpa.projection; diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java index 9c83985546..657778b260 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java @@ -93,9 +93,7 @@ public AbstractStringBasedJpaQuery(JpaQueryMethod method, EntityManager em, Stri return query.deriveCountQuery(method.getCountQueryProjection()); }); - this.countParameterBinder = Lazy.of(() -> { - return this.createBinder(this.countQuery.get()); - }); + this.countParameterBinder = Lazy.of(() -> this.createBinder(this.countQuery.get())); this.queryRewriter = queryRewriter; diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancer.java index 1686148603..c7a76502f9 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancer.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JSqlParserQueryEnhancer.java @@ -98,7 +98,8 @@ public JSqlParserQueryEnhancer(DeclaredQuery query) { /** * Parses a query string with JSqlParser. * - * @param query the query to parse + * @param sql the query to parse + * @param classOfT the query to parse * @return the parsed query */ static T parseStatement(String sql, Class classOfT) { @@ -502,7 +503,7 @@ private static boolean onlyASingleColumnProjection(List> projectio * */ enum ParsedType { - DELETE, UPDATE, SELECT, INSERT, MERGE, OTHER; + DELETE, UPDATE, SELECT, INSERT, MERGE, OTHER } /** diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java index 8ca7a007df..affcee14c8 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java @@ -143,7 +143,8 @@ private static class DeclaredQueryLookupStrategy extends AbstractQueryLookupStra * * @param em must not be {@literal null}. * @param queryMethodFactory must not be {@literal null}. - * @param evaluationContextProvider must not be {@literal null}. + * @param delegate must not be {@literal null}. + * @param queryRewriterProvider must not be {@literal null}. */ public DeclaredQueryLookupStrategy(EntityManager em, JpaQueryMethodFactory queryMethodFactory, ValueExpressionDelegate delegate, QueryRewriterProvider queryRewriterProvider) { diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryBuilder.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryBuilder.java index 287b397384..6c1817946b 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryBuilder.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpqlQueryBuilder.java @@ -848,9 +848,7 @@ public String getAlias(Origin source) { */ public String getAlias(Origin source) { - return aliases.computeIfAbsent(source, it -> JpqlQueryBuilder.getAlias(source.getName(), s -> { - return !aliases.containsValue(s); - }, () -> "join_" + (counter++))); + return aliases.computeIfAbsent(source, it -> JpqlQueryBuilder.getAlias(source.getName(), s -> !aliases.containsValue(s), () -> "join_" + (counter++))); } /** diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/KeysetScrollDelegate.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/KeysetScrollDelegate.java index 5d4d8acb5f..a9f38dcebc 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/KeysetScrollDelegate.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/KeysetScrollDelegate.java @@ -138,7 +138,7 @@ public Sort createSort(Sort sort, JpaEntityInformation entity) { } /** - * Reverse scrolling variant applying {@link Direction#Backward}. In reverse scrolling, we need to flip directions for + * Reverse scrolling variant applying {@link Direction#BACKWARD}. In reverse scrolling, we need to flip directions for * the actual query so that we do not get everything from the top position and apply the limit but rather flip the * sort direction, apply the limit and then reverse the result to restore the actual sort order. */ diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinding.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinding.java index 259343e9c7..ecd4d63ee0 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinding.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinding.java @@ -653,7 +653,7 @@ static MethodInvocationArgument ofParameter(@Nullable String name, @Nullable Int /** * Creates a {@link MethodInvocationArgument} object for {@code position}. * - * @param position the parameter position (1-based) from the method invocation. + * @param parameter the parameter from the method invocation. * @return {@link MethodInvocationArgument} object for {@code position}. */ static MethodInvocationArgument ofParameter(Parameter parameter) { diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java index de3256baa3..9fd7817a7e 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterMetadataProvider.java @@ -273,17 +273,12 @@ public Object prepare(@Nullable Object value) { if (String.class.equals(parameterType) && !noWildcards) { - switch (type) { - case STARTING_WITH: - return String.format("%s%%", escape.escape(value.toString())); - case ENDING_WITH: - return String.format("%%%s", escape.escape(value.toString())); - case CONTAINING: - case NOT_CONTAINING: - return String.format("%%%s%%", escape.escape(value.toString())); - default: - return value; - } + return switch (type) { + case STARTING_WITH -> String.format("%s%%", escape.escape(value.toString())); + case ENDING_WITH -> String.format("%%%s", escape.escape(value.toString())); + case CONTAINING, NOT_CONTAINING -> String.format("%%%s%%", escape.escape(value.toString())); + default -> value; + }; } return Collection.class.isAssignableFrom(parameterType) // diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java index 4844060aa3..4b5f530d0b 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java @@ -93,7 +93,6 @@ static QueryParameterSetterFactory forSynthetic() { * * @param parser must not be {@literal null}. * @param evaluationContextProvider must not be {@literal null}. - * @param parameters must not be {@literal null}. * @return a {@link QueryParameterSetterFactory} that can handle * {@link org.springframework.expression.spel.standard.SpelExpression}s. */ @@ -170,7 +169,6 @@ private static class ExpressionBasedQueryParameterSetterFactory extends QueryPar /** * @param parser must not be {@literal null}. * @param evaluationContextProvider must not be {@literal null}. - * @param parameters must not be {@literal null}. */ ExpressionBasedQueryParameterSetterFactory(ValueExpressionParser parser, ValueEvaluationContextProvider evaluationContextProvider) { diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryTokenStream.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryTokenStream.java index b31f48939c..9b97836ab9 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryTokenStream.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryTokenStream.java @@ -46,6 +46,7 @@ static QueryTokenStream empty() { /** * Creates a QueryTokenStream from a {@link QueryToken}. + * @since 4.0 */ static QueryTokenStream from(QueryToken token) { return QueryRenderer.from(Collections.singletonList(token)); @@ -53,6 +54,7 @@ static QueryTokenStream from(QueryToken token) { /** * Creates an token QueryRenderer from an AST {@link TerminalNode}. + * @since 4.0 */ static QueryTokenStream ofToken(TerminalNode node) { return from(QueryTokens.token(node)); @@ -60,6 +62,7 @@ static QueryTokenStream ofToken(TerminalNode node) { /** * Creates an token QueryRenderer from an AST {@link Token}. + * @since 4.0 */ static QueryTokenStream ofToken(Token node) { return from(QueryTokens.token(node)); @@ -148,6 +151,7 @@ default QueryToken getFirst() { /** * @return the required first query token or throw {@link java.util.NoSuchElementException} if empty. + * @since 4.0 */ default QueryToken getRequiredFirst() { @@ -170,6 +174,7 @@ default QueryToken getLast() { /** * @return the required last query token or throw {@link java.util.NoSuchElementException} if empty. + * @since 4.0 */ default QueryToken getRequiredLast() { diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java index 16fa3c30e0..b044191b54 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java @@ -84,23 +84,13 @@ private void validateQuery(String query, String errorMessage, Object... argument return; } - EntityManager validatingEm = null; - - try { - validatingEm = getEntityManager().getEntityManagerFactory().createEntityManager(); - validatingEm.createQuery(query); - - } catch (RuntimeException e) { - - // Needed as there's ambiguities in how an invalid query string shall be expressed by the persistence provider - // https://java.net/projects/jpa-spec/lists/jsr338-experts/archive/2012-07/message/17 - throw new IllegalArgumentException(String.format(errorMessage, arguments), e); - - } finally { - - if (validatingEm != null) { - validatingEm.close(); - } - } + try (EntityManager validatingEm = getEntityManager().getEntityManagerFactory().createEntityManager()) { + validatingEm.createQuery(query); + } catch (RuntimeException e) { + + // Needed as there's ambiguities in how an invalid query string shall be expressed by the persistence provider + // https://java.net/projects/jpa-spec/lists/jsr338-experts/archive/2012-07/message/17 + throw new IllegalArgumentException(String.format(errorMessage, arguments), e); + } } } diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java index 471ede0403..e531262ce1 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java @@ -304,25 +304,17 @@ String parseParameterBindingsOfQueryIntoBindingsAndReturnCleanedQuery(String que : ParameterOrigin.ofExpression(expression); BindingIdentifier targetBinding = queryParameter; - Function bindingFactory; - switch (ParameterBindingType.of(typeSource)) { + Function bindingFactory = switch (ParameterBindingType.of(typeSource)) { + case LIKE -> { - case LIKE: + Type likeType = LikeParameterBinding.getLikeTypeFrom(matcher.group(2)); + yield (identifier) -> new LikeParameterBinding(identifier, origin, likeType); + } + case IN -> (identifier) -> new InParameterBinding(identifier, origin); // fall-through we don't need a special parameter queryParameter for the given parameter. + default -> (identifier) -> new ParameterBinding(identifier, origin); + }; - Type likeType = LikeParameterBinding.getLikeTypeFrom(matcher.group(2)); - bindingFactory = (identifier) -> new LikeParameterBinding(identifier, origin, likeType); - break; - - case IN: - bindingFactory = (identifier) -> new InParameterBinding(identifier, origin); - break; - - case AS_IS: // fall-through we don't need a special parameter queryParameter for the given parameter. - default: - bindingFactory = (identifier) -> new ParameterBinding(identifier, origin); - } - - if (origin.isExpression()) { + if (origin.isExpression()) { parameterBindings.register(bindingFactory.apply(queryParameter)); } else { targetBinding = parameterBindings.register(queryParameter, origin, bindingFactory); diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/support/ClasspathScanningPersistenceUnitPostProcessor.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/support/ClasspathScanningPersistenceUnitPostProcessor.java index 8415d67959..06f454e24c 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/support/ClasspathScanningPersistenceUnitPostProcessor.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/support/ClasspathScanningPersistenceUnitPostProcessor.java @@ -193,7 +193,7 @@ private Set scanForMappingFileLocations() { * @param uri * @return */ - private static String getResourcePath(URI uri) throws IOException { + private static String getResourcePath(URI uri) { if (uri.isOpaque()) { // e.g. jar:file:/foo/lib/somelib.jar!/com/acme/orm.xml