@@ -332,6 +332,87 @@ public interface UserRepository extends JpaRepository<User, Long> {
332
332
----
333
333
====
334
334
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
+
335
416
[[jpa.query-methods.at-query.advanced-like]]
336
417
==== Using Advanced `LIKE` Expressions
337
418
0 commit comments