@@ -966,7 +966,9 @@ static Component createEmbeddable(
966966 embeddable .setComponentClassName ( embeddable .getOwner ().getClassName () );
967967 }
968968 else {
969- embeddable .setComponentClassName ( inferredData .getClassOrElementType ().getName () );
969+ final var type = inferredData .getClassOrElementType ();
970+ embeddable .setComponentClassName ( type .getName () );
971+ checkEmbeddableRecursiveHierarchy ( type , inferredData , propertyHolder );
970972 }
971973 embeddable .setCustomInstantiator ( customInstantiatorImpl );
972974 final var constructor = resolveInstantiator ( inferredData .getClassOrElementType () );
@@ -981,6 +983,30 @@ static Component createEmbeddable(
981983 return embeddable ;
982984 }
983985
986+ private static void checkEmbeddableRecursiveHierarchy (
987+ TypeDetails type ,
988+ PropertyData propertyData ,
989+ PropertyHolder propertyHolder ) {
990+ final var embeddableClass = type .determineRawClass ();
991+ while ( propertyHolder .isComponent () ) {
992+ final ComponentPropertyHolder componentHolder = (ComponentPropertyHolder ) propertyHolder ;
993+ // we need to check that the embeddable is not used in a recursive hierarchy
994+ var classDetails = embeddableClass ;
995+ while ( classDetails != null ) {
996+ if ( propertyHolder .getClassName ().equals ( classDetails .getClassName () ) ) {
997+ throw new MappingException ( String .format (
998+ Locale .ROOT ,
999+ "Recursive embeddable mapping detected for property '%s' for type [%s]" ,
1000+ getPath ( propertyHolder , propertyData ),
1001+ propertyHolder .getClassName ()
1002+ ) );
1003+ }
1004+ classDetails = classDetails .getSuperClass ();
1005+ }
1006+ propertyHolder = componentHolder .parent ;
1007+ }
1008+ }
1009+
9841010 private static void applyColumnNamingPattern (Component embeddable , PropertyData inferredData ) {
9851011 final var componentClass = embeddable .getComponentClass ();
9861012 if ( componentClass == null || Map .class .equals ( componentClass ) ) {
0 commit comments