Hibernate allows customizing the instantiation of JPA embeddables via an implementation that can be registered via the @EmbeddableInstantiator annotation on a type or field. It will try to instantiate those via their default constructor. It would be nice if Spring Framework's entity processing would automatically generate the necessary reflection metadata for those declarations.

Comment From: odrotbohm

Thanks for the quick turnaround. Unfortunately, the fix misses the situation that an embeddable type is annotated, but the field then doesn't have to be anymore:

@Embeddable
@EmbeddableInstantiator(…)
class Foo { … }

@Entity
class MyEntity {
  Foo foo;
}

In other words, the processing would need to detect the annotation on a managed type as well.

Looking at the current implementation, I think this can be simplified to scan the managed type, its fields and the types of those fields (field.getType()) for the annotation.

Comment From: odrotbohm

This seems to do the trick for me (replace PersistenceManagedTypesBeanRegistrationAotProcessor.contributeHibernateHints(…) with the following:

private void contributeHibernateHints(RuntimeHints hints, Class<?> managedClass) {

    if (embeddableInstantiatorClass == null) {
        return;
    }

    ReflectionHints reflection = hints.reflection();

    registerInstantiatorForReflection(reflection,
            AnnotationUtils.findAnnotation(managedClass, embeddableInstantiatorClass));

    ReflectionUtils.doWithFields(managedClass, field -> {
        registerInstantiatorForReflection(reflection,
                AnnotationUtils.findAnnotation(field, embeddableInstantiatorClass));
        registerInstantiatorForReflection(reflection,
                AnnotationUtils.findAnnotation(field.getType(), embeddableInstantiatorClass));
    });
}

void registerInstantiatorForReflection(ReflectionHints reflection, Annotation annotation) {

    if (annotation == null) {
        return;
    }

    Class<?> embeddableInstantiatorClass = (Class<?>) AnnotationUtils.getAnnotationAttributes(annotation)
            .get("value");
    reflection.registerType(embeddableInstantiatorClass, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
}