java-topology/defects/hibernate/patch/hibernate-0005-orderhierarchy-linkedhashset.patch

44 lines
2.1 KiB
Diff

# UNDF: UNDF-2026-000000111
--- a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java
@@ -172,10 +172,13 @@ class AnnotationMetadataSourceProcessorImpl {
private List<ClassDetails> orderAndFillHierarchy(LinkedHashSet<ClassDetails> original) {
final LinkedHashSet<ClassDetails> copy = new LinkedHashSet<>( original.size() );
insertMappedSuperclasses( original, copy );
// order the hierarchy
final List<ClassDetails> workingCopy = new ArrayList<>( copy );
- final List<ClassDetails> newList = new ArrayList<>( copy.size() );
+ // hibernate-0005 fix: LinkedHashSet for O(1) contains() in orderHierarchy().
+ // Previously ArrayList<ClassDetails>: the recursive orderHierarchy() called
+ // newList.contains() which is O(N). For E entities with inheritance depth D,
+ // the recursion runs O(E*D) times, each with O(E) contains(), giving O(E²*D).
+ // LinkedHashSet is O(1) contains() and preserves insertion order.
+ final LinkedHashSet<ClassDetails> newSet = new LinkedHashSet<>( copy.size() );
while ( !workingCopy.isEmpty() ) {
final var clazz = workingCopy.get( 0 );
- orderHierarchy( workingCopy, newList, copy, clazz );
+ orderHierarchy( workingCopy, newSet, copy, clazz );
}
- return newList;
+ return new ArrayList<>( newSet );
}
@@ -209,10 +212,10 @@ class AnnotationMetadataSourceProcessorImpl {
private void orderHierarchy(List<ClassDetails> copy,
- List<ClassDetails> newList,
+ LinkedHashSet<ClassDetails> newSet,
LinkedHashSet<ClassDetails> original,
ClassDetails clazz) {
if ( clazz != null && !isObjectClass( clazz ) ) {
- orderHierarchy( copy, newList, original, clazz.getSuperClass() );
+ orderHierarchy( copy, newSet, original, clazz.getSuperClass() );
if ( original.contains( clazz ) ) {
- if ( !newList.contains( clazz ) ) {
- newList.add( clazz );
- }
+ // O(1) add/contains with LinkedHashSet; was O(N) with ArrayList
+ newSet.add( clazz );
copy.remove( clazz );
}
}
}