MongoHelper uses a set of annotations to describe how your Java classes map to MongoDB collections, documents, fields, and indexes. This page explains each annotation and shows how to use them. ## List of Annotations - `@OrmModel` - `@OrmField` - `@OrmUnique` - `@OrmModelUnique` - `@OrmModelIndex` - `@OrmConstructor` - `@OrmParameter` --- ## `@OrmModel` **Target:** Class (`ElementType.TYPE`) Marks a class as a MongoDB model and defines its **collection name**. ```java import net.clydo.mongo.annotations.OrmModel; @OrmModel("posts") public class Post { // fields ... } ``` - `value()` — the MongoDB collection name to use for this model. - MongoHelper reads this in `ModelVisitorImpl` and stores it as the model's collection name. If a class is used as a model but is not annotated with `@OrmModel`, MongoHelper will fail to build metadata for it. --- ## `@OrmField` **Target:** Field (`ElementType.FIELD`) Defines how a Java field maps to a **document field name** in MongoDB. ```java import net.clydo.mongo.annotations.OrmField; import org.bson.types.ObjectId; @OrmModel("posts") public class Post { @OrmField("_id") private ObjectId id; @OrmField("title") private String title; @OrmField("body") private String body; } ``` - `value()` — the field name in the MongoDB document. - MongoHelper reads this in `TypeFieldVisitorImpl` and builds field metadata. ### Special Rule for `_id` If you mark a field as `"_id"`: ```java @OrmField("_id") private ObjectId id; ``` Then **that field must be of type `org.bson.types.ObjectId`**. Otherwise, MongoHelper throws an `IllegalStateException`: > Field '_id' must be of type org.bson.types.ObjectId --- ## `@OrmUnique` **Target:** Field (`ElementType.FIELD`) Marks a field as a **unique index**. ```java import net.clydo.mongo.annotations.OrmUnique; @OrmModel("users") public class User { @OrmField("email") @OrmUnique private String email; } ``` Attributes: - `String map() default ""` — an optional mapping string stored in index metadata. - `SortOrder sort() default SortOrder.ASCENDING` — sort order used when building the index (ascending or descending). MongoHelper uses `@OrmUnique` in `IndexVisitorImpl`: - It checks each field for `@OrmUnique`. - For each such field, it creates a `UniqueIndexMeta` for the collection. This results in a **single-field unique index** on the given field. --- ## `@OrmModelUnique` **Target:** Class (`ElementType.TYPE`), **repeatable** Defines a **compound unique index** on multiple fields of a model. ```java import net.clydo.mongo.annotations.OrmModelUnique; @OrmModel("users") @OrmModelUnique({"email", "tenant"}) public class User { @OrmField("email") private String email; @OrmField("tenant") private String tenant; } ``` Attributes: - `String[] value()` — the aliases of fields to include in the unique index. - These names must match the `@OrmField` values, not the Java field names. - `String name() default ""` — optional index name. - `String map() default ""` — optional mapping string stored in metadata. In `IndexVisitorImpl` MongoHelper: - Reads all `@OrmModelUnique` annotations on the class. - Resolves the field aliases to actual field metadata. - Builds a `UniqueIndexMeta` with the collection name, sort order (ascending by default), field names, mapping, and index name. This results in **compound unique indexes** (e.g., `(email, tenant)` must be unique together). --- ## `@OrmModelIndex` **Target:** Class (`ElementType.TYPE`), **repeatable** Defines a **non-unique compound index** on multiple fields. ```java import net.clydo.mongo.annotations.OrmModelIndex; @OrmModel("posts") @OrmModelIndex({"author_id", "created_at"}) public class Post { @OrmField("author_id") private String authorId; @OrmField("created_at") private long createdAt; } ``` Attributes: - `String[] value()` — field aliases (from `@OrmField`) to index. - `String map() default ""` — optional mapping string stored in metadata. In `IndexVisitorImpl` MongoHelper: - Reads all `@OrmModelIndex` annotations on the class. - Resolves the aliases to field metadata. - Builds a `NonUniqueIndexMeta` and adds it to the model metadata. This results in **compound non-unique indexes** (useful for query performance but not enforcing uniqueness). --- ## `@OrmConstructor` **Target:** Constructor (`ElementType.CONSTRUCTOR`) Marks a constructor as the one MongoHelper should use to create instances when materializing documents. ```java import net.clydo.mongo.annotations.OrmConstructor; import net.clydo.mongo.annotations.OrmField; import net.clydo.mongo.annotations.OrmParameter; import org.bson.types.ObjectId; @OrmModel("users") public class User { @OrmField("_id") private ObjectId id; @OrmField("email") private String email; @OrmField("age") private int age; @OrmConstructor(strict = true) public User( @OrmParameter("_id") ObjectId id, @OrmParameter("email") String email, @OrmParameter("age") int age ) { this.id = id; this.email = email; this.age = age; } } ``` Attributes: - `boolean strict() default true` — if `true`, the constructor must cover **all** fields annotated with `@OrmField`. Behavior (from `ConstructorVisitorImpl`): - Only **one** constructor per class may be annotated with `@OrmConstructor`. Otherwise an `IllegalStateException` is thrown. - For the annotated constructor, parameters are validated (see `@OrmParameter` below). - If `strict = true`, MongoHelper checks that all `@OrmField` fields are covered by `@OrmParameter` constructor parameters. - If some annotated fields are missing, an `IllegalStateException` is thrown with details. If no constructor is annotated with `@OrmConstructor`, MongoHelper falls back to a default constructor selection strategy. --- ## `@OrmParameter` **Target:** Constructor parameter (`ElementType.PARAMETER`) Binds a constructor parameter to a specific `@OrmField` by its alias. ```java import net.clydo.mongo.annotations.OrmParameter; @OrmConstructor public User( @OrmParameter("_id") ObjectId id, @OrmParameter("email") String email, @OrmParameter("age") int age ) { // ... } ``` Attributes: - `String value()` — the alias of the field, exactly as specified in `@OrmField("...")`. Behavior (from `ConstructorVisitorImpl`): - For each parameter with `@OrmParameter`, MongoHelper: - Locates the corresponding field metadata by alias. - Validates that the parameter type matches the field's type (with primitive wrapping). - Throws an `IllegalStateException` if there is a type mismatch. - Throws an `IllegalStateException` if there is a duplicate parameter name. - For parameters **without** `@OrmParameter`, a `null` placeholder is stored in the required-fields list. When `strict = true` on `@OrmConstructor`, all `@OrmField` fields must appear as `@OrmParameter` entries at least once, or a detailed error is thrown listing missing fields. --- ## Summary - Use `@OrmModel` to declare your collection name. - Use `@OrmField` to map Java fields to document field names. - Use `@OrmUnique` for single-field unique indexes. - Use `@OrmModelUnique` for compound unique indexes. - Use `@OrmModelIndex` for compound non-unique indexes. - Use `@OrmConstructor` and `@OrmParameter` to control how instances are created when reading from MongoDB. These annotations together drive MongoHelper's metadata, codec resolution, and index creation.