Skip to content

Commit 3f40705

Browse files
committed
Update reference docs with QueryRewriter details.
See #2162.
1 parent 6c94e0e commit 3f40705

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

src/main/asciidoc/jpa.adoc

+81
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)