Copy DomainParameterXref on demand instead of recreating to avoid instance mismatch with ParameterMetadata
This commit is contained in:
parent
1e823386f6
commit
de0dd8cda3
|
@ -39,7 +39,7 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation
|
||||||
*/
|
*/
|
||||||
private final BoundedConcurrentHashMap<Key, QueryPlan> queryPlanCache;
|
private final BoundedConcurrentHashMap<Key, QueryPlan> queryPlanCache;
|
||||||
|
|
||||||
private final BoundedConcurrentHashMap<String, ImmutableHqlInterpretation> hqlInterpretationCache;
|
private final BoundedConcurrentHashMap<String, HqlInterpretation> hqlInterpretationCache;
|
||||||
private final BoundedConcurrentHashMap<String, ParameterInterpretation> nativeQueryParamCache;
|
private final BoundedConcurrentHashMap<String, ParameterInterpretation> nativeQueryParamCache;
|
||||||
private final Supplier<StatisticsImplementor> statisticsSupplier;
|
private final Supplier<StatisticsImplementor> statisticsSupplier;
|
||||||
|
|
||||||
|
@ -108,8 +108,8 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation
|
||||||
final long startTime = ( stats ) ? System.nanoTime() : 0L;
|
final long startTime = ( stats ) ? System.nanoTime() : 0L;
|
||||||
|
|
||||||
final DomainParameterXref domainParameterXref;
|
final DomainParameterXref domainParameterXref;
|
||||||
ImmutableHqlInterpretation immutableHqlInterpretation = hqlInterpretationCache.get( queryString );
|
HqlInterpretation hqlInterpretation = hqlInterpretationCache.get( queryString );
|
||||||
if ( immutableHqlInterpretation == null ) {
|
if ( hqlInterpretation == null ) {
|
||||||
log.debugf( "Creating and caching HqlInterpretation - %s", queryString );
|
log.debugf( "Creating and caching HqlInterpretation - %s", queryString );
|
||||||
final SqmStatement<?> sqmStatement = creator.apply( queryString );
|
final SqmStatement<?> sqmStatement = creator.apply( queryString );
|
||||||
final ParameterMetadataImplementor parameterMetadata;
|
final ParameterMetadataImplementor parameterMetadata;
|
||||||
|
@ -123,8 +123,8 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation
|
||||||
parameterMetadata = new ParameterMetadataImpl( domainParameterXref.getQueryParameters() );
|
parameterMetadata = new ParameterMetadataImpl( domainParameterXref.getQueryParameters() );
|
||||||
}
|
}
|
||||||
|
|
||||||
immutableHqlInterpretation = new ImmutableHqlInterpretation( sqmStatement, parameterMetadata);
|
hqlInterpretation = new SimpleHqlInterpretationImpl( sqmStatement, parameterMetadata, domainParameterXref );
|
||||||
hqlInterpretationCache.put( queryString, immutableHqlInterpretation );
|
hqlInterpretationCache.put( queryString, hqlInterpretation );
|
||||||
|
|
||||||
if ( stats ) {
|
if ( stats ) {
|
||||||
final long endTime = System.nanoTime();
|
final long endTime = System.nanoTime();
|
||||||
|
@ -136,19 +136,9 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation
|
||||||
if ( stats ) {
|
if ( stats ) {
|
||||||
statistics.queryPlanCacheHit( queryString );
|
statistics.queryPlanCacheHit( queryString );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( immutableHqlInterpretation.sqmStatement.getSqmParameters().isEmpty() ) {
|
|
||||||
domainParameterXref = DomainParameterXref.empty();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
domainParameterXref = DomainParameterXref.from( immutableHqlInterpretation.sqmStatement );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SimpleHqlInterpretationImpl(
|
return hqlInterpretation;
|
||||||
immutableHqlInterpretation.sqmStatement,
|
|
||||||
immutableHqlInterpretation.parameterMetadata,
|
|
||||||
domainParameterXref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -179,16 +169,4 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation
|
||||||
queryPlanCache.clear();
|
queryPlanCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ImmutableHqlInterpretation {
|
|
||||||
|
|
||||||
private final SqmStatement<?> sqmStatement;
|
|
||||||
private final ParameterMetadataImplementor parameterMetadata;
|
|
||||||
|
|
||||||
public ImmutableHqlInterpretation(
|
|
||||||
SqmStatement<?> sqmStatement,
|
|
||||||
ParameterMetadataImplementor parameterMetadata) {
|
|
||||||
this.sqmStatement = sqmStatement;
|
|
||||||
this.parameterMetadata = parameterMetadata;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,6 @@ public class SimpleHqlInterpretationImpl implements HqlInterpretation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DomainParameterXref getDomainParameterXref() {
|
public DomainParameterXref getDomainParameterXref() {
|
||||||
return domainParameterXref;
|
return domainParameterXref.copy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,6 +163,14 @@ public class DomainParameterXref {
|
||||||
this.parameterResolutions = parameterResolutions;
|
this.parameterResolutions = parameterResolutions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DomainParameterXref copy() {
|
||||||
|
return new DomainParameterXref(
|
||||||
|
sqmParamsByQueryParam,
|
||||||
|
new IdentityHashMap<>( queryParamBySqmParam ),
|
||||||
|
parameterResolutions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does this xref contain any parameters?
|
* Does this xref contain any parameters?
|
||||||
*/
|
*/
|
||||||
|
@ -256,5 +264,4 @@ public class DomainParameterXref {
|
||||||
|
|
||||||
expansions.clear();
|
expansions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,16 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.orm.test.query.sqm.exec;
|
package org.hibernate.orm.test.query.sqm.exec;
|
||||||
|
|
||||||
|
import org.hibernate.query.spi.QueryImplementor;
|
||||||
|
import org.hibernate.query.spi.QueryParameterImplementor;
|
||||||
|
import org.hibernate.query.sqm.internal.DomainParameterXref;
|
||||||
|
import org.hibernate.query.sqm.internal.QuerySqmImpl;
|
||||||
|
|
||||||
import org.hibernate.testing.orm.domain.StandardDomainModel;
|
import org.hibernate.testing.orm.domain.StandardDomainModel;
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,4 +45,27 @@ public class ParameterTest {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParametersWithQueryInterpretationCache(SessionFactoryScope scope) {
|
||||||
|
String query = "from SalesAssociate p where p.name.familiarName in :names";
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
QueryImplementor q = session.createQuery( query );
|
||||||
|
DomainParameterXref xref = q.unwrap( QuerySqmImpl.class ).getDomainParameterXref();
|
||||||
|
for ( QueryParameterImplementor<?> p : xref.getQueryParameters().keySet() ) {
|
||||||
|
Assertions.assertTrue( q.getParameterMetadata().containsReference( p ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
QueryImplementor q = session.createQuery( query );
|
||||||
|
DomainParameterXref xref = q.unwrap( QuerySqmImpl.class ).getDomainParameterXref();
|
||||||
|
for ( QueryParameterImplementor<?> p : xref.getQueryParameters().keySet() ) {
|
||||||
|
Assertions.assertTrue( q.getParameterMetadata().containsReference( p ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue