HHH-11495 Reduce criteria overhead by adding an implementors cache
This commit is contained in:
parent
35cd3a1c38
commit
9684afda76
|
@ -111,6 +111,8 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable {
|
||||||
|
|
||||||
private final TypeConfiguration typeConfiguration;
|
private final TypeConfiguration typeConfiguration;
|
||||||
|
|
||||||
|
private final Map<String, String[]> implementorsCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public MetamodelImpl(SessionFactoryImplementor sessionFactory, TypeConfiguration typeConfiguration) {
|
public MetamodelImpl(SessionFactoryImplementor sessionFactory, TypeConfiguration typeConfiguration) {
|
||||||
this.sessionFactory = sessionFactory;
|
this.sessionFactory = sessionFactory;
|
||||||
this.typeConfiguration = typeConfiguration;
|
this.typeConfiguration = typeConfiguration;
|
||||||
|
@ -622,51 +624,7 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable {
|
||||||
* @throws MappingException
|
* @throws MappingException
|
||||||
*/
|
*/
|
||||||
public String[] getImplementors(String className) throws MappingException {
|
public String[] getImplementors(String className) throws MappingException {
|
||||||
|
return implementorsCache.computeIfAbsent( className, this::doGetImplementors );
|
||||||
final Class clazz;
|
|
||||||
try {
|
|
||||||
clazz = getSessionFactory().getServiceRegistry().getService( ClassLoaderService.class ).classForName( className );
|
|
||||||
}
|
|
||||||
catch (ClassLoadingException e) {
|
|
||||||
return new String[] { className }; //for a dynamic-class
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<String> 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()] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -789,4 +747,53 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable {
|
||||||
public void close() {
|
public void close() {
|
||||||
// anything to do ?
|
// 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<String> 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()] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue