(Quick Reference)

2 Getting Started - Reference Documentation

Authors: Graeme Rocher, Burt Beckwith

Version: 5.0.8.RELEASE

2 Getting Started

To get started with GORM for MongoDB you need configure it as a dependency in build.gradle:

dependencies {
	compile 'org.grails.plugins:mongodb:VERSION'
}

Note, in newer versions of Grails it may be require to enforce the necessary dependencies. If you get errors on startup it is likely due to a dependency problem. The following block will ensure the correct dependencies are in place:

dependencies {
    compile "org.grails.plugins:mongodb:VERSION"
    compile "org.mongodb:mongodb-driver:3.0.2"
    runtime 'org.springframework.data:spring-data-mongodb:1.8.1.RELEASE'
}

The spring-data-mongodb is not required by GORM for MongoDB, but there is a bug in Spring Boot 1.3 M2 which means that if you are using the MongoDB driver with Grails 3.1 M2 you will get an exception without this dependency. This bug is resolved in Spring Boot 1.3 RC1.

For Grails 2.x you need to modify BuildConfig.groovy:

plugins {
 compile ':mongodb:VERSION'
}

With that done you need to set up a running MongoDB server. Refer to the MongoDB Documentation for an explanation on how to startup a MongoDB instance. Once installed, starting MongoDB is typically a matter of executing the following command:

MONGO_HOME/bin/mongod

With the above command executed in a terminal window you should see output like the following appear:

2015-11-18T19:38:50.073+0100 I JOURNAL  [initandlisten] journal dir=/data/db/journal
2015-11-18T19:38:50.073+0100 I JOURNAL  [initandlisten] recover : no journal files present, no recovery needed
2015-11-18T19:38:50.090+0100 I JOURNAL  [durability] Durability thread started
2015-11-18T19:38:50.090+0100 I JOURNAL  [journal writer] Journal writer thread started
2015-11-18T19:38:50.090+0100 I CONTROL  [initandlisten] MongoDB starting : pid=52540 port=27017 dbpath=/data/db 64-bit host=Graemes-iMac.local
2015-11-18T19:38:50.090+0100 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2015-11-18T19:38:50.090+0100 I CONTROL  [initandlisten]
2015-11-18T19:38:50.090+0100 I CONTROL  [initandlisten]
2015-11-18T19:38:50.090+0100 I CONTROL  [initandlisten] ** WARNING: soft rlimits too low. Number of files is 256, should be at least 1000
2015-11-18T19:38:50.090+0100 I CONTROL  [initandlisten] db version v3.0.4
2015-11-18T19:38:50.090+0100 I CONTROL  [initandlisten] git version: 0481c958daeb2969800511e7475dc66986fa9ed5
2015-11-18T19:38:50.090+0100 I CONTROL  [initandlisten] build info: Darwin mci-osx108-11.build.10gen.cc 12.5.0 Darwin Kernel Version 12.5.0: Sun Sep 29 13:33:47 PDT 2013; root:xnu-2050.48.12~1/RELEASE_X86_64 x86_64 BOOST_LIB_VERSION=1_49
2015-11-18T19:38:50.090+0100 I CONTROL  [initandlisten] allocator: system
2015-11-18T19:38:50.090+0100 I CONTROL  [initandlisten] options: {}
2015-11-18T19:38:50.176+0100 I NETWORK  [initandlisten] waiting for connections on port 27017

As you can see the server is running on port 27017, but don't worry the MongoDB plugin for Grails will automatically configure itself to look for MongoDB on that port by default.

If you want to configure how Grails connects to MongoDB then you can do so using the following settings in grails-app/conf/application.yml:

grails:
    mongodb:
        host: "localhost"
        port: 27017
        username: "blah"
        password: "blah"
        databaseName: "foo"

2.1 Using MongoDB Standalone

If you plan to use MongoDB as your primary datastore then you need to remove the Hibernate plugin from the build.gradle file by commenting out the hibernate line in the plugins block

compile 'org.grails.plugins:hibernate'

With this done all domain classes in grails-app/domain will be persisted via MongoDB and not Hibernate. You can create a domain class by running the regular create-domain-class command:

grails create-domain-class Person

The Person domain class will automatically be a persistent entity that can be stored in MongoDB.

2.2 Combining MongoDB and Hibernate

If you have both the Hibernate and Mongo plugins installed then by default all classes in the grails-app/domain directory will be persisted by Hibernate and not Mongo. If you want to persist a particular domain class with Mongo then you must use the mapWith property in the domain class:

static mapWith = "mongo"

2.3 Advanced Configuration

Mongo Database Connection Configuration

As mentioned the GORM for MongoDB plugin will configure all the defaults for you, but if you wish to customize those defaults you can do so in the grails-app/conf/application.groovy file:

grails {
    mongodb {
        host = "localhost"
        port = 27017
        username = "blah"
        password = "blah"
        databaseName = "foo"
    }
}

The databaseName setting configures the default database name. If not specified the databaseName will default to the name of your application.

You can also customize the MongoDB connection settings using an options block:

grails {
    mongodb {
        options {
            autoConnectRetry = true
            connectTimeout = 300
        }
    }
}

Available options and their descriptions are defined in the MongoOptions javadoc.

In production scenarios you will typically use more than one MongoDB server in either master/slave or replication scenarios. The plugin allows you to configure replica sets:

grails {
    mongodb {
        replicaSet = [ "localhost:27017", "localhost:27018"]
    }
}

The replica sets are defined using a list of strings that conform to the MongoDB DBAddress specification.

MongoDB Connection Strings

Since 2.0, you can also use MongoDB connection strings to configure the connection:

grails {
    mongodb {
        connectionString = "mongodb://localhost/mydb"
    }
}

Using MongoDB connection strings is currently the most flexible and recommended way to configure MongoDB connections.

SSL Connections

You can configure SSL connections by setting ssl to true in the options block:

grails {
    mongodb {
        …
        options {
            ssl = true
            …
        }
    }
}

Note you can also configure the SSLSocketFactory manually if necessary. All settings within the options block are propagated to the underlying MongoOptionsFactoryBean

Configuration Options Guide

Below is a complete example showing all configuration options:

grails {
    mongodb {
        databaseName = "myDb" // the default database name
        host "localhost" // the host to connect to
        port = 27017 // the port to connect to
        username = ".." // the username to connect with
        password = ".." // the password to connect with
        stateless = false // whether to use stateless sessions by default

// Alternatively, using 'replicaSet' or 'connectionString' // replicaSet = [ "localhost:27017", "localhost:27018"] // connectionString = "mongodb://localhost/mydb"

options { connectionsPerHost = 10 // The maximum number of connections allowed per host threadsAllowedToBlockForConnectionMultiplier = 5 maxWaitTime = 120000 // Max wait time of a blocking thread for a connection. connectTimeout = 0 // The connect timeout in milliseconds. 0 == infinite socketTimeout = 0 // The socket timeout. 0 == infinite socketKeepAlive = false // Whether or not to have socket keep alive turned on writeConcern = new com.mongodb.WriteConcern(0, 0, false) // Specifies the number of servers to wait for on the write operation, and exception raising behavior sslEnabled = false // Specifies if the driver should use an SSL connection to Mongo socketFactory = … // Specifies the SocketFactory to use for creating connections } } }

Global Mapping Configuration

Using the grails.mongodb.default.mapping setting in grails-app/conf/application.groovy you can configure global mapping options across your domain classes. This is useful if, for example, you want to disable optimistic locking globally or you wish to use DBRefs in your association mappings. For example, the following configuration will disable optimistic locking globally and use DBRefs for all properties:

grails.mongodb.default.mapping = {
    version false
    '*'(reference:true)
}

The * method is used to indicate that the setting applies to all properties.

2.4 Using GORM in Spring Boot

To use GORM for MongoDB in Spring Boot add the necessary dependencies to your Boot application:

compile("org.grails:gorm-mongodb-spring-boot:VERSION")

Ensure your Boot Application class is annotated with ComponentScan, example:

import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.context.annotation.*

@Configuration @EnableAutoConfiguration @ComponentScan class Application { static void main(String[] args) { SpringApplication.run Application, args } }

Using ComponentScan without a value results in Boot scanning for classes in the same package or any package nested within the Application class package. If your GORM entities are in a different package specify the package name as the value of the ComponentScan annotation.

Finally create your GORM entities and ensure they are annotated with grails.persistence.Entity:

import grails.persistence.*

@Entity class Person { String firstName String lastName }

2.5 GORM for MongoDB without Grails

If you wish to use GORM for MongoDB outside of a Grails application you should declare the necessary dependencies, for example in Gradle:

compile "org.grails:grails-datastore-gorm-mongodb:VERSION"

Then annotate your entities with the grails.gorm.annotation.Entity annotation:

@Entity
class Person {
    String name
}

Then you need to place the bootstrap logic somewhere in the loading sequence of your application which uses MongoDbDataStoreSpringInitializer:

def initializer = new MongoDbDataStoreSpringInitializer(Person)
def applicationContext = initializer.configure()

println Person.count()

For configuration you can either pass a map or an instance of the org.springframework.core.env.PropertyResolver interface:

def initializer = new MongoDbDataStoreSpringInitializer(['grails.mongodb.url':'http://myserver'], Person)
def applicationContext = initializer.configure()

println Person.count()

If you are using Spring with an existing ApplicationContext you can instead call configureForBeanDefinitionRegistry prior to refreshing the context. You can pass the Spring Environment object to the constructor for configuration:

ApplicationContext myApplicationContext = …
def initializer = new MongoDbDataStoreSpringInitializer(myApplicationContext.getEnvironment(), Person)
initializer.configureForBeanDefinitionRegistry(myApplicationContext)

println Person.count()