Docs Menu
Docs Home
/ / /
Java Sync
/ /

Document Data Format: Records

On this page

  • Overview
  • Serialize and Deserialize a Record
  • Example Record
  • Insert a Record
  • Retrieve a Record
  • Specify Component Conversion Using Annotations
  • Example Annotated Record
  • Insert an Annotated Record
  • Retrieve an Annotated Record
  • Operations with Recursive Types
  • Retrieve the Record Codec

In this guide, you can learn how to store and retrieve data in the MongoDB Java Driver using Java records. Java records are a type of Java class often used to model data and separate business logic from data representation.

Tip

You can declare Java records in Java 16 or later. Learn more about the functionality and restrictions of records from Java 17 Language Updates: Record Classes.

If you are using an earlier version of Java, you can use plain old Java objects instead. See the Document Data Format: POJOs guide for implementation details.

Note

If you are using the driver in an OSGi container and your application uses the driver to encode or decode Java records, you must add an explicit dependency on the org.bson.codecs.record module. Learn more about defining dependencies for OSGi containers in the IBM OSGi documentation.

The driver natively supports encoding and decoding Java records for MongoDB read and write operations using the default codec registry. The default codec registry is a collection of classes called codecs that define how to convert encode and decode Java types. Learn more about codecs and the default codec registry in the guide on Codecs.

The code examples in this section reference the following sample record, which describes a data storage device:

public record DataStorageRecord(
String productName,
double capacity
) {}

You can insert a DataStorageRecord instance as shown in the following code:

MongoCollection<DataStorageRecord> collection = database.getCollection("data_storage_devices", DataStorageRecord.class);
// insert the record
collection.insertOne(new DataStorageRecord("2TB SSD", 1.71));

You can retrieve documents as DataStorageRecord instances and print them as shown in the following code:

MongoCollection<DataStorageRecord> collection = database.getCollection("data_storage_devices", DataStorageRecord.class);
// retrieve and print the records
List<DataStorageRecord> records = new ArrayList<DataStorageRecord>();
collection.find().into(records);
records.forEach(System.out::println);
DataStorageRecord[productName=1TB SSD, capacity=1.71]

This section describes the annotations you can use to configure the serialization behavior of record components and provides an example to demonstrate the annotation behavior.

Tip

The org.bson.codecs.records.annotations package is deprecated. Use the equivalent ones from the org.bson.codecs.pojo.annotations package instead.

You can use the following annotations on record components:

Annotation Name
Description
BsonId
Specifies the component to serialize as the _id property.
BsonProperty
Specifies a custom document field name when converting the record component to BSON. Accepts the field name as the parameter.
BsonRepresentation
Specifies a BSON type to store when different from the record component type. Accepts the BSON type as the parameter.

Note

The driver supports annotations for Java records, but only if you include them when you define the component as shown in the following example record. You cannot use the annotations inside the record constructor.

The code examples in this section reference the following sample record, which describes a network device:

import org.bson.BsonType;
import org.bson.codecs.pojo.annotations.BsonProperty;
import org.bson.codecs.pojo.annotations.BsonId;
import org.bson.codecs.pojo.annotations.BsonRepresentation;
public record NetworkDeviceRecord(
@BsonId()
@BsonRepresentation(BsonType.OBJECT_ID)
String deviceId,
String name,
@BsonProperty("type")
String deviceType
)
{}

You can insert a DataStorageRecord instance as shown in the following code:

MongoCollection<NetworkDeviceRecord> collection = database.getCollection("network_devices", NetworkDeviceRecord.class);
// insert the record
String deviceId = new ObjectId().toHexString();
collection.insertOne(new NetworkDeviceRecord(deviceId, "Enterprise Wi-fi", "router"));

The inserted document in MongoDB should resemble the following:

{
_id: ObjectId("fedc..."),
name: 'Enterprise Wi-fi',
type: 'router'
}

You can retrieve documents as NetworkDeviceRecord instances and print them as shown in the following code:

MongoCollection<NetworkDeviceRecord> collection = database.getCollection("network_devices", NetworkDeviceRecord.class);
// return all documents in the collection as records
List<NetworkDeviceRecord> records = new ArrayList<NetworkDeviceRecord>();
collection.find().into(records);
records.forEach(System.out::println);
NetworkDeviceRecord[deviceId=fedc..., name=Enterprise Wi-fi, deviceType=router]

The driver natively supports encoding and decoding of recursively defined records without causing runtime recursion. This support extends to cycles of multiple record types in type definitions. The following code provides an example of a recursive record design:

public record RecordTree(
String content,
RecordTree left,
RecordTree right
) {}

You can perform read and write operations on recursively defined records the same way you would for other records. The following code shows how you can execute a find operation on a collection of RecordTree types:

MongoDatabase database = mongoClient.getDatabase("myDB");
MongoCollection<RecordTree> collection = database.getCollection("myCollection", RecordTree.class);
Bson filter = Filters.eq("left.left.right.content", "Ikatere");
collection.find(filter).forEach(doc -> System.out.println(doc));
RecordTree[content=Ranginui, left=RecordTree[content=..., left=RecordTree[content=..., right=RecordTree[content=Ikatere...]]

You can use the RecordCodecProvider to retrieve the record codec. You should use this interface when you want to customize the codec to encode and decode Java record objects to and from corresponding BSON types while minimizing duplicate code. To learn more about codecs and their usage, see Codecs.

You can't create a record codec directly, but you can use the RecordCodecProvider to implement the record codec in your code. Learn more about the RecordCodecProvider, see the API documentation.

Back

Document Data Format: POJOs