Entities & Annotations

Morphium maps Java POJOs to MongoDB documents using annotations. This page covers all annotations supported by the Quarkus extension.

@Entity

Marks a class as a top-level MongoDB document stored in its own collection.

import de.caluga.morphium.annotations.Entity;

@Entity(collectionName = "products")
public class ProductEntity {
    // ...
}

The collectionName parameter specifies the MongoDB collection name. If omitted, Morphium derives it from the class name (lowercased).

@Embedded

Marks a class as an embedded (sub-)document that is stored inside another entity’s document, not in its own collection.

import de.caluga.morphium.annotations.Embedded;

@Embedded
public class AddressEmbedded {
    @Property(fieldName = "street") private String street;
    @Property(fieldName = "city")   private String city;
    // getters / setters
}

Use embedded documents for data that doesn’t need its own collection and is always loaded together with the parent entity.

@Id

Marks the primary key field. Morphium supports MorphiumId (similar to MongoDB ObjectId) and String as ID types.

import de.caluga.morphium.annotations.Id;

@Id
private String id;

Morphium automatically generates the ID on store() if the field is null.

@Property

Maps a Java field to a specific MongoDB document field name.

import de.caluga.morphium.annotations.Property;

@Property(fieldName = "display_name")
private String name;

Without @Property, Morphium uses the Java field name as-is.

@Version — Optimistic Locking

Enables optimistic locking. Morphium increments the version on every store() and throws an exception if the document was modified concurrently.

import de.caluga.morphium.annotations.Version;

@Version
@Property(fieldName = "version")
private long version;

For more details see the Morphium core documentation.

@AutoSequence

Generates automatic, sequential numeric IDs using a server-side sequence.

import de.caluga.morphium.annotations.AutoSequence;

@AutoSequence
@Id
private long id;

For details on sequence configuration see the Morphium core documentation.

Lifecycle Annotations

Morphium supports lifecycle callbacks via annotations. Annotate the entity class with @Lifecycle and individual methods with the appropriate callback annotation.

import de.caluga.morphium.annotations.lifecycle.*;

@Entity(collectionName = "products")
@Lifecycle
public class ProductEntity {

    @PreStore
    public void beforeSave() {
        // called before each store() operation
    }

    @PostStore
    public void afterSave() {
        // called after a successful store()
    }
}
Table 1. Available lifecycle annotations
Annotation When it fires

@PreStore

Before store() — validate or set defaults

@PostStore

After a successful store()

@PreRemove

Before delete()

@PostRemove

After a successful delete()

@PostLoad

After loading a document from MongoDB

@Cache

Enables query-result caching for an entity type. Cached queries are served from memory until the cache TTL expires or the cache is invalidated by a write operation.

import de.caluga.morphium.annotations.caching.Cache;

@Cache(maxEntries = 1000, clearOnWrite = true)
@Entity(collectionName = "products")
public class ProductEntity {
    // ...
}

Cache behavior is controlled globally via quarkus.morphium.cache.* properties (see Configuration Reference) and per-entity via @Cache attributes. For advanced caching patterns see the Morphium core documentation.

@Reference

Stores a link to another entity in a separate collection instead of embedding it inline. Morphium persists only the referenced entity’s _id in the parent document and resolves it on load.

import de.caluga.morphium.annotations.Reference;

@Entity
public class BlogPost {
    @Id private MorphiumId id;

    @Reference
    private Author author;

    @Reference(lazyLoading = true)
    private Author reviewer;

    @Reference(cascadeDelete = true)
    private List<OrderItem> items;

    @Reference(orphanRemoval = true)
    private List<Tag> tags;
}
Table 2. @Reference attributes
Attribute Default Description

automaticStore

true

When true, Morphium automatically persists referenced objects that don’t yet have an ID when the parent is stored. Set to false to control persistence order manually.

lazyLoading

false

When true, the referenced entity is not loaded from the database until a method on the proxy is called. Useful for rarely-accessed references or to break bidirectional deserialization cycles.

cascadeDelete

false

When true, deleting the parent entity also deletes the referenced entities. Only applies to entity-based delete(Object) calls, not query-based deletes. Circular cascade references are detected and do not cause infinite loops.

orphanRemoval

false

When true, updating the parent entity automatically deletes referenced entities that are no longer referenced. Only triggers on updates (entities with an existing ID), not on inserts.

fieldName

.

Override the MongoDB field name for the reference. Defaults to the Java field name.

targetCollection

.

Override the target collection for the referenced entity. Defaults to the entity’s own collection.

automaticStore (default: true)

With the default automaticStore = true, you do not need to store referenced entities before storing the parent. Morphium handles this automatically:

Author author = new Author();
author.setName("Jane");
// author has no ID yet — Morphium will store it automatically

BlogPost post = new BlogPost();
post.setAuthor(author);
morphium.store(post); // author is auto-stored first, then post references author's new ID

Set automaticStore = false when you want to control persistence order manually:

@Reference(automaticStore = false)
private Author author;

// Must store author explicitly first:
morphium.store(author);
post.setAuthor(author);
morphium.store(post);

Circular references

Morphium includes cycle detection for circular @Reference chains (e.g., A → B → A). If a cycle is detected during serialization, objects with IDs return a minimal {_id: …​} document; objects without IDs throw IllegalStateException with a clear error message.

For bidirectional references, use lazyLoading = true on at least one side to prevent deserialization cycles.

For more details see the Morphium core documentation.

GraalVM Native Image

All classes annotated with @Entity or @Embedded are automatically registered for GraalVM reflection at build time. The Quarkus deployment processor uses ClassGraph to scan the classpath and registers constructors, methods, and fields for each annotated class.

No manual reflect-config.json entries are needed. If the classpath scan fails (logged as a WARN at build time), you can add entries manually via standard GraalVM reflection configuration.