Skip to content

Commit

Permalink
Add query plan cache statistics for native queries and implement prop…
Browse files Browse the repository at this point in the history
…er caching
  • Loading branch information
beikov committed Dec 23, 2021
1 parent 1184a59 commit 3ea5a06
Show file tree
Hide file tree
Showing 49 changed files with 1,504 additions and 265 deletions.
Expand Up @@ -113,4 +113,36 @@ public JavaType<O> getDomainJavaTypeDescriptor() {
public JavaType<R> getRelationalJavaTypeDescriptor() {
return jdbcJtd;
}

@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}

JpaAttributeConverterImpl<?, ?> that = (JpaAttributeConverterImpl<?, ?>) o;

if ( !attributeConverterBean.equals( that.attributeConverterBean ) ) {
return false;
}
if ( !converterJtd.equals( that.converterJtd ) ) {
return false;
}
if ( !domainJtd.equals( that.domainJtd ) ) {
return false;
}
return jdbcJtd.equals( that.jdbcJtd );
}

@Override
public int hashCode() {
int result = attributeConverterBean.hashCode();
result = 31 * result + converterJtd.hashCode();
result = 31 * result + domainJtd.hashCode();
result = 31 * result + jdbcJtd.hashCode();
return result;
}
}
Expand Up @@ -60,6 +60,7 @@
import org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.DynamicModelJtd;
import org.hibernate.type.descriptor.java.spi.EntityJavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;

/**
Expand Down Expand Up @@ -195,7 +196,7 @@ public <X> EntityDomainType<X> entity(Class<X> cls) {
@Override
public <X> EmbeddableDomainType<X> embeddable(Class<X> cls) {
final ManagedType<?> type = jpaManagedTypeMap.get( cls );
if ( !( type instanceof EntityDomainType<?> ) ) {
if ( !( type instanceof EmbeddableDomainType<?> ) ) {
throw new IllegalArgumentException( "Not an embeddable: " + cls.getName() );
}
//noinspection unchecked
Expand Down Expand Up @@ -503,21 +504,26 @@ public void processJpa(
if ( embeddable.getJavaType() != null && embeddable.getJavaType() != Map.class ) {
this.jpaEmbeddables.add( embeddable );
this.jpaManagedTypes.add( embeddable );
this.jpaManagedTypeMap.put( embeddable.getJavaType(), embeddable );
if ( !( embeddable.getExpressableJavaTypeDescriptor() instanceof EntityJavaTypeDescriptor<?> ) ) {
this.jpaManagedTypeMap.put( embeddable.getJavaType(), embeddable );
}
}
break;
case ENABLED:
this.jpaEmbeddables.add( embeddable );
this.jpaManagedTypes.add( embeddable );
if ( embeddable.getJavaType() != null ) {
if ( embeddable.getJavaType() != null
&& !( embeddable.getExpressableJavaTypeDescriptor() instanceof EntityJavaTypeDescriptor<?> ) ) {
this.jpaManagedTypeMap.put( embeddable.getJavaType(), embeddable );
}
break;
case DISABLED:
if ( embeddable.getJavaType() == null ) {
throw new UnsupportedOperationException( "ANY not supported" );
}
this.jpaManagedTypeMap.put( embeddable.getJavaType(), embeddable );
if ( !( embeddable.getExpressableJavaTypeDescriptor() instanceof EntityJavaTypeDescriptor<?> ) ) {
this.jpaManagedTypeMap.put( embeddable.getJavaType(), embeddable );
}
break;
}
}
Expand Down
Expand Up @@ -50,6 +50,11 @@ public Class<?> getJavaType() {
return entityDescriptor.getJavaTypeDescriptor().getJavaTypeClass();
}

@Override
public ResultBuilder cacheKeyInstance() {
return this;
}

@Override
public EntityResult buildResult(
JdbcValuesMetadata jdbcResultsMetadata,
Expand Down Expand Up @@ -77,4 +82,22 @@ public EntityResult buildResult(
domainResultCreationState
);
}

@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}

final EntityDomainResultBuilder that = (EntityDomainResultBuilder) o;
return entityDescriptor.equals( that.entityDescriptor );
}

@Override
public int hashCode() {
return entityDescriptor.hashCode();
}
}
Expand Up @@ -39,4 +39,28 @@ public DomainResult<T> buildResult(
DomainResultCreationState domainResultCreationState) {
return new BasicResult<>( resultPosition, null, typeDescriptor );
}

@Override
public ResultBuilder cacheKeyInstance() {
return this;
}

@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}

ScalarDomainResultBuilder<?> that = (ScalarDomainResultBuilder<?>) o;

return typeDescriptor.equals( that.typeDescriptor );
}

@Override
public int hashCode() {
return typeDescriptor.hashCode();
}
}
Expand Up @@ -47,7 +47,11 @@ public int getNumberOfCachedQueryPlans() {

@Override
public <R> SelectQueryPlan<R> resolveSelectQueryPlan(Key key, Supplier<SelectQueryPlan<R>> creator) {
return null;
final StatisticsImplementor statistics = statisticsSupplier.get();
if ( statistics.isStatisticsEnabled() ) {
statistics.queryPlanCacheMiss( key.getQueryString() );
}
return creator.get();
}

@Override
Expand All @@ -61,7 +65,7 @@ public void cacheNonSelectQueryPlan(Key key, NonSelectQueryPlan plan) {

@Override
public HqlInterpretation resolveHqlInterpretation(String queryString, Function<String, SqmStatement<?>> creator) {
StatisticsImplementor statistics = statisticsSupplier.get();
final StatisticsImplementor statistics = statisticsSupplier.get();
final boolean stats = statistics.isStatisticsEnabled();
final long startTime = ( stats ) ? System.nanoTime() : 0L;
final SqmStatement<?> sqmStatement = creator.apply( queryString );
Expand All @@ -76,7 +80,6 @@ public HqlInterpretation resolveHqlInterpretation(String queryString, Function<S
else {
domainParameterXref = DomainParameterXref.from( sqmStatement );
parameterMetadata = new ParameterMetadataImpl( domainParameterXref.getQueryParameters() );

}

if ( stats ) {
Expand Down
Expand Up @@ -80,15 +80,23 @@ public <R> SelectQueryPlan<R> resolveSelectQueryPlan(
Key key,
Supplier<SelectQueryPlan<R>> creator) {
log.tracef( "QueryPlan#getSelectQueryPlan(%s)", key );
final StatisticsImplementor statistics = statisticsSupplier.get();
final boolean stats = statistics.isStatisticsEnabled();

@SuppressWarnings("unchecked")
final SelectQueryPlan<R> cached = (SelectQueryPlan<R>) queryPlanCache.get( key );
if ( cached != null ) {
if ( stats ) {
statistics.queryPlanCacheHit( key.getQueryString() );
}
return cached;
}

final SelectQueryPlan<R> plan = creator.get();
queryPlanCache.put( key.prepareForStore(), plan );
if ( stats ) {
statistics.queryPlanCacheMiss( key.getQueryString() );
}
return plan;
}

Expand Down
Expand Up @@ -6,14 +6,15 @@
*/
package org.hibernate.query.results;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.metamodel.EntityType;
import jakarta.persistence.metamodel.SingularAttribute;

import org.hibernate.LockMode;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.RuntimeMetamodels;
import org.hibernate.metamodel.mapping.AttributeMapping;
Expand All @@ -38,6 +39,7 @@
import org.hibernate.query.results.implicit.ImplicitFetchBuilderBasic;
import org.hibernate.query.results.implicit.ImplicitFetchBuilderEmbeddable;
import org.hibernate.query.results.implicit.ImplicitFetchBuilderEntity;
import org.hibernate.query.results.implicit.ImplicitFetchBuilderEntityPart;
import org.hibernate.query.results.implicit.ImplicitFetchBuilderPlural;
import org.hibernate.query.results.implicit.ImplicitModelPartResultBuilderEntity;
import org.hibernate.sql.results.graph.DomainResultCreationState;
Expand Down Expand Up @@ -236,7 +238,7 @@ public static DynamicResultBuilderEntityCalculated entityCalculated(
}

public static DynamicFetchBuilderLegacy fetch(String tableAlias, String ownerTableAlias, String joinPropertyName) {
return new DynamicFetchBuilderLegacy( tableAlias, ownerTableAlias, joinPropertyName, null, null );
return new DynamicFetchBuilderLegacy( tableAlias, ownerTableAlias, joinPropertyName, new ArrayList<>(), new HashMap<>() );
}

public static ResultBuilder implicitEntityResultBuilder(
Expand Down Expand Up @@ -273,15 +275,7 @@ public static ImplicitFetchBuilder implicitFetchBuilder(
}

if ( fetchable instanceof EntityCollectionPart ) {
final EntityCollectionPart entityCollectionPart = (EntityCollectionPart) fetchable;
return (parent, fetchablePath, jdbcResultsMetadata, legacyFetchResolver, domainResultCreationState) -> parent.generateFetchableFetch(
entityCollectionPart,
fetchablePath,
FetchTiming.IMMEDIATE,
true,
null,
domainResultCreationState
);
return new ImplicitFetchBuilderEntityPart( fetchPath, (EntityCollectionPart) fetchable );
}

throw new UnsupportedOperationException();
Expand Down
Expand Up @@ -35,4 +35,6 @@ Fetch buildFetch(

default void visitFetchBuilders(BiConsumer<String, FetchBuilder> consumer) {
}

FetchBuilder cacheKeyInstance();
}
Expand Up @@ -32,6 +32,11 @@ public ImplicitAttributeFetchBuilder(NavigablePath navigablePath, AttributeMappi
this.attributeMapping = attributeMapping;
}

@Override
public FetchBuilder cacheKeyInstance() {
return this;
}

@Override
public Fetch buildFetch(
FetchParent parent,
Expand All @@ -50,4 +55,25 @@ public Fetch buildFetch(
domainResultCreationState
);
}

@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}

final ImplicitAttributeFetchBuilder that = (ImplicitAttributeFetchBuilder) o;
return navigablePath.equals( that.navigablePath )
&& attributeMapping.equals( that.attributeMapping );
}

@Override
public int hashCode() {
int result = navigablePath.hashCode();
result = 31 * result + attributeMapping.hashCode();
return result;
}
}
Expand Up @@ -31,6 +31,8 @@ DomainResult<?> buildResult(

Class<?> getJavaType();

ResultBuilder cacheKeyInstance();

default void visitFetchBuilders(BiConsumer<String, FetchBuilder> consumer) {
}
}

0 comments on commit 3ea5a06

Please sign in to comment.