diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaRepository.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaRepository.java index a3541460f..4346d853d 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaRepository.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/JpaRepository.java @@ -15,10 +15,10 @@ */ package org.springframework.data.jpa.repository; -import java.util.List; - import jakarta.persistence.EntityManager; +import java.util.List; + import org.springframework.data.domain.Example; import org.springframework.data.domain.Sort; import org.springframework.data.repository.ListCrudRepository; @@ -38,7 +38,8 @@ import org.springframework.data.repository.query.QueryByExampleExecutor; * @author Jens Schauder */ @NoRepositoryBean -public interface JpaRepository extends ListCrudRepository, ListPagingAndSortingRepository, QueryByExampleExecutor { +public interface JpaRepository + extends ListCrudRepository, ListPagingAndSortingRepository, QueryByExampleExecutor { /** * Flushes all pending changes to the database. @@ -66,6 +67,8 @@ public interface JpaRepository extends ListCrudRepository, ListPag * Deletes the given entities in a batch which means it will create a single query. This kind of operation leaves JPAs * first level cache and the database out of sync. Consider flushing the {@link EntityManager} before calling this * method. + *

+ * It will also NOT honor cascade semantics of JPA, nor will it emit JPA lifecycle events. * * @param entities entities to be deleted. Must not be {@literal null}. * @deprecated Use {@link #deleteAllInBatch(Iterable)} instead. @@ -80,8 +83,8 @@ public interface JpaRepository extends ListCrudRepository, ListPag * first level cache and the database out of sync. Consider flushing the {@link EntityManager} before calling this * method. *

- * It will also NOT honor cascade semantics of JPA, nor will it emit JPA lifecycle events. - *

+ * It will also NOT honor cascade semantics of JPA, nor will it emit JPA lifecycle events. + * * @param entities entities to be deleted. Must not be {@literal null}. * @since 2.5 */ diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java index 14b289005..0fb78d4b5 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java @@ -40,16 +40,7 @@ import jakarta.persistence.metamodel.SingularAttribute; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Member; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -292,9 +283,8 @@ public abstract class QueryUtils { Set selectionAliases = getFunctionAliases(query); selectionAliases.addAll(getFieldAliases(query)); - String orderClauses = sort.stream() - .map(order -> getOrderClause(joinAliases, selectionAliases, alias, order)) - .collect(Collectors.joining(", ")); + String orderClauses = sort.stream().map(order -> getOrderClause(joinAliases, selectionAliases, alias, order)) + .collect(Collectors.joining(", ")); builder.append(orderClauses); @@ -532,7 +522,6 @@ public abstract class QueryUtils { * @param entityManager must not be {@literal null}. * @return Guaranteed to be not {@literal null}. */ - public static Query applyAndBind(String queryString, Iterable entities, EntityManager entityManager) { Assert.notNull(queryString, "Querystring must not be null"); @@ -546,30 +535,8 @@ public abstract class QueryUtils { } String alias = detectAlias(queryString); - StringBuilder builder = new StringBuilder(queryString); - builder.append(" where"); - - int i = 0; - - while (iterator.hasNext()) { - - iterator.next(); - - builder.append(String.format(" %s = ?%d", alias, ++i)); - - if (iterator.hasNext()) { - builder.append(" or"); - } - } - - Query query = entityManager.createQuery(builder.toString()); - - iterator = entities.iterator(); - i = 0; - - while (iterator.hasNext()) { - query.setParameter(++i, iterator.next()); - } + Query query = entityManager.createQuery("%s where %s IN (?1)".formatted(queryString, alias)); + query.setParameter(1, entities instanceof Collection ? entities : Streamable.of(entities).toList()); return query; }