15
15
*/
16
16
package org .springframework .data .jpa .repository .query ;
17
17
18
+ import java .util .ArrayList ;
19
+ import java .util .List ;
20
+
18
21
import org .apache .commons .logging .Log ;
19
22
import org .apache .commons .logging .LogFactory ;
23
+ import org .springframework .data .util .Lazy ;
20
24
21
25
/**
22
26
* Encapsulates different strategies for the creation of a {@link QueryEnhancer} from a {@link DeclaredQuery}.
@@ -33,19 +37,63 @@ public final class QueryEnhancerFactory {
33
37
34
38
private QueryEnhancerFactory () {}
35
39
40
+ /**
41
+ * Creates a {@link List} containing all the possible {@link QueryEnhancer} implementations for native queries. The
42
+ * order of the entries indicates that the first {@link QueryEnhancer} should be used. If this is not possible the
43
+ * next until the last one is reached which will be always {@link DefaultQueryEnhancer}.
44
+ *
45
+ * @param query the query for which the list should be created for
46
+ * @return list containing all the suitable implementations for the given query
47
+ */
48
+ private static List <Lazy <QueryEnhancer >> nativeQueryEnhancers (DeclaredQuery query ) {
49
+ ArrayList <Lazy <QueryEnhancer >> suitableImplementations = new ArrayList <>();
50
+
51
+ if (qualifiesForJSqlParserUsage (query )) {
52
+ suitableImplementations .add (Lazy .of (() -> new JSqlParserQueryEnhancer (query )));
53
+ }
54
+
55
+ // DefaultQueryEnhancer has to be the last since this is our fallback
56
+ suitableImplementations .add (Lazy .of (() -> new DefaultQueryEnhancer (query )));
57
+ return suitableImplementations ;
58
+ }
59
+
60
+ /**
61
+ * Creates a {@link List} containing all the possible {@link QueryEnhancer} implementations for non-native queries.
62
+ * The order of the entries indicates that the first {@link QueryEnhancer} should be used. If this is not possible the
63
+ * next until the last one is reached which will be always {@link DefaultQueryEnhancer}.
64
+ *
65
+ * @param query the query for which the list should be created for
66
+ * @return list containing all the suitable implementations for the given query
67
+ */
68
+ private static List <Lazy <QueryEnhancer >> nonNativeQueryEnhancers (DeclaredQuery query ) {
69
+ ArrayList <Lazy <QueryEnhancer >> suitableImplementations = new ArrayList <>();
70
+
71
+ // DefaultQueryEnhancer has to be the last since this is our fallback
72
+ suitableImplementations .add (Lazy .of (() -> new DefaultQueryEnhancer (query )));
73
+ return suitableImplementations ;
74
+ }
75
+
36
76
/**
37
77
* Creates a new {@link QueryEnhancer} for the given {@link DeclaredQuery}.
38
78
*
39
79
* @param query must not be {@literal null}.
40
80
* @return an implementation of {@link QueryEnhancer} that suits the query the most
41
81
*/
42
82
public static QueryEnhancer forQuery (DeclaredQuery query ) {
83
+ List <Lazy <QueryEnhancer >> suitableQueryEnhancers = query .isNativeQuery () ? nativeQueryEnhancers (query )
84
+ : nonNativeQueryEnhancers (query );
43
85
44
- if (qualifiesForJSqlParserUsage (query )) {
45
- return new JSqlParserQueryEnhancer (query );
46
- } else {
47
- return new DefaultQueryEnhancer (query );
86
+ for (Lazy <QueryEnhancer > suitableQueryEnhancer : suitableQueryEnhancers ) {
87
+ try {
88
+ return suitableQueryEnhancer .get ();
89
+ } catch (Exception e ) {
90
+ LOG .debug ("Falling back to next QueryEnhancer implementation, due to exception." , e );
91
+ }
48
92
}
93
+
94
+ throw new IllegalStateException (
95
+ "No QueryEnhancer found for the query [%s]! This should not happen since the default implementation (DefaultQueryEnhancer) should have been called!"
96
+ .formatted (query .getQueryString ()));
49
97
}
50
98
51
99
/**
0 commit comments