Skip to content

Commit d54d364

Browse files
committed
HHH-19648 Add check for recursive embeddable mappings
1 parent c325c8d commit d54d364

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

hibernate-core/src/main/java/org/hibernate/boot/model/internal/EmbeddableBinder.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
import java.util.HashMap;
1414
import java.util.LinkedHashMap;
1515
import java.util.List;
16+
import java.util.Locale;
1617
import java.util.Map;
1718

1819
import org.hibernate.AnnotationException;
20+
import org.hibernate.MappingException;
1921
import org.hibernate.annotations.DiscriminatorFormula;
2022
import org.hibernate.annotations.Instantiator;
2123
import org.hibernate.annotations.TypeBinderType;
@@ -850,6 +852,7 @@ static Component createEmbeddable(
850852
else {
851853
embeddableClass = inferredData.getClassOrPluralElement();
852854
component.setComponentClassName( embeddableClass.getName() );
855+
checkEmbeddableRecursiveHierarchy( embeddableClass, inferredData, propertyHolder );
853856
}
854857
component.setCustomInstantiator( customInstantiatorImpl );
855858
final Constructor<?> constructor = resolveInstantiator( embeddableClass, context );
@@ -863,6 +866,29 @@ static Component createEmbeddable(
863866
return component;
864867
}
865868

869+
private static void checkEmbeddableRecursiveHierarchy(
870+
XClass embeddableClass,
871+
PropertyData propertyData,
872+
PropertyHolder propertyHolder) {
873+
while ( propertyHolder.isComponent() ) {
874+
final ComponentPropertyHolder componentHolder = (ComponentPropertyHolder) propertyHolder;
875+
// we need to check that the embeddable is not used in a recursive hierarchy
876+
XClass classDetails = embeddableClass;
877+
while ( classDetails != null ) {
878+
if ( propertyHolder.getClassName().equals( classDetails.getName() ) ) {
879+
throw new MappingException( String.format(
880+
Locale.ROOT,
881+
"Recursive embeddable mapping detected for property '%s' for type [%s]",
882+
getPath( propertyHolder, propertyData ),
883+
propertyHolder.getClassName()
884+
) );
885+
}
886+
classDetails = classDetails.getSuperclass();
887+
}
888+
propertyHolder = componentHolder.parent;
889+
}
890+
}
891+
866892
private static Constructor<?> resolveInstantiator(XClass embeddableClass, MetadataBuildingContext buildingContext) {
867893
if ( embeddableClass != null ) {
868894
final Constructor<?>[] declaredConstructors = buildingContext.getBootstrapContext().getReflectionManager()

0 commit comments

Comments
 (0)