@@ -13,17 +13,218 @@ Document Data Format: POJOs
1313Overview
1414--------
1515
16- - Description; convert between BSON and POJOs
17- - Summary of contents of this doc
16+ This guide explains how you can store and retrieve MongoDB data using plain
17+ old Java objects (`POJOs <https://en.wikipedia.org/wiki/Plain_old_Java_object>`__).
18+ POJOs are often used for data encapsulation, separating business logic from
19+ data representation.
1820
19- CodecRegistry
20- -------------
21+ In the following sections we show:
2122
22- - Brief introduction, link to data-formats/codecs for more info
23- - Example demonstrating the following:
24- - specifying how to create a CodecRegistry that uses PojoCodecProvider
25- - example POJO class with getters/setters
26- - include user-defined classes and lists
27- - Sample input/output of aforementioned example
23+ - a POJO example
24+ - how to configure the driver to serialize and deserialize the POJO
25+ - sample code to read and write documents to MongoDB using the POJO
2826
29- - Link to data-formats/pojo-customization for more information
27+ .. _fundamentals-example-pojo:
28+
29+ Example POJO
30+ ------------
31+
32+ To follow the steps in this guide, you can create your own class or use the
33+ following sample POJO class which describes characteristics of a flower:
34+
35+ .. code-block:: java
36+
37+ public class Flower {
38+
39+ private ObjectId id;
40+ private String name;
41+ private List<String> colors;
42+ private Boolean isBlooming;
43+ private Float height;
44+
45+ // public empty constructor needed for retrieving the POJO
46+ public Flower() {}
47+
48+ public Flower(String name, Boolean isBlooming, Float height, List<String> colors) {
49+ this.name = name;
50+ this.isBlooming = isBlooming;
51+ this.height = height;
52+ this.colors = colors;
53+ }
54+
55+ public ObjectId getId() {
56+ return id;
57+ }
58+
59+ public void setId(ObjectId id) {
60+ this.id = id;
61+ }
62+
63+ public String getName() {
64+ return name;
65+ }
66+
67+ public void setName(String name) {
68+ this.name = name;
69+ }
70+
71+ public Boolean getIsBlooming() {
72+ return isBlooming;
73+ }
74+
75+ public void setIsBlooming(Boolean isBlooming) {
76+ this.isBlooming = isBlooming;
77+ }
78+
79+ public Float getHeight() {
80+ return height;
81+ }
82+
83+ public void setHeight(Float height) {
84+ this.height = height;
85+ }
86+
87+ public List<String> getColors() {
88+ return colors;
89+ }
90+
91+ public void setColors(List<String> colors) {
92+ this.colors = colors;
93+ }
94+
95+ @Override
96+ public String toString() {
97+ return "Flower [id=" + id + ", name=" + name + ", colors=" + colors + ", isBlooming=" + isBlooming + ", height=" + height + "]";
98+ }
99+ }
100+
101+ If you are creating your own POJO for storing and retrieving data in MongoDB,
102+ make sure to follow the following guidelines:
103+
104+ - The POJO class should not implement interfaces or extend classes from a
105+ framework.
106+ - Include all the fields for which you want to store and retrieve data;
107+ make sure they are not ``static`` or ``transient``.
108+ - If you include public getter or setter methods using the
109+ `JavaBean naming conventions <https://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html>`__
110+ in your POJO, the driver calls them when serializing or deserializing data.
111+ If you omit the getter or setter methods for a public property field, the
112+ driver accesses or assigns them directly.
113+
114+ Configure the Driver for POJOs
115+ ------------------------------
116+
117+ To set up the driver to store and retrieve POJOs, we need to specify:
118+
119+ - The ``PojoCodecProvider``, a codec provider that includes
120+ :doc:`Codecs </fundamentals/data-formats/codecs>` that define how to
121+ encode/decode the data between the POJO and MongoDB document, and which
122+ POJO classes or packages that the Codecs should apply to.
123+ - A :java-docs:`CodecRegistry <apidocs/bson/org/bson/codecs/configuration/CodecRegistry.html>`
124+ instance that contains the codec provider and other related information.
125+ - A ``MongoClient``, ``MongoDatabase``, or ``MongoCollection`` instance
126+ configured to use the ``CodecRegistry``.
127+ - A ``MongoCollection`` instance created with the POJO document class
128+ bound to the :java-docs:`TDocument </apidocs/mongodb-driver-sync/com/mongodb/client/MongoCollection.html>`__
129+ generic type.
130+
131+ Follow the steps below to see how to perform each of the configuration
132+ requirements:
133+
134+
135+ 1. Configure the :java-docs:`PojoCodecProvider <apidocs/bson/org/bson/codecs/pojo/PojoCodecProvider.html>`,
136+ a codec provider that provides the Codecs that define how to encode the data
137+ and on which classes to apply the Codecs. In this example, we use the
138+ :java-docs:`automatic(true) <apidocs/bson/org/bson/codecs/pojo/PojoCodecProvider.Builder.html#automatic(boolean)>`
139+ setting of the :java-docs:`PojoCodecProvider.Builder <apidocs/bson/org/bson/codecs/pojo/PojoCodecProvider.Builder.html>`
140+ to apply the Codecs to any class and its properties.
141+
142+ .. code-block:: java
143+
144+ CodecProvider pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build();
145+
146+ .. note::
147+
148+ Codec providers also contain other objects such as ``ClassModel`` and
149+ ``Convention`` instances that further define serialization behavior.
150+ For more information on codec providers and customization, see our guide
151+ on :doc:`POJO Customization </fundamentals/data-formats/pojo-customization>`.
152+
153+
154+ #. Add the ``PojoCodecProvider`` instance to a ``CodecRegistry``. The
155+ ``CodecRegistry`` allows you to specify one or more codec providers to
156+ encode the POJO data. In this example, we call the following methods:
157+
158+ - :java-docs:`fromRegistries() <apidocs/bson/org/bson/codecs/configuration/CodecRegistries.html#fromRegistries(org.bson.codecs.configuration.CodecRegistry...)>`
159+ to combine multiple ``CodecRegistry`` instances into a single one
160+ - :java-docs:`getDefaultCodecRegistry() <apidocs/mongodb-driver-core/com/mongodb/MongoClientSettings.html?is-external=true#getDefaultCodecRegistry()>`
161+ to retrieve a ``CodecRegistry`` instance from a list of codec providers
162+ - :java-docs:`fromProviders() <apidocs/bson/org/bson/codecs/configuration/CodecRegistries.html#fromProviders(org.bson.codecs.configuration.CodecProvider...)>`
163+ to create a ``CodecRegistry`` instance from the ``PojoCodecProvider``
164+
165+ See the code below to see how to instantiate the ``CodecRegistry``:
166+
167+ .. code-block:: java
168+
169+ // ensure you use the following static imports above your class definition
170+ import static com.mongodb.MongoClientSettings.getDefaultCodecRegistry;
171+ import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
172+ import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
173+
174+ // ...
175+
176+ CodecRegistry pojoCodecRegistry = fromRegistries(getDefaultCodecRegistry(), fromProviders(pojoCodecProvider));
177+
178+ #. Configure our ``MongoClient``, ``MongoDatabase``, or ``MongoCollection``
179+ instance to use the Codecs in the ``CodecRegistry``. You only need to
180+ configure one of these. In this example, we set the ``CodecRegistry`` on a
181+ ``MongoDatabase`` called ``sample_pojos`` using the ``withCodecRegistry()``
182+ method.
183+
184+ .. code-block:: java
185+
186+ try (MongoClient mongoClient = MongoClients.create(uri)) {
187+ MongoDatabase database = mongoClient.getDatabase("sample_pojos").withCodecRegistry(pojoCodecRegistry);
188+ // ...
189+ }
190+
191+ #. Pass your POJO class to your call to ``getCollection()`` as the
192+ document class parameter and specify it as the type argument of your
193+ ``MongoCollection`` instance as follows:
194+
195+ .. code-block:: java
196+
197+ MongoCollection<Flower> collection = database.getCollection("flowers", Flower.class);
198+
199+ Once you have configured the ``MongoCollection`` instance above, you can:
200+
201+ - save an instance of the POJO to the collection
202+ - retrieve instances of the POJO from a query on the collection
203+
204+ The code below shows you how you can insert an instance of ``Flower`` into
205+ the collection and then retrieve it as a ``List`` of your POJO class objects:
206+
207+ .. code-block:: java
208+
209+ Flower flower = new Flower("rose", false, 25.4f, Arrays.asList(new String[] {"red", "green"}));
210+
211+ // insert the instance
212+ collection.insertOne(flower);
213+
214+ // return all documents in the collection
215+ List<Flower> flowers = new ArrayList<>();
216+ collection.find().into(flowers);
217+ System.out.println(flowers);
218+
219+ When you run this code, your output should resemble the following:
220+
221+ .. code-block:: none
222+ :copyable: false
223+
224+ [Flower [id=5f7f87659ed5b07cf3480a06, name=rose, colors=[green, red], isBlooming=false, height=25.4]]
225+
226+ .. note::
227+
228+ By default, the ``PojoCodecProvider`` omits fields in your POJO that are
229+ set to ``null``. For more information on how to specify this behavior, see
230+ our guide on :doc:`POJO Customization </fundamentals/data-formats/pojo-customization>`.
0 commit comments