What do @Document, @Id, and @Field do when mapping a Java/Kotlin class to a MongoDB collection with Spring Data MongoDB?
answer
- @Document = collection, default = decapitalized class name
- @Id -> _id primary key (ObjectId/String/Long)
- @Field renames the stored key
- MappingMongoConverter reads the annotations
- no auto snake_case / no pluralization
basics
~10 s@Document marks a class as a MongoDB collection (optionally naming it). @Id marks the field used as MongoDB's _id primary key. @Field maps a Java field to a differently-named document key.
solid answer
~40 s@Document tells Spring Data MongoDB the class is persistable as a document; @Document(collection = "users") sets the collection name (default is the decapitalized class name). @Id maps a property to MongoDB's mandatory _id key — the primary key; if you use an ObjectId or String field, MongoDB or Spring generates it on insert. @Field customizes how a single property is stored: @Field("first_name") stores the Java property firstName under the document key first_name, letting your Java naming differ from the stored schema. Without @Field the property name is used verbatim. These annotations are read by the MappingMongoConverter, which builds a MongoPersistentEntity model of the class and uses it to convert between org.bson.Document (BSON) and your objects in both directions.
code
java · 18 linesimport org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
@Document(collection = "users")
public class User {
@Id
private ObjectId id; // maps to _id, auto-generated on insert
@Field("first_name")
private String firstName; // stored under key "first_name"
private String email; // stored under key "email" (name unchanged)
// constructors / getters / setters
}go deeper
Know the three annotations and that _id is the primary key.
Know default collection naming, id generation, and @Field extras (targetType, write).
Explain that MappingMongoConverter/MongoMappingContext read these into a MongoPersistentEntity model.
Discuss schema-migration implications of renaming fields and choosing id types for sharding/index behavior.
Spring Data MongoDB maps plain classes (POJOs) to MongoDB documents. A MongoDB **document** is a JSON/BSON object stored inside a **collection** (the rough equivalent of a SQL table). The mapping is driven by annotations in `org.springframework.data.mongodb.core.mapping` and `org.springframework.data.annotation`. ## @Document `@Document` (`org.springframework.data.mongodb.core.mapping.Document`) marks a class as the root of a document. It is optional for the mapping to work but recommended — it lets you set the collection name via `@Document(collection = "users")` (the `value`/`collection` attributes are aliases). - If omitted, the collection name defaults to the **decapitalized simple class name** (class `User` -> collection `user`). - It can also carry a SpEL `#{...}` collection expression and a `language`/`collation` hint. ## @Id `@Id` (`org.springframework.data.annotation.Id`) designates the property that maps to MongoDB's special `_id` field. Every MongoDB document must have an `_id`; it is the primary key and is automatically indexed and unique. - Common id types: `org.bson.types.ObjectId`, `String`, or `Long`. - If the id is `String`/`ObjectId` and is null on insert, Spring/Mongo generates an `ObjectId` value. - Note: a property literally named `id` is also treated as the id even without the annotation. - In the stored document the key is always `_id`, regardless of your Java field name. ## @Field `@Field` (`org.springframework.data.mongodb.core.mapping.Field`) customizes a single property's storage. `@Field("first_name")` (or `@Field(name = "first_name")`) changes the document key. It also supports: - `order`, - `targetType` (e.g. `FieldType.STRING` to store a value as a specific BSON type), - and `write` (e.g. `Field.Write.NON_NULL` to skip writing null fields). Without `@Field`, the Java property name is used as-is (there is no automatic snake_case conversion unless you configure a `FieldNamingStrategy`). ## Who reads these The `MappingMongoConverter` together with `MongoMappingContext`. On startup (or first use) it inspects the class, builds a `MongoPersistentEntity` with `MongoPersistentProperty` entries, and caches it. At runtime it uses that model to convert a domain object to `org.bson.Document` on save and back on read. ## Gotchas and when to use **Gotchas:** - (1) `@Document` collection default is decapitalized, not pluralized — no automatic `s`. - (2) Changing `@Field` names or the id type does **not** migrate existing data — old documents keep their old keys. - (3) A transient field can be excluded with `@Transient`. - (4) The class needs a way to be instantiated (a persistence constructor or a no-arg constructor); Spring can use a parameterized constructor and even bypass setters via field access. **When to use:** - always annotate the id; - use `@Document(collection=...)` when you want an explicit, stable collection name; - use `@Field` when your Java naming should differ from the stored schema (e.g. matching an existing collection).
- If you omit @Document, is the class still persistable?Yes. Mapping works from any POJO; @Document is optional. Without it the collection name defaults to the decapitalized class name. You lose the ability to set an explicit collection name/collation via the annotation.
- What type does MongoDB generate for an @Id String field that is null on insert?An ObjectId is generated and stored in _id; when read back into a String field it is the ObjectId's 24-char hex string. If you need a real ObjectId object, declare the field as ObjectId.
saying these in an interview costs you the question
- Thinking the default collection name is pluralized (e.g. 'users') — it is the decapitalized class name.
- Believing @Field auto-converts camelCase to snake_case — it does not; you must name it explicitly or set a FieldNamingStrategy.
- Claiming @Document is mandatory for persistence.