Mongo JDBC - JakartaEE library to increase the productivity allowing the developer focus on the logic he needs to work forgetting about Mongodb-JDBC concerns.
Mongo JDBC-JakartaEE library provide below capabilities.
-
It is done on CDI this makes it compatible with Jakarta EE (JavaEE 8) applications and every CDI application.
-
Provide Serializer implementation for ObjectId class.
-
Developer work based on the use of
MongoDatabase
injectable instance. -
Ready to work with Mongodb JDBC Pojo Decoder.
-
Configurable via environment variables.
-
Mongo entity interface provided to create BSON documents based on POJO.
Getting started
Default behaviour
By default the Mongo JDBC - JakartaEE
library will run connecting to localhost
though 27017
port without certificate and creating a database called
avalane
.
This behaviour can be changed setting some environment variables in the host overriding the default values.
Available environment variables
Environment variable Name | Description | Default value |
---|---|---|
MONGO_USERNAME |
User name to connect to MongoDB server |
|
MONGO_PASSWORD |
Password of the defined username |
|
MONGO_SERVER |
Hostname of the MongoDB server |
localhost |
MONGO_PORT |
Port of the MongoDB server |
27017 |
DATABASE_NAME |
Database name |
avalane |
MONGO_OPTIONS |
Mongo options that will be attached in string built if
|
|
BUILD_CONNECTION_STRING |
If |
|
MONGO_CONNECTION_STRING |
Connection string |
|
Mongo JDBC
Mongo JDBC - JakartaEE uses Mongo JDBC driver version 3.10.2.
This library is a transitive dependency what means it is not needed to add the JDBC mongo driver when this library is used, only adding the Mongo JDBC - JakartaEE as dependency it’s enough to start to work with mongo in the application.
The MongodbEntity interface
The Mongo entity interface gives to user the ability to create a BSON object based on the POJO which implements the interface.
Why does this interface exist
The MongodbEntity
was created to provide method toDocument()
which will convert
the entity to a BSON object that can be created to save into database to get the
id, because over POJO codec is not possible to obtain the new ID
after save.
MongoClient
The MongoClient
instance is injectable via CDI as explained below.
@Inject private MongoClient client;
The instance is created when the application is started.
Customizer
In the case of the necessity to create an index the library provides an
interface which can be implemented and this will run as soon as the
MongoDatabase
reference is created.
The interface co.pablob.mongo.boundary.MongodbCustomizer
requires the
implementation of the method customize
which receives a reference of the
database (MongoDatabase
) to make the needed customizations like index
creation.
When multitenant mode is enabled customizer only will run in default database other databases will not apply the customizers. |
Multi-tenant
Since version 1.3.0, there is a strategy to support multi tenant database.
How does it work?
This library creates one MongodbClient instance, this instance is used to provide the database reference which is used by the collections injection.
The collection injector is a generic method which must be @Dependent
scope
and cannot be @RequestScoped
doing this provider not an option when a
multi-tenant behaviour is needed due to the database must be choose based on
each request. On the other hand, the database provider is not a generic
producer method allowing this to be scoped as @RequestScoped
hitting the
connection to the database based on each request.
To achieve a multi-tenant behaviour, the library provide the option to specialize
the class co.pablob.mongo.control.DatabaseNameProvider
which is in charge
to specify to the Database producer what is the database name.|
Examples
Below some examples to clarify the uses this library has.
Working with MongoDatabase
In case you need to work directly with the MongoDatabase
instance, the injection of this instance is available by
@Inject
cdi annotation.
import com.mongodb.client.MongoDatabase;
...
@Inject
private MongoDatabase database;
...
Above example will inject the unique instance of database which is share by the whole application.
Injecting MongoCollection<Document>
To inject a MongoCollection of type org.bson.Document
, follow the below sniped.
@Inject
@Definition(collection = MyEntity.COLLECTION_NAME) (1)
MongoCollection<Document> vanillaCollection; (2)
1 | Use the annotaion @Definition specifying the collection attribute with the collection name. |
2 | Declare the MongoCollection object of type org.bson.Document . |
This collection is useful when you want to save a document and get its id after save. |
Working with MongoCollection<T>
Mongo JDBC - JakartaEE provides a way to inject a MongoCollection specifying the
POJO type of the MongoCollection
.
@Inject
@Definition(collection = MyEntity.COLLECTION_NAME, clazz = MyEntity.class) (1)
MongoCollection<MyEntity> collection; (2)
1 | Use the annotation Definition to specify the definition of the Collection
|
2 | The MongoCollection of the specified type on clazz attribute in step 1. |
Using MongodbEntity interface
The Mongo JDBC - JakartaEE defines a interface to provide the method toDocument()
to your classes.
This method will be useful to convert the actual POJO to a org.bson.Document
object that can be handle by the
Mongo JDBC driver.
import co.pablob.mongo.entity.MongodbEntity; (1)
public MyEntity implements MongodbEntity { (2)
...
}
1 | Import the respective interface. |
2 | Implements this interface in your entity. |
How to get id after save a document
There is a know behaviour in Mongodb JDBC driver, this not allow to get the id of an POJO object just after creation (JAVA-2374).
Because of this, bellow an example of how to obtain this id
using
MongodbEntity
and MongoCollection<Document>
with Mongo JDBC - JakartaEE.
import co.pablob.mongo.entity.MongodbEntity; (1)
public MyEntity implements MongodbEntity { (2)
...
}
(3)
@Inject
@Definition(MyEntity.COLLECTION_NAME)
MongoCollection<Document> vanillaCollection;
...
Document document = myEntity.toDocument(); (4)
vanillaCollection.insertOne(document); (5)
ObjectId id = document.getObjectId("_id"); (6)
System.out.println(id);
1 | Inside the entity import the Interface MongodbEntity |
2 | In the entity, implement the interface MongodbEntity |
3 | In the a vanilla MongoCollection (Inject MongoCollection). |
4 | Use the method toDocument() (Use Mongodb Interface). |
5 | Use the method insertOne from the MongoCollection instance. |
6 | From the document, obtain the value of the id (ObjectId) |
How to create indexes
When there is the necessity to create index into your database proceed based on below example.
public class Indexer implements MongodbCustomizer { @Override public void customize(MongoDatabase mongoDatabase) { MongoCollection<Document> collection = mongoDatabase.getCollection("collection");
IndexOptions options = new IndexOptions(); options.unique(true);
collection.createIndex(Indexes.ascending("unq_field"), options); } }
Multi-tenant based on user
On this example let’s assume the database will depend on the user and we can get the user information via CDI Injection.
@Specializes (1) public class MultiTenantDatabaseNameProvider extends DatabaseNameProvider { (2) @Inject private JwtPrincipal principal; (3) @Override public String produceDatabaseName() { return principal.getDatabase(); (4) } } public class MyService { @Inject private Database database; (5) public void doSomething() { Collection collection = database.getCollection("colection_name"); (6) ... } }
-
The class must be an specialization, this can achieved annotation the class
Specializes
fromjavax.enterprise.inject
package. -
The class must extends
co.pablob.mongo.control.DatabaseNameProvider
. -
In this example, the user information is stored in
JwtPrincipal
object so the injection of this instance is done (CDI injection is supported in this point). -
In the
produceDatabaseName
method overwriting a String is returned, this String is the database name that will be used in Database reference instantiation. -
Now, on our service or where we needed, we can inject the database and this will reference the database specified in the
DatabaseNameProvider
specialized class. -
Use this instance to access the collection and do whatever you need.