HHH-18863 allow index creation to be disabled in processor
also cache enum results read from index
This commit is contained in:
parent
3cf2bc88e0
commit
83110b4638
|
@ -107,6 +107,8 @@ public final class Context {
|
|||
private String[] includes = {"*"};
|
||||
private String[] excludes = {};
|
||||
|
||||
private boolean indexing = true;
|
||||
|
||||
private final Map<String, String> entityNameMappings = new HashMap<>();
|
||||
private final Map<String, Set<String>> enumTypesByValue = new HashMap<>();
|
||||
|
||||
|
@ -551,4 +553,12 @@ public final class Context {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setIndexing(boolean index) {
|
||||
this.indexing = index;
|
||||
}
|
||||
|
||||
public boolean isIndexing() {
|
||||
return indexing;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ import static org.hibernate.processor.HibernateProcessor.DEBUG_OPTION;
|
|||
import static org.hibernate.processor.HibernateProcessor.EXCLUDE;
|
||||
import static org.hibernate.processor.HibernateProcessor.FULLY_ANNOTATION_CONFIGURED_OPTION;
|
||||
import static org.hibernate.processor.HibernateProcessor.INCLUDE;
|
||||
import static org.hibernate.processor.HibernateProcessor.INDEX;
|
||||
import static org.hibernate.processor.HibernateProcessor.LAZY_XML_PARSING;
|
||||
import static org.hibernate.processor.HibernateProcessor.ORM_XML_OPTION;
|
||||
import static org.hibernate.processor.HibernateProcessor.PERSISTENCE_XML_OPTION;
|
||||
|
@ -120,7 +121,8 @@ import static org.hibernate.processor.util.TypeUtils.isMemberType;
|
|||
ADD_GENERATED_ANNOTATION,
|
||||
ADD_SUPPRESS_WARNINGS_ANNOTATION,
|
||||
SUPPRESS_JAKARTA_DATA_METAMODEL,
|
||||
INCLUDE, EXCLUDE
|
||||
INCLUDE, EXCLUDE,
|
||||
INDEX
|
||||
})
|
||||
public class HibernateProcessor extends AbstractProcessor {
|
||||
|
||||
|
@ -190,6 +192,13 @@ public class HibernateProcessor extends AbstractProcessor {
|
|||
*/
|
||||
public static final String EXCLUDE = "exclude";
|
||||
|
||||
/**
|
||||
* Option to suppress creation of a filesystem-based index of entity
|
||||
* types and enums for use by the query validator. By default, and
|
||||
* index is created.
|
||||
*/
|
||||
public static final String INDEX = "index";
|
||||
|
||||
private static final boolean ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS = false;
|
||||
|
||||
public static final String ENTITY_INDEX = "entity.index";
|
||||
|
@ -282,6 +291,8 @@ public class HibernateProcessor extends AbstractProcessor {
|
|||
context.setInclude( options.getOrDefault( INCLUDE, "*" ) );
|
||||
context.setExclude( options.getOrDefault( EXCLUDE, "" ) );
|
||||
|
||||
context.setIndexing( parseBoolean( options.get( INDEX ) ) );
|
||||
|
||||
return parseBoolean( options.get( FULLY_ANNOTATION_CONFIGURED_OPTION ) );
|
||||
}
|
||||
|
||||
|
@ -773,43 +784,45 @@ public class HibernateProcessor extends AbstractProcessor {
|
|||
}
|
||||
|
||||
private void writeIndex() {
|
||||
final ProcessingEnvironment processingEnvironment = context.getProcessingEnvironment();
|
||||
final Elements elementUtils = processingEnvironment.getElementUtils();
|
||||
context.getEntityNameMappings().forEach((entityName, className) -> {
|
||||
try (Writer writer = processingEnvironment.getFiler()
|
||||
.createResource(
|
||||
StandardLocation.SOURCE_OUTPUT,
|
||||
ENTITY_INDEX,
|
||||
entityName,
|
||||
elementUtils.getTypeElement( className )
|
||||
)
|
||||
.openWriter()) {
|
||||
writer.append(className);
|
||||
}
|
||||
catch (IOException e) {
|
||||
processingEnvironment.getMessager()
|
||||
.printMessage(Diagnostic.Kind.WARNING,
|
||||
"could not write entity index " + e.getMessage());
|
||||
}
|
||||
});
|
||||
context.getEnumTypesByValue().forEach((valueName, enumTypeNames) -> {
|
||||
try (Writer writer = processingEnvironment.getFiler()
|
||||
.createResource(
|
||||
StandardLocation.SOURCE_OUTPUT,
|
||||
ENTITY_INDEX,
|
||||
'.' + valueName,
|
||||
elementUtils.getTypeElement( enumTypeNames.iterator().next() )
|
||||
)
|
||||
.openWriter()) {
|
||||
for (String enumTypeName : enumTypeNames) {
|
||||
writer.append(enumTypeName).append(" ");
|
||||
if ( context.isIndexing() ) {
|
||||
final ProcessingEnvironment processingEnvironment = context.getProcessingEnvironment();
|
||||
final Elements elementUtils = processingEnvironment.getElementUtils();
|
||||
context.getEntityNameMappings().forEach( (entityName, className) -> {
|
||||
try (Writer writer = processingEnvironment.getFiler()
|
||||
.createResource(
|
||||
StandardLocation.SOURCE_OUTPUT,
|
||||
ENTITY_INDEX,
|
||||
entityName,
|
||||
elementUtils.getTypeElement( className )
|
||||
)
|
||||
.openWriter()) {
|
||||
writer.append( className );
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
processingEnvironment.getMessager()
|
||||
.printMessage(Diagnostic.Kind.WARNING,
|
||||
"could not write entity index " + e.getMessage());
|
||||
}
|
||||
});
|
||||
catch (IOException e) {
|
||||
processingEnvironment.getMessager()
|
||||
.printMessage( Diagnostic.Kind.WARNING,
|
||||
"could not write entity index " + e.getMessage() );
|
||||
}
|
||||
} );
|
||||
context.getEnumTypesByValue().forEach( (valueName, enumTypeNames) -> {
|
||||
try (Writer writer = processingEnvironment.getFiler()
|
||||
.createResource(
|
||||
StandardLocation.SOURCE_OUTPUT,
|
||||
ENTITY_INDEX,
|
||||
'.' + valueName,
|
||||
elementUtils.getTypeElement( enumTypeNames.iterator().next() )
|
||||
)
|
||||
.openWriter()) {
|
||||
for ( String enumTypeName : enumTypeNames ) {
|
||||
writer.append( enumTypeName ).append( " " );
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
processingEnvironment.getMessager()
|
||||
.printMessage( Diagnostic.Kind.WARNING,
|
||||
"could not write entity index " + e.getMessage() );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,8 @@ public abstract class AnnotationMeta implements Metamodel {
|
|||
new WarningErrorHandler( context, getElement(), mirror, value, hql,
|
||||
reportErrors, checkHql ),
|
||||
ProcessorSessionFactory.create( context.getProcessingEnvironment(),
|
||||
context.getEntityNameMappings(), context.getEnumTypesByValue() )
|
||||
context.getEntityNameMappings(), context.getEnumTypesByValue(),
|
||||
context.isIndexing() )
|
||||
);
|
||||
if ( !isJakartaDataStyle()
|
||||
&& statement instanceof SqmSelectStatement<?> selectStatement ) {
|
||||
|
|
|
@ -2451,7 +2451,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
true,
|
||||
new ErrorHandler( context, isLocal(method) ? method : element, mirror, value, hql ),
|
||||
ProcessorSessionFactory.create( context.getProcessingEnvironment(),
|
||||
context.getEntityNameMappings(), context.getEnumTypesByValue() )
|
||||
context.getEntityNameMappings(), context.getEnumTypesByValue(), context.isIndexing() )
|
||||
);
|
||||
if ( statement != null ) {
|
||||
if ( statement instanceof SqmSelectStatement ) {
|
||||
|
|
|
@ -72,8 +72,9 @@ public abstract class ProcessorSessionFactory extends MockSessionFactory {
|
|||
public static MockSessionFactory create(
|
||||
ProcessingEnvironment environment,
|
||||
Map<String,String> entityNameMappings,
|
||||
Map<String, Set<String>> enumTypesByValue) {
|
||||
return instance.make(environment, entityNameMappings, enumTypesByValue);
|
||||
Map<String, Set<String>> enumTypesByValue,
|
||||
boolean indexing) {
|
||||
return instance.make(environment, indexing, entityNameMappings, enumTypesByValue);
|
||||
}
|
||||
|
||||
static final Mocker<ProcessorSessionFactory> instance = Mocker.variadic(ProcessorSessionFactory.class);
|
||||
|
@ -88,16 +89,19 @@ public abstract class ProcessorSessionFactory extends MockSessionFactory {
|
|||
private final Elements elementUtil;
|
||||
private final Types typeUtil;
|
||||
private final Filer filer;
|
||||
private final boolean indexing;
|
||||
private final Map<String, String> entityNameMappings;
|
||||
private final Map<String, Set<String>> enumTypesByValue;
|
||||
|
||||
public ProcessorSessionFactory(
|
||||
ProcessingEnvironment processingEnvironment,
|
||||
boolean indexing,
|
||||
Map<String,String> entityNameMappings,
|
||||
Map<String, Set<String>> enumTypesByValue) {
|
||||
elementUtil = processingEnvironment.getElementUtils();
|
||||
typeUtil = processingEnvironment.getTypeUtils();
|
||||
filer = processingEnvironment.getFiler();
|
||||
this.indexing = indexing;
|
||||
this.entityNameMappings = entityNameMappings;
|
||||
this.enumTypesByValue = enumTypesByValue;
|
||||
}
|
||||
|
@ -220,15 +224,25 @@ public abstract class ProcessorSessionFactory extends MockSessionFactory {
|
|||
if ( result != null ) {
|
||||
return result;
|
||||
}
|
||||
try (Reader reader = filer.getResource(StandardLocation.SOURCE_OUTPUT, ENTITY_INDEX, value)
|
||||
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
|
||||
return Set.of(split(" ", buffered.readLine()));
|
||||
if ( indexing ) {
|
||||
final Set<String> indexed = getIndexedEnumTypesByValue(value);
|
||||
enumTypesByValue.put(value, indexed);
|
||||
return indexed;
|
||||
}
|
||||
//TODO: else do a full scan like in findEntityByUnqualifiedName()
|
||||
return null;
|
||||
}
|
||||
|
||||
private @Nullable Set<String> getIndexedEnumTypesByValue(String value) {
|
||||
try (Reader reader = filer.getResource( StandardLocation.SOURCE_OUTPUT, ENTITY_INDEX, value )
|
||||
.openReader( true ); BufferedReader buffered = new BufferedReader( reader )) {
|
||||
return Set.of( split( " ", buffered.readLine() ) );
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
try (Reader reader = filer.getResource(StandardLocation.CLASS_PATH, ENTITY_INDEX, '.' + value)
|
||||
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
|
||||
return Set.of(split(" ", buffered.readLine()));
|
||||
try (Reader reader = filer.getResource( StandardLocation.CLASS_PATH, ENTITY_INDEX, '.' + value )
|
||||
.openReader( true ); BufferedReader buffered = new BufferedReader( reader )) {
|
||||
return Set.of( split( " ", buffered.readLine() ) );
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
|
@ -503,27 +517,13 @@ public abstract class ProcessorSessionFactory extends MockSessionFactory {
|
|||
if ( cached != null ) {
|
||||
return cached;
|
||||
}
|
||||
final String qualifiedName = entityNameMappings.get(entityName);
|
||||
if ( qualifiedName != null ) {
|
||||
final TypeElement result = elementUtil.getTypeElement(qualifiedName);
|
||||
entityCache.put(entityName, result);
|
||||
return result;
|
||||
}
|
||||
try (Reader reader = filer.getResource( StandardLocation.SOURCE_OUTPUT, ENTITY_INDEX, entityName)
|
||||
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
|
||||
final TypeElement result = elementUtil.getTypeElement(buffered.readLine());
|
||||
entityCache.put(entityName, result);
|
||||
return result;
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
try (Reader reader = filer.getResource(StandardLocation.CLASS_PATH, ENTITY_INDEX, entityName)
|
||||
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
|
||||
final TypeElement result = elementUtil.getTypeElement(buffered.readLine());
|
||||
entityCache.put(entityName, result);
|
||||
return result;
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
|
||||
if ( indexing ) {
|
||||
final TypeElement indexedEntity = findIndexedEntityByQualifiedName( entityName );
|
||||
if ( indexedEntity != null ) {
|
||||
entityCache.put(entityName, indexedEntity);
|
||||
return indexedEntity;
|
||||
}
|
||||
}
|
||||
|
||||
TypeElement symbol =
|
||||
|
@ -543,6 +543,26 @@ public abstract class ProcessorSessionFactory extends MockSessionFactory {
|
|||
return null;
|
||||
}
|
||||
|
||||
private @Nullable TypeElement findIndexedEntityByQualifiedName(String entityName) {
|
||||
final String qualifiedName = entityNameMappings.get(entityName);
|
||||
if ( qualifiedName != null ) {
|
||||
return elementUtil.getTypeElement(qualifiedName);
|
||||
}
|
||||
try (Reader reader = filer.getResource( StandardLocation.SOURCE_OUTPUT, ENTITY_INDEX, entityName)
|
||||
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
|
||||
return elementUtil.getTypeElement(buffered.readLine());
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
try (Reader reader = filer.getResource(StandardLocation.CLASS_PATH, ENTITY_INDEX, entityName)
|
||||
.openReader(true); BufferedReader buffered = new BufferedReader(reader) ) {
|
||||
return elementUtil.getTypeElement(buffered.readLine());
|
||||
}
|
||||
catch (IOException ignore) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static TypeElement findEntityByUnqualifiedName(String entityName, ModuleElement module) {
|
||||
for (Element element: module.getEnclosedElements()) {
|
||||
if (element.getKind() == ElementKind.PACKAGE) {
|
||||
|
|
Loading…
Reference in New Issue