From 388c3ea1d43fe1ccd7b68bbea622ae59556707bb Mon Sep 17 00:00:00 2001 From: Richard Zowalla Date: Fri, 21 Aug 2026 14:27:45 +0200 Subject: [PATCH] [OPENJPA-2957] Resolve embeddables through the metadata repository instead of annotation names --- .../exps/AbstractExpressionBuilder.java | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java index 6b6b08a36e..a659b04c7a 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/AbstractExpressionBuilder.java @@ -305,8 +305,7 @@ protected Value traversePath(Path path, String field, boolean pcOnly, meta = fmd.getEmbeddedMetaData(); else meta = fmd.getDeclaredTypeMetaData(); - if (meta == null && fmd.isEmbedded() - && !hasEmbeddableAnnotation(fmd.getDeclaredType())) { + if (meta == null && fmd.isEmbedded() && !isEmbeddable(fmd)) { // Non-@Embeddable @IdClass field inside @EmbeddedId (JPA 2.4.1.3 // ex2b). Resolve via the @MapsId @ManyToOne target entity. meta = resolveMapsIdTargetMeta(fmd); @@ -352,18 +351,16 @@ private boolean isMultiValuedTraversalAttempt(Path path, String field) { } /** - * Checks whether a class has an @Embeddable annotation via reflection. - * Uses annotation simple name to avoid compile-time dependency on - * jakarta.persistence. + * Whether the declared type of the given field is known to the metadata + * repository as an embeddable. Asking the repository rather than the type's + * annotations also covers embeddables that are declared in orm.xml only. */ - private static boolean hasEmbeddableAnnotation(Class type) { - if (type == null) return false; - for (java.lang.annotation.Annotation ann : type.getAnnotations()) { - if ("Embeddable".equals(ann.annotationType().getSimpleName())) { - return true; - } - } - return false; + private static boolean isEmbeddable(FieldMetaData fmd) { + Class type = fmd.getDeclaredType(); + if (type == null) + return false; + ClassMetaData typeMeta = fmd.getRepository().getMetaData(type, null, false); + return typeMeta != null && typeMeta.isEmbeddable(); } /**