quarkusio/quarkus · error · BuildException

Type ${className} must be annotated with @Embeddable, becaus

Error message

Type ${className} must be annotated with @Embeddable, because it is used as an embeddable. This type is used in class ${declaringClass} for attribute ${attribute}.

What it means

Quarkus validates at build time that any type used as an embeddable (via @Embedded, @EmbeddedId, or @ElementCollection on an embeddable type) is annotated with @Embeddable. If the target type lacks the annotation, a BuildException is thrown naming the type, declaring class, and attribute.

Source

Thrown at extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/JpaJandexScavenger.java:584

    }

    private void collectEmbeddedType(Set<DotName> embeddedTypes, ClassInfo declaringClass,
            Declaration attribute, Type attributeType, boolean validate)
            throws BuildException {
        DotName className;
        switch (attributeType.kind()) {
            case CLASS:
                className = attributeType.asClassType().name();
                break;
            case PARAMETERIZED_TYPE:
                className = attributeType.name();
                break;
            default:
                // do nothing
                return;
        }
        if (validate && !index.getClassByName(className).hasAnnotation(ClassNames.EMBEDDABLE)) {
            throw new BuildException(
                    "Type " + className + " must be annotated with @Embeddable, because it is used as an embeddable."
                            + " This type is used in class " + declaringClass
                            + " for attribute " + attribute + ".");
        }
        embeddedTypes.add(attributeType.name());
    }

    private void collectElementCollectionTypes(Set<DotName> embeddedTypes, ClassInfo declaringClass,
            Declaration attribute, Type attributeType)
            throws BuildException {
        switch (attributeType.kind()) {
            case CLASS:
                // Raw collection type, nothing we can do
                break;
            case PARAMETERIZED_TYPE:
                embeddedTypes.add(attributeType.name());
                var typeArguments = attributeType.asParameterizedType().arguments();
                for (Type typeArgument : typeArguments) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Annotate the referenced type with jakarta.persistence.Embeddable
  2. If the type should be its own entity, change the field mapping (remove @Embedded, use @OneToOne etc.)
  3. If the type is in another module, ensure it is part of the application and indexed by Quarkus
  4. Verify the attribute name and declaring class in the message to find the exact field to fix

Example fix

// before
public class Address { private String street; }
@Entity public class Person { @Embedded Address address; }
// after
@Embeddable
public class Address { private String street; }
@Entity public class Person { @Embedded Address address; }
Defensive patterns

Strategy: validation

Validate before calling

// Check before mapping an @Embedded field
static void requireEmbeddable(Class<?> type) {
    if (!type.isAnnotationPresent(jakarta.persistence.Embeddable.class))
        throw new IllegalArgumentException(type + " must be @Embeddable");
}

Type guard

static boolean isEmbeddable(Class<?> t) {
    return t.isAnnotationPresent(jakarta.persistence.Embeddable.class);
}

Prevention

When it happens

Trigger: collectEmbeddedType is invoked from enlistEmbeddedsAndElementCollections or collectElementCollectionTypes when an entity field annotated @Embedded/@EmbeddedId/@ElementCollection points to a type without @Embeddable in the Jandex index.

Common situations: Using an entity or plain POJO as an @Embedded field; forgetting @Embeddable when introducing an embeddable; the embeddable class present but not indexed; switching a field type from entity to embeddable without adding the annotation.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/21755d78af3139b4. Report an issue: GitHub.