From 9684afda76e9a1d7c700d8cba6a076a546aa9a3c Mon Sep 17 00:00:00 2001 From: Carlos Aristu Date: Fri, 29 Jun 2018 12:15:47 +0200 Subject: [PATCH] HHH-11495 Reduce criteria overhead by adding an implementors cache --- .../metamodel/internal/MetamodelImpl.java | 97 ++++++++++--------- 1 file changed, 52 insertions(+), 45 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetamodelImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetamodelImpl.java index d508418a1e..a397c19227 100755 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetamodelImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetamodelImpl.java @@ -111,6 +111,8 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable { private final TypeConfiguration typeConfiguration; + private final Map implementorsCache = new ConcurrentHashMap<>(); + public MetamodelImpl(SessionFactoryImplementor sessionFactory, TypeConfiguration typeConfiguration) { this.sessionFactory = sessionFactory; this.typeConfiguration = typeConfiguration; @@ -622,51 +624,7 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable { * @throws MappingException */ public String[] getImplementors(String className) throws MappingException { - - final Class clazz; - try { - clazz = getSessionFactory().getServiceRegistry().getService( ClassLoaderService.class ).classForName( className ); - } - catch (ClassLoadingException e) { - return new String[] { className }; //for a dynamic-class - } - - ArrayList results = new ArrayList<>(); - for ( EntityPersister checkPersister : entityPersisters().values() ) { - if ( ! Queryable.class.isInstance( checkPersister ) ) { - continue; - } - final Queryable checkQueryable = Queryable.class.cast( checkPersister ); - final String checkQueryableEntityName = checkQueryable.getEntityName(); - final boolean isMappedClass = className.equals( checkQueryableEntityName ); - if ( checkQueryable.isExplicitPolymorphism() ) { - if ( isMappedClass ) { - return new String[] { className }; //NOTE EARLY EXIT - } - } - else { - if ( isMappedClass ) { - results.add( checkQueryableEntityName ); - } - else { - final Class mappedClass = checkQueryable.getMappedClass(); - if ( mappedClass != null && clazz.isAssignableFrom( mappedClass ) ) { - final boolean assignableSuperclass; - if ( checkQueryable.isInherited() ) { - Class mappedSuperclass = entityPersister( checkQueryable.getMappedSuperclass() ).getMappedClass(); - assignableSuperclass = clazz.isAssignableFrom( mappedSuperclass ); - } - else { - assignableSuperclass = false; - } - if ( !assignableSuperclass ) { - results.add( checkQueryableEntityName ); - } - } - } - } - } - return results.toArray( new String[results.size()] ); + return implementorsCache.computeIfAbsent( className, this::doGetImplementors ); } @Override @@ -789,4 +747,53 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable { public void close() { // anything to do ? } + + private String[] doGetImplementors(String className) throws MappingException { + final Class clazz; + + try { + clazz = getSessionFactory().getServiceRegistry().getService( ClassLoaderService.class ).classForName( className ); + } + catch (ClassLoadingException e) { + return new String[]{ className }; //for a dynamic-class + } + + ArrayList results = new ArrayList<>(); + for ( EntityPersister checkPersister : entityPersisters().values() ) { + if ( !Queryable.class.isInstance( checkPersister ) ) { + continue; + } + final Queryable checkQueryable = Queryable.class.cast( checkPersister ); + final String checkQueryableEntityName = checkQueryable.getEntityName(); + final boolean isMappedClass = className.equals( checkQueryableEntityName ); + if ( checkQueryable.isExplicitPolymorphism() ) { + if ( isMappedClass ) { + return new String[]{ className }; // NOTE EARLY EXIT + } + } + else { + if ( isMappedClass ) { + results.add( checkQueryableEntityName ); + } + else { + final Class mappedClass = checkQueryable.getMappedClass(); + if ( mappedClass != null && clazz.isAssignableFrom( mappedClass ) ) { + final boolean assignableSuperclass; + if ( checkQueryable.isInherited() ) { + Class mappedSuperclass = entityPersister( checkQueryable.getMappedSuperclass() ).getMappedClass(); + assignableSuperclass = clazz.isAssignableFrom( mappedSuperclass ); + } + else { + assignableSuperclass = false; + } + if ( !assignableSuperclass ) { + results.add( checkQueryableEntityName ); + } + } + } + } + } + + return results.toArray( new String[results.size()] ); + } }