|
13 | 13 | import org.hibernate.query.spi.QueryOptions; |
14 | 14 | import org.hibernate.sql.ast.tree.expression.JdbcParameter; |
15 | 15 | import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer; |
16 | | -import org.hibernate.type.descriptor.java.JavaType; |
17 | 16 |
|
18 | 17 | /** |
19 | 18 | * Executable JDBC command |
@@ -97,52 +96,43 @@ public JdbcLockStrategy getLockStrategy() { |
97 | 96 |
|
98 | 97 | @Override |
99 | 98 | public boolean isCompatibleWith(JdbcParameterBindings jdbcParameterBindings, QueryOptions queryOptions) { |
100 | | - if ( !appliedParameters.isEmpty() ) { |
101 | | - if ( jdbcParameterBindings == null ) { |
102 | | - return false; |
103 | | - } |
104 | | - for ( Map.Entry<JdbcParameter, JdbcParameterBinding> entry : appliedParameters.entrySet() ) { |
105 | | - final JdbcParameter parameter = entry.getKey(); |
106 | | - final JdbcParameterBinding appliedBinding = entry.getValue(); |
107 | | - // This is a special case where the rendered SQL depends on the presence of the parameter, |
108 | | - // but not specifically on the value. In this case we have to re-generate the SQL if we can't find a binding |
109 | | - // The need for this can be tested with the OracleFollowOnLockingTest#testPessimisticLockWithMaxResultsThenNoFollowOnLocking |
110 | | - // Since the Limit is not part of the query plan cache key, but this has an effect on follow on locking, |
111 | | - // we must treat the absence of Limit parameters, when they were considered for locking, as incompatible |
112 | | - if ( appliedBinding == null ) { |
113 | | - if ( parameter == offsetParameter ) { |
114 | | - if ( queryOptions.getLimit() == null || queryOptions.getLimit().getFirstRowJpa() == 0 ) { |
115 | | - return false; |
116 | | - } |
117 | | - } |
118 | | - else if ( parameter == limitParameter ) { |
119 | | - if ( queryOptions.getLimit() == null || queryOptions.getLimit().getMaxRowsJpa() == Integer.MAX_VALUE ) { |
120 | | - return false; |
121 | | - } |
122 | | - } |
123 | | - else if ( jdbcParameterBindings.getBinding( parameter ) == null ) { |
124 | | - return false; |
125 | | - } |
126 | | - } |
127 | | - // We handle limit and offset parameters below |
128 | | - if ( parameter != offsetParameter && parameter != limitParameter ) { |
129 | | - final JdbcParameterBinding binding = jdbcParameterBindings.getBinding( parameter ); |
130 | | - // TODO: appliedBinding can be null here, resulting in NPE |
131 | | - if ( binding == null || !areEqualBindings( appliedBinding, binding ) ) { |
132 | | - return false; |
133 | | - } |
134 | | - } |
135 | | - } |
| 99 | + if ( !super.isCompatibleWith( jdbcParameterBindings, queryOptions ) ) { |
| 100 | + return false; |
136 | 101 | } |
137 | 102 | final Limit limit = queryOptions.getLimit(); |
138 | 103 | return ( offsetParameter != null || limitParameter != null || limit == null || limit.isEmpty() ) |
139 | 104 | && isCompatible( offsetParameter, limit == null ? null : limit.getFirstRow(), 0 ) |
140 | 105 | && isCompatible( limitParameter, limit == null ? null : limit.getMaxRows(), Integer.MAX_VALUE ); |
141 | 106 | } |
142 | 107 |
|
143 | | - private static boolean areEqualBindings(JdbcParameterBinding appliedBinding, JdbcParameterBinding binding) { |
144 | | - final JavaType<Object> javaTypeDescriptor = appliedBinding.getBindType().getJavaTypeDescriptor(); |
145 | | - return javaTypeDescriptor.areEqual( binding.getBindValue(), appliedBinding.getBindValue() ); |
| 108 | + @Override |
| 109 | + protected boolean isCompatible( |
| 110 | + JdbcParameter parameter, |
| 111 | + JdbcParameterBinding appliedBinding, |
| 112 | + JdbcParameterBinding binding, |
| 113 | + QueryOptions queryOptions) { |
| 114 | + // This is a special case where the rendered SQL depends on the presence of the parameter, |
| 115 | + // but not specifically on the value. In this case we have to re-generate the SQL if we can't find a binding |
| 116 | + // The need for this can be tested with the OracleFollowOnLockingTest#testPessimisticLockWithMaxResultsThenNoFollowOnLocking |
| 117 | + // Since the Limit is not part of the query plan cache key, but this has an effect on follow on locking, |
| 118 | + // we must treat the absence of Limit parameters, when they were considered for locking, as incompatible. |
| 119 | + if ( appliedBinding == null ) { |
| 120 | + if ( parameter == offsetParameter ) { |
| 121 | + if ( queryOptions.getLimit() == null || queryOptions.getLimit().getFirstRowJpa() == 0 ) { |
| 122 | + return false; |
| 123 | + } |
| 124 | + } |
| 125 | + else if ( parameter == limitParameter ) { |
| 126 | + if ( queryOptions.getLimit() == null || queryOptions.getLimit().getMaxRowsJpa() == Integer.MAX_VALUE ) { |
| 127 | + return false; |
| 128 | + } |
| 129 | + } |
| 130 | + } |
| 131 | + // We handle limit and offset parameters in isCompatibleWith |
| 132 | + if ( parameter != offsetParameter && parameter != limitParameter ) { |
| 133 | + return super.isCompatible( parameter, appliedBinding, binding, queryOptions ); |
| 134 | + } |
| 135 | + return true; |
146 | 136 | } |
147 | 137 |
|
148 | 138 | private boolean isCompatible(JdbcParameter parameter, Integer requestedValue, int defaultValue) { |
|
0 commit comments