Skip to content

Commit cea044e

Browse files
vladmihalceabeikov
authored andcommitted
HHH-14632 - Call statistics.queryPlanCacheHit and statistics.queryPlanCacheMiss for FilterQueryPlan and NativeSQLQueryPlan
1 parent 7570f39 commit cea044e

5 files changed

Lines changed: 99 additions & 9 deletions

File tree

hibernate-core/src/main/java/org/hibernate/engine/query/spi/QueryPlanCache.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,17 +200,26 @@ public FilterQueryPlan getFilterQueryPlan(
200200
Map<String,Filter> enabledFilters) throws QueryException, MappingException {
201201
final FilterQueryPlanKey key = new FilterQueryPlanKey( filterString, collectionRole, shallow, enabledFilters );
202202
FilterQueryPlan value = (FilterQueryPlan) queryPlanCache.get( key );
203+
final StatisticsImplementor statistics = factory.getStatistics();
204+
boolean stats = statistics.isStatisticsEnabled();
203205
if ( value == null ) {
204206
LOG.tracev(
205207
"Unable to locate collection-filter query plan in cache; generating ({0} : {1} )",
206208
collectionRole,
207209
filterString
208210
);
209211
value = new FilterQueryPlan( filterString, collectionRole, shallow, enabledFilters,factory );
212+
if ( stats ) {
213+
statistics.queryPlanCacheMiss( key.query );
214+
}
210215
queryPlanCache.putIfAbsent( key, value );
211216
}
212217
else {
213218
LOG.tracev( "Located collection-filter query plan in cache ({0} : {1})", collectionRole, filterString );
219+
220+
if ( stats ) {
221+
statistics.queryPlanCacheHit( key.query );
222+
}
214223
}
215224
return value;
216225
}
@@ -228,13 +237,22 @@ public FilterQueryPlan getFilterQueryPlan(
228237
@SuppressWarnings("unchecked")
229238
public NativeSQLQueryPlan getNativeSQLQueryPlan(final NativeSQLQuerySpecification spec) {
230239
NativeSQLQueryPlan value = (NativeSQLQueryPlan) queryPlanCache.get( spec );
240+
final StatisticsImplementor statistics = factory.getStatistics();
241+
boolean stats = statistics.isStatisticsEnabled();
231242
if ( value == null ) {
232243
LOG.tracev( "Unable to locate native-sql query plan in cache; generating ({0})", spec.getQueryString() );
233244
value = nativeQueryInterpreter.createQueryPlan( spec, factory );
245+
if ( stats ) {
246+
statistics.queryPlanCacheMiss( spec.getQueryString() );
247+
}
234248
queryPlanCache.putIfAbsent( spec, value );
235249
}
236250
else {
237251
LOG.tracev( "Located native-sql query plan in cache ({0})", spec.getQueryString() );
252+
253+
if ( stats ) {
254+
statistics.queryPlanCacheHit( spec.getQueryString() );
255+
}
238256
}
239257
return value;
240258
}

hibernate-core/src/main/java/org/hibernate/stat/internal/QueryStatisticsImpl.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,10 @@ void incrementPlanCacheHitCount() {
202202
planCacheHitCount.increment();
203203
}
204204

205+
void incrementPlanCacheMissCount() {
206+
planCacheMissCount.increment();
207+
}
208+
205209
public String toString() {
206210
return "QueryStatistics"
207211
+ "[query=" + query

hibernate-core/src/main/java/org/hibernate/stat/internal/StatisticsImpl.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -805,11 +805,20 @@ public void queryCompiled(String hql, long microseconds) {
805805
}
806806

807807
@Override
808-
public void queryPlanCacheHit(String hql) {
808+
public void queryPlanCacheHit(String query) {
809809
queryPlanCacheHitCount.increment();
810810

811-
if ( hql != null ) {
812-
getQueryStatistics( hql ).incrementPlanCacheHitCount();
811+
if ( query != null ) {
812+
getQueryStatistics( query ).incrementPlanCacheHitCount();
813+
}
814+
}
815+
816+
@Override
817+
public void queryPlanCacheMiss(String query) {
818+
queryPlanCacheMissCount.increment();
819+
820+
if ( query != null ) {
821+
getQueryStatistics( query ).incrementPlanCacheMissCount();
813822
}
814823
}
815824

hibernate-core/src/main/java/org/hibernate/stat/spi/StatisticsImplementor.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,18 @@ public interface StatisticsImplementor extends Statistics, Service {
251251
/**
252252
* Callback indicating a get from the query plan cache resulted in a hit.
253253
*
254-
* @param hql The query
254+
* @param query The query
255+
*/
256+
default void queryPlanCacheHit(String query) {
257+
//For backward compatibility
258+
}
259+
260+
/**
261+
* Callback indicating a get from the query plan cache resulted in a miss.
262+
*
263+
* @param query The query
255264
*/
256-
default void queryPlanCacheHit(String hql) {
265+
default void queryPlanCacheMiss(String query) {
257266
//For backward compatibility
258267
}
259268

hibernate-core/src/test/java/org/hibernate/stat/internal/QueryPlanCacheStatisticsTest.java

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import javax.persistence.Id;
1515
import javax.persistence.LockModeType;
1616
import javax.persistence.NamedQuery;
17+
import javax.persistence.Table;
1718
import javax.persistence.Tuple;
1819
import javax.persistence.TypedQuery;
1920

@@ -150,7 +151,7 @@ public void testCreateQueryHitCount() {
150151

151152
assertEquals( 5, employees.size() );
152153

153-
//The miss count is still 1, as no we got the query plan from the cache
154+
//The miss count is still 1, as now we got the query plan from the cache
154155
assertEquals( 1, statistics.getQueryPlanCacheMissCount() );
155156
//And the cache hit count increases.
156157
assertEquals( 1, statistics.getQueryPlanCacheHitCount() );
@@ -164,7 +165,55 @@ public void testCreateQueryHitCount() {
164165

165166
assertEquals( 5, employees.size() );
166167

167-
//The miss count is still 1, as no we got the query plan from the cache
168+
//The miss count is still 1, as now we got the query plan from the cache
169+
assertEquals( 1, statistics.getQueryPlanCacheMissCount() );
170+
//And the cache hit count increases.
171+
assertEquals( 2, statistics.getQueryPlanCacheHitCount() );
172+
} );
173+
}
174+
175+
@Test
176+
@TestForIssue( jiraKey = "HHH-14632" )
177+
public void testCreateNativeQueryHitCount() {
178+
statistics.clear();
179+
180+
doInJPA( this::entityManagerFactory, entityManager -> {
181+
182+
List<Employee> employees = entityManager.createNativeQuery(
183+
"select * from employee e", Employee.class )
184+
.getResultList();
185+
186+
assertEquals( 5, employees.size() );
187+
188+
//First time, we get a cache miss, so the query is compiled
189+
assertEquals( 1, statistics.getQueryPlanCacheMissCount() );
190+
//The hit count should be 0 as we don't need to go to the cache after we already compiled the query
191+
assertEquals( 0, statistics.getQueryPlanCacheHitCount() );
192+
} );
193+
194+
doInJPA( this::entityManagerFactory, entityManager -> {
195+
196+
List<Employee> employees = entityManager.createNativeQuery(
197+
"select * from employee e", Employee.class )
198+
.getResultList();
199+
200+
assertEquals( 5, employees.size() );
201+
202+
//The miss count is still 1, as now we got the query plan from the cache
203+
assertEquals( 1, statistics.getQueryPlanCacheMissCount() );
204+
//And the cache hit count increases.
205+
assertEquals( 1, statistics.getQueryPlanCacheHitCount() );
206+
} );
207+
208+
doInJPA( this::entityManagerFactory, entityManager -> {
209+
210+
List<Employee> employees = entityManager.createNativeQuery(
211+
"select * from employee e", Employee.class )
212+
.getResultList();
213+
214+
assertEquals( 5, employees.size() );
215+
216+
//The miss count is still 1, as now we got the query plan from the cache
168217
assertEquals( 1, statistics.getQueryPlanCacheMissCount() );
169218
//And the cache hit count increases.
170219
assertEquals( 2, statistics.getQueryPlanCacheHitCount() );
@@ -232,7 +281,7 @@ public void testCreateQueryTupleHitCount() {
232281

233282
assertEquals( 5, employees.size() );
234283

235-
//The miss count is still 1, as no we got the query plan from the cache
284+
//The miss count is still 1, as now we got the query plan from the cache
236285
assertEquals( 1, statistics.getQueryPlanCacheMissCount() );
237286
//And the cache hit count increases.
238287
assertEquals( 1, statistics.getQueryPlanCacheHitCount() );
@@ -246,7 +295,7 @@ public void testCreateQueryTupleHitCount() {
246295

247296
assertEquals( 5, employees.size() );
248297

249-
//The miss count is still 1, as no we got the query plan from the cache
298+
//The miss count is still 1, as now we got the query plan from the cache
250299
assertEquals( 1, statistics.getQueryPlanCacheMissCount() );
251300
//And the cache hit count increases.
252301
assertEquals( 2, statistics.getQueryPlanCacheHitCount() );
@@ -292,6 +341,7 @@ private void assertQueryStatistics(String hql, int hitCount) {
292341
}
293342

294343
@Entity(name = "Employee")
344+
@Table(name = "employee")
295345
@NamedQuery(
296346
name = "find_employee_by_name",
297347
query = "select e from Employee e where e.name = :name"

0 commit comments

Comments
 (0)