@@ -332,6 +332,87 @@ public interface UserRepository extends JpaRepository<User, Long> {
332332----
333333====
334334
335+ [[jpa.query-methods.query-rewriter]]
336+ ==== Applying a QueryRewriter
337+
338+ Sometimes, no matter how many features you try to apply, it seems impossible to get Spring Data JPA to apply every thing
339+ you'd like to a query before it is sent to the `EntityManager`.
340+
341+ You have the ability to get your hands on the query, right before it's sent to the `EntityManager` and "rewrite" it. That is,
342+ you can make any alterations at the last moment.
343+
344+ .Declare a QueryRewriter using `@Query`
345+ ====
346+ [source, java]
347+ ----
348+ public interface MyRepository extends JpaRepository<User, Long> {
349+
350+ @Query(value = "select original_user_alias.* from SD_USER original_user_alias",
351+ nativeQuery = true,
352+ queryRewriter = MyQueryRewriter.class)
353+ List<User> findByNativeQuery(String param);
354+
355+ @Query(value = "select original_user_alias from User original_user_alias",
356+ queryRewriter = MyQueryRewriter.class)
357+ List<User> findByNonNativeQuery(String param);
358+ }
359+ ----
360+ ====
361+
362+ This example shows both a native (pure SQL) rewriter as well as a JPQL query, both leveraging the same `QueryRewriter`.
363+ In this scenario, Spring Data JPA will look for a bean registered in the application context of the corresponding type.
364+
365+ You can write a query rewriter like this:
366+
367+ .Example `QueryRewriter`
368+ ====
369+ [source, java]
370+ ----
371+ public class MyQueryRewriter implements QueryRewriter {
372+
373+ @Override
374+ public String rewrite(String query, Sort sort) {
375+ return query.replaceAll("original_user_alias", "rewritten_user_alias");
376+ }
377+ }
378+ ----
379+ ====
380+
381+ You have to ensure your `QueryRewriter` is registered in the application context, whether it's by applying one of Spring Framework's
382+ `@Component`-based annotations, or having it as part of a `@Bean` method inside an `@Configuration` class.
383+
384+ Another option is to have the repository itself implement the interface.
385+
386+ .Repository that provides the `QueryRewriter`
387+ ====
388+ [source, java]
389+ ----
390+ public interface MyRepository extends JpaRepository<User, Long>, QueryRewriter {
391+
392+ @Query(value = "select original_user_alias.* from SD_USER original_user_alias",
393+ nativeQuery = true,
394+ queryRewriter = MyRepository.class)
395+ List<User> findByNativeQuery(String param);
396+
397+ @Query(value = "select original_user_alias from User original_user_alias",
398+ queryRewriter = MyRepository.class)
399+ List<User> findByNonNativeQuery(String param);
400+
401+ @Override
402+ default String rewrite(String query, Sort sort) {
403+ return query.replaceAll("original_user_alias", "rewritten_user_alias");
404+ }
405+ }
406+ ----
407+ ====
408+
409+ Depending on what you're doing with your `QueryRewriter`, it may be advisable to have more than one, each registered with the
410+ application context.
411+
412+ NOTE: In a CDI-based environment, Spring Data JPA will search the `BeanManager` for instances of your implementation of
413+ `QueryRewriter`.
414+
415+
335416[[jpa.query-methods.at-query.advanced-like]]
336417==== Using Advanced `LIKE` Expressions
337418
0 commit comments