From 7afb8d4747e8d0af35b140bc2d640ae419e79043 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 21 Nov 2024 09:58:43 +0100 Subject: [PATCH] Polishing. Remove JPA 2.1 guards as we require JPA 3.x. Refine API to reduce nullability. Original pull request: #3684 See #3682 --- .../repository/query/AbstractJpaQuery.java | 2 +- .../data/jpa/repository/query/Jpa21Utils.java | 52 +++++-------------- .../repository/support/DefaultQueryHints.java | 6 +-- .../modules/ROOT/pages/jpa/query-methods.adoc | 2 +- 4 files changed, 17 insertions(+), 45 deletions(-) diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java index 5742a1ea4..bbde6d941 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java @@ -256,7 +256,7 @@ public abstract class AbstractJpaQuery implements RepositoryQuery { JpaEntityGraph entityGraph = method.getEntityGraph(); if (entityGraph != null) { - QueryHints hints = Jpa21Utils.getFetchGraphHint(em, method.getEntityGraph(), + QueryHints hints = Jpa21Utils.getFetchGraphHint(em, entityGraph, getQueryMethod().getEntityInformation().getJavaType()); hints.forEach(query::setHint); diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/Jpa21Utils.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/Jpa21Utils.java index e3133719f..8605786fc 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/Jpa21Utils.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/Jpa21Utils.java @@ -15,24 +15,21 @@ */ package org.springframework.data.jpa.repository.query; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import jakarta.persistence.AttributeNode; import jakarta.persistence.EntityGraph; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; import jakarta.persistence.Subgraph; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + import org.springframework.data.jpa.repository.support.MutableQueryHints; import org.springframework.data.jpa.repository.support.QueryHints; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; -import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; /** @@ -48,38 +45,16 @@ import org.springframework.util.StringUtils; */ public class Jpa21Utils { - private static final @Nullable Method GET_ENTITY_GRAPH_METHOD; - private static final boolean JPA21_AVAILABLE = ClassUtils.isPresent("jakarta.persistence.NamedEntityGraph", - Jpa21Utils.class.getClassLoader()); - - static { - - if (JPA21_AVAILABLE) { - GET_ENTITY_GRAPH_METHOD = ReflectionUtils.findMethod(EntityManager.class, "getEntityGraph", String.class); - } else { - GET_ENTITY_GRAPH_METHOD = null; - } - } - private Jpa21Utils() { // prevent instantiation } - public static QueryHints getFetchGraphHint(EntityManager em, @Nullable JpaEntityGraph entityGraph, - Class entityType) { + public static QueryHints getFetchGraphHint(EntityManager em, JpaEntityGraph entityGraph, Class entityType) { MutableQueryHints result = new MutableQueryHints(); - if (entityGraph == null) { - return result; - } - EntityGraph graph = tryGetFetchGraph(em, entityGraph, entityType); - if (graph == null) { - return result; - } - result.add(entityGraph.getType().getKey(), graph); return result; } @@ -94,24 +69,21 @@ public class Jpa21Utils { * @param entityType must not be {@literal null}. * @return the {@link EntityGraph} described by the given {@code entityGraph}. */ - @Nullable private static EntityGraph tryGetFetchGraph(EntityManager em, JpaEntityGraph jpaEntityGraph, Class entityType) { Assert.notNull(em, "EntityManager must not be null"); Assert.notNull(jpaEntityGraph, "EntityGraph must not be null"); Assert.notNull(entityType, "EntityType must not be null"); - Assert.isTrue(JPA21_AVAILABLE, "The EntityGraph-Feature requires at least a JPA 2.1 persistence provider"); - Assert.isTrue(GET_ENTITY_GRAPH_METHOD != null, - "It seems that you have the JPA 2.1 API but a JPA 2.0 implementation on the classpath"); + if (StringUtils.hasText(jpaEntityGraph.getName())) { - try { - // first check whether an entityGraph with that name is already registered. - return em.getEntityGraph(jpaEntityGraph.getName()); - } catch (Exception ex) { - // try to create and dynamically register the entityGraph - return createDynamicEntityGraph(em, jpaEntityGraph, entityType); + try { + // check whether an entityGraph with that name is already registered. + return em.getEntityGraph(jpaEntityGraph.getName()); + } catch (Exception ignore) {} } + + return createDynamicEntityGraph(em, jpaEntityGraph, entityType); } /** diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/DefaultQueryHints.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/DefaultQueryHints.java index bbf5b12a9..f5ff87be6 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/DefaultQueryHints.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/DefaultQueryHints.java @@ -15,11 +15,11 @@ */ package org.springframework.data.jpa.repository.support; +import jakarta.persistence.EntityManager; + import java.util.Optional; import java.util.function.BiConsumer; -import jakarta.persistence.EntityManager; - import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.query.Jpa21Utils; import org.springframework.data.jpa.repository.query.JpaEntityGraph; @@ -99,7 +99,7 @@ class DefaultQueryHints implements QueryHints { return Optionals .mapIfAllPresent(entityManager, metadata.getEntityGraph(), (em, graph) -> Jpa21Utils.getFetchGraphHint(em, getEntityGraph(graph), information.getJavaType())) - .orElse(new MutableQueryHints()); + .orElseGet(MutableQueryHints::new); } private JpaEntityGraph getEntityGraph(EntityGraph entityGraph) { diff --git a/src/main/antora/modules/ROOT/pages/jpa/query-methods.adoc b/src/main/antora/modules/ROOT/pages/jpa/query-methods.adoc index f69bb7929..f96e27eee 100644 --- a/src/main/antora/modules/ROOT/pages/jpa/query-methods.adoc +++ b/src/main/antora/modules/ROOT/pages/jpa/query-methods.adoc @@ -824,7 +824,7 @@ public interface GroupRepository extends CrudRepository { It is also possible to define ad hoc entity graphs by using `@EntityGraph`. The provided `attributePaths` are translated into the according `EntityGraph` without needing to explicitly add `@NamedEntityGraph` to your domain types, as shown in the following example: -.Using AD-HOC entity graph definition on an repository query method. +.Using ad-hoc entity graph definitions on a repository query method ==== [source, java] ----