HHH-11374 - ConcurrentStatisticsImpl#getSecondLevelCacheStatistics() throws NPE if second level cache is not activated

This commit is contained in:
Andrea Boriero 2017-05-03 10:56:52 +01:00 committed by Vlad Mihalcea
parent 5a7526b484
commit 93559d2e60
3 changed files with 152 additions and 56 deletions

View File

@ -17,7 +17,7 @@ public interface Statistics {
/**
* reset all statistics
*/
public void clear();
void clear();
/**
* find entity statistics per name
@ -25,22 +25,26 @@ public interface Statistics {
* @param entityName entity name
* @return EntityStatistics object
*/
public EntityStatistics getEntityStatistics(String entityName);
EntityStatistics getEntityStatistics(String entityName);
/**
* Get collection statistics per role
*
* @param role collection role
* @return CollectionStatistics
*/
public CollectionStatistics getCollectionStatistics(String role);
CollectionStatistics getCollectionStatistics(String role);
/**
/**
* Second level cache statistics per region
*
*
* @param regionName region name
* @return SecondLevelCacheStatistics
*
* @return SecondLevelCacheStatistics or {@code null} if the second level cache is not enabled
*
* @throws IllegalArgumentException if the region name could not be resolved
*/
public SecondLevelCacheStatistics getSecondLevelCacheStatistics(String regionName);
SecondLevelCacheStatistics getSecondLevelCacheStatistics(String regionName);
/**
* Natural id cache statistics per region
@ -48,7 +52,7 @@ public interface Statistics {
* @param regionName region name
* @return NaturalIdCacheStatistics
*/
public NaturalIdCacheStatistics getNaturalIdCacheStatistics(String regionName);
NaturalIdCacheStatistics getNaturalIdCacheStatistics(String regionName);
/**
* Query statistics from query string (HQL or SQL)
@ -56,203 +60,240 @@ public interface Statistics {
* @param queryString query string
* @return QueryStatistics
*/
public QueryStatistics getQueryStatistics(String queryString);
QueryStatistics getQueryStatistics(String queryString);
/**
* Get global number of entity deletes
* @return entity deletion count
*/
public long getEntityDeleteCount();
long getEntityDeleteCount();
/**
* Get global number of entity inserts
* @return entity insertion count
*/
public long getEntityInsertCount();
long getEntityInsertCount();
/**
* Get global number of entity loads
* @return entity load (from DB)
*/
public long getEntityLoadCount();
long getEntityLoadCount();
/**
* Get global number of entity fetchs
* @return entity fetch (from DB)
*/
public long getEntityFetchCount();
long getEntityFetchCount();
/**
* Get global number of entity updates
* @return entity update
*/
public long getEntityUpdateCount();
long getEntityUpdateCount();
/**
* Get global number of executed queries
* @return query execution count
*/
public long getQueryExecutionCount();
long getQueryExecutionCount();
/**
* Get the time in milliseconds of the slowest query.
*/
public long getQueryExecutionMaxTime();
long getQueryExecutionMaxTime();
/**
* Get the query string for the slowest query.
*/
public String getQueryExecutionMaxTimeQueryString();
String getQueryExecutionMaxTimeQueryString();
/**
* Get the global number of cached queries successfully retrieved from cache
*/
public long getQueryCacheHitCount();
long getQueryCacheHitCount();
/**
* Get the global number of cached queries *not* found in cache
*/
public long getQueryCacheMissCount();
long getQueryCacheMissCount();
/**
* Get the global number of cacheable queries put in cache
*/
public long getQueryCachePutCount();
long getQueryCachePutCount();
/**
* Get the global number of naturalId queries executed against the database
*/
public long getNaturalIdQueryExecutionCount();
long getNaturalIdQueryExecutionCount();
/**
* Get the global maximum query time for naturalId queries executed against the database
*/
public long getNaturalIdQueryExecutionMaxTime();
long getNaturalIdQueryExecutionMaxTime();
/**
* Get the region for the maximum naturalId query time
*/
public String getNaturalIdQueryExecutionMaxTimeRegion();
String getNaturalIdQueryExecutionMaxTimeRegion();
/**
* Get the global number of cached naturalId lookups successfully retrieved from cache
*/
public long getNaturalIdCacheHitCount();
long getNaturalIdCacheHitCount();
/**
* Get the global number of cached naturalId lookups *not* found in cache
*/
public long getNaturalIdCacheMissCount();
long getNaturalIdCacheMissCount();
/**
* Get the global number of cacheable naturalId lookups put in cache
*/
public long getNaturalIdCachePutCount();
long getNaturalIdCachePutCount();
/**
* Get the global number of timestamps successfully retrieved from cache
*/
public long getUpdateTimestampsCacheHitCount();
long getUpdateTimestampsCacheHitCount();
/**
* Get the global number of tables for which no update timestamps was *not* found in cache
*/
public long getUpdateTimestampsCacheMissCount();
long getUpdateTimestampsCacheMissCount();
/**
* Get the global number of timestamps put in cache
*/
public long getUpdateTimestampsCachePutCount();
long getUpdateTimestampsCachePutCount();
/**
* Get the global number of flush executed by sessions (either implicit or explicit)
*/
public long getFlushCount();
long getFlushCount();
/**
* Get the global number of connections asked by the sessions
* (the actual number of connections used may be much smaller depending
* whether you use a connection pool or not)
*/
public long getConnectCount();
long getConnectCount();
/**
* Global number of cacheable entities/collections successfully retrieved from the cache
*/
public long getSecondLevelCacheHitCount();
long getSecondLevelCacheHitCount();
/**
* Global number of cacheable entities/collections not found in the cache and loaded from the database.
*/
public long getSecondLevelCacheMissCount();
long getSecondLevelCacheMissCount();
/**
* Global number of cacheable entities/collections put in the cache
*/
public long getSecondLevelCachePutCount();
long getSecondLevelCachePutCount();
/**
* Global number of sessions closed
*/
public long getSessionCloseCount();
long getSessionCloseCount();
/**
* Global number of sessions opened
*/
public long getSessionOpenCount();
long getSessionOpenCount();
/**
* Global number of collections loaded
*/
public long getCollectionLoadCount();
long getCollectionLoadCount();
/**
* Global number of collections fetched
*/
public long getCollectionFetchCount();
long getCollectionFetchCount();
/**
* Global number of collections updated
*/
public long getCollectionUpdateCount();
long getCollectionUpdateCount();
/**
* Global number of collections removed
*/
//even on inverse="true"
public long getCollectionRemoveCount();
long getCollectionRemoveCount();
/**
* Global number of collections recreated
*/
public long getCollectionRecreateCount();
long getCollectionRecreateCount();
/**
* @return start time in ms (JVM standards {@link System#currentTimeMillis()})
*/
public long getStartTime();
long getStartTime();
/**
* log in info level the main statistics
*/
public void logSummary();
void logSummary();
/**
* Are statistics logged
*/
public boolean isStatisticsEnabled();
boolean isStatisticsEnabled();
/**
* Enable statistics logs (this is a dynamic parameter)
*/
public void setStatisticsEnabled(boolean b);
void setStatisticsEnabled(boolean b);
/**
* Get all executed query strings
*/
public String[] getQueries();
String[] getQueries();
/**
* Get the names of all entities
*/
public String[] getEntityNames();
String[] getEntityNames();
/**
* Get the names of all collection roles
*/
public String[] getCollectionRoleNames();
String[] getCollectionRoleNames();
/**
* Get all second-level cache region names
*/
public String[] getSecondLevelCacheRegionNames();
String[] getSecondLevelCacheRegionNames();
/**
* The number of transactions we know to have been successful
*/
public long getSuccessfulTransactionCount();
long getSuccessfulTransactionCount();
/**
* The number of transactions we know to have completed
*/
public long getTransactionCount();
long getTransactionCount();
/**
* The number of prepared statements that were acquired
*/
public long getPrepareStatementCount();
long getPrepareStatementCount();
/**
* The number of prepared statements that were released
*/
public long getCloseStatementCount();
long getCloseStatementCount();
/**
* The number of <tt>StaleObjectStateException</tt>s
* that occurred
*/
public long getOptimisticFailureCount();
long getOptimisticFailureCount();
}

View File

@ -10,6 +10,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import org.hibernate.cache.spi.QueryCache;
import org.hibernate.cache.spi.Region;
import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.spi.access.EntityRegionAccessStrategy;
@ -290,7 +291,9 @@ public class ConcurrentStatisticsImpl implements StatisticsImplementor, Service
*
* @param regionName region name
*
* @return SecondLevelCacheStatistics
* @return SecondLevelCacheStatistics or null if the second level cache is not enabled
*
* @throws IllegalArgumentException if the region name could not be resolved
*/
public ConcurrentSecondLevelCacheStatisticsImpl getSecondLevelCacheStatistics(String regionName) {
ConcurrentSecondLevelCacheStatisticsImpl stat = secondLevelCacheStatistics.get( regionName );
@ -303,7 +306,11 @@ public class ConcurrentStatisticsImpl implements StatisticsImplementor, Service
final CollectionRegionAccessStrategy collectionRegionAccess = sessionFactory.getCache().getCollectionRegionAccess( regionName );
if ( entityRegionAccess == null && collectionRegionAccess == null ) {
final Region region = sessionFactory.getCache().getQueryCache( regionName ).getRegion();
final QueryCache queryCache = sessionFactory.getCache().getQueryCache( regionName );
if ( queryCache == null ) {
return null;
}
final Region region = queryCache.getRegion();
if ( region == null ) {
throw new IllegalArgumentException( "Could not resolve region name [" + regionName + "]" );
}

View File

@ -0,0 +1,48 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.stat.internal;
import org.hibernate.SessionFactory;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.nullValue;
import static org.junit.Assert.assertThat;
/**
* @author Andrea Boriero
*/
public class ConcurrentStatisticsTest extends BaseCoreFunctionalTestCase {
private static final String TRIVIAL_REGION_NAME = "noname";
private ConcurrentStatisticsImpl statistics;
private SessionFactory sessionFactory;
@Before
public void setUp() {
sessionFactory = sessionFactory();
statistics = new ConcurrentStatisticsImpl( (SessionFactoryImplementor) sessionFactory );
}
@After
public void tearDown() {
sessionFactory.close();
}
@Test
public void testThatGetSecondLevelCacheStatisticsWhenSecondLevelCacheIsNotEnabledReturnsNull() {
final ConcurrentSecondLevelCacheStatisticsImpl secondLevelCacheStatistics = statistics
.getSecondLevelCacheStatistics( TRIVIAL_REGION_NAME );
assertThat( secondLevelCacheStatistics, is( nullValue() ) );
}
}