Building a CRUD Web Application Using Grails 6 and MongoDB

by Didin J. on Jun 15, 2025 Building a CRUD Web Application Using Grails 6 and MongoDB

Build a CRUD web app with Grails 6 and MongoDB using updated Mongo GORM, RESTful controllers, and modern Grails Forge—step-by-step for 2025.

In early 2025, Grails 6.2.3 was released, built on top of Spring Boot 2.7.x, Gradle 7.6+, and requiring Java 11+—with key bug fixes and dependency upgrades endoflife.date+14grails.org+14newreleases.io+14grails.org+2medium.com+2grails.org+2. This makes it the current stable baseline for new Java/Groovy web applications, including MongoDB-powered CRUD systems, so let’s update our Grails tutorial accordingly.

In this guide, we'll walk you through building a CRUD (Create, Read, Update, Delete) app using Grails 6.2.3, GORM for MongoDB, and RESTful controllers. You’ll learn how to leverage updated conventions and Grails Forge tooling for a clean, modern setup.

In this tutorial, we will use more than one entity that relates to each other using one-to-one, one-to-many, and many-to-many relationships. All relationships use the Grails domain class. For more details, you can see this entity relationship diagram.

Building CRUD Web Application using Grails 4 and MongoDB Easily - ERD

The above diagram describes a one-to-one relationship between the Teacher and the Lesson, a one-to-many relationship between the Classroom and the Students, and a many-to-many relationship between the Students and the Lessons. Using that relational Domain class, we will build the CRUD (create, read, update, delete) operations using the web form.

The following tools, frameworks, and libraries are required for this tutorial:

  1. JDK 17
  2. Grails 6.2.3
  3. MongoDB
  4. Grails MongoDB plugin
  5. Terminal or Command Line
  6. Text Editor or IDE

Before the move to the main steps, make sure you have installed JDK 17, MongoDB.


Prerequisites & Setup

There are various and different ways to install the Grails web application, depending on the operating system. If you are using macOS terminal, the easiest way to install Grails is to use the SDKMan. Simply run this command from the terminal to install it.

sdk install grails 6.2.3

The Groovy language will be included in the Grails installation bundle. For the Windows platform, just download the compressed Grails binary from the Grails download page, then extract that Grails folder to the specific directory wherever you like. Add the Grails folder to the environment variable and the path to make the Grails command available in the Windows Command line. To check the installed Grails version, type this command.

grails --version
Grails Version: 6.2.3
JVM Version: 17.0.9

Next, create a new Grails application by typing this command.

grails create-app grails-crud

To work in the Grails interactive console, type this command after going to the newly created Grails application folder.

cd ./grails-crud
grails

Run Grails for the first time by typing this command from the root of the project.

cd ..
./gradlew bootRun

Open the browser, then point to `http://localhost:8080` and you will see the Grails application home page.

Building CRUD Web Application using Grails 4 and MongoDB Easily - Home Page


Install and Configure MongoDB Plugin

We will use MongoDB as the primary Datastore for this Grails application. So, we have to disable or uninstall the Hibernate plugin from this application. Open the Grails project in your IDE or text editor, then open and edit the `build.gradle` file. Comment out the Hibernate plugin and related. Then add the Grails MongoDB plugin to that file in the dependencies bracket.

dependencies {
    ...
    implementation "org.grails.plugins:mongodb"
    ...
}

Next, compile the Grails application using this command.

./gradlew clean

Next, configure the MongoDB connection by opening and editing `grails-app/conf/application.yml`, then comment out the Hibernate and H2 database connections while adding the connection for the MongoDB.

# hibernate:
#     cache:
#         queries: false
#         use_second_level_cache: false
#         use_query_cache: false
# dataSource:
#     pooled: true
#     jmxExport: true
#     driverClassName: org.h2.Driver
#     username: sa
#     password: ''

environments:
    # development:
    #     dataSource:
    #         dbCreate: create-drop
    #         url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    # test:
    #     dataSource:
    #         dbCreate: update
    #         url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    # production:
    #     dataSource:
    #         dbCreate: none
    #         url: jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    #         properties:
    #             jmxEnabled: true
    #             initialSize: 5
    #             maxActive: 50
    #             minIdle: 5
    #             maxIdle: 25
    #             maxWait: 10000
    #             maxAge: 600000
    #             timeBetweenEvictionRunsMillis: 5000
    #             minEvictableIdleTimeMillis: 60000
    #             validationQuery: SELECT 1
    #             validationQueryTimeout: 3
    #             validationInterval: 15000
    #             testOnBorrow: true
    #             testWhileIdle: true
    #             testOnReturn: false
    #             jdbcInterceptors: ConnectionState
    #             defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED
    development:
        grails:
            mongodb:
                host: "localhost"
                port: 27017
                username: ""
                password: ""
                databaseName: "grails-crud"
    production:
        grails:
            mongodb:
                host: "localhost"
                port: 27017
                username: ""
                password: ""
                databaseName: "grails-crud"


Create the Grails Domain Classes

One of the Grails' great features is building entities easily just by creating a domain class. Right here, we will translate the Entity Relationship Diagram to the Grails domain class. For that, type these commands.

grails create-domain-class grails.crud.Teacher
grails create-domain-class grails.crud.Student
grails create-domain-class grails.crud.Lesson
grails create-domain-class grails.crud.Classroom

Next, open and edit `grails-app/domain/grails/crud/Teacher.groovy`, then insert these lines of field codes inside the class bracket.

String teacherName
static hasOne = [lesson: Lesson]

That field has a one-to-one relationship with the Lesson class. Next, add the mapping method after the constraint method to give an index to this MongoDB collection.

static mapping = {
    teacherName index: true
}

Add the blank constraint for the lesson field; otherwise, it will be mandatory in the CRUD views.

static constraints = {
    lesson blank: true, nullable: true
}

Also, add these lines of Groovy code to make the Teacher domain show up as the teacher's name in the views.

String toString() {
    teacherName
}

Next, open and edit `grails-app/domain/grails/crud/Lesson.groovy`, then insert these lines of field codes inside the class bracket.

String lessonName
Integer lessonHour
Teacher teacher
static hasMany = [students: Student]

That field has a one-to-one relationship with the Teacher class, a many-to-many relationship with the Student class. Next, add the mapping method after the constraint method to give an index to this MongoDB collection.

static mapping = {
    lessonName index: true
}

Add the blank constraint for the teacher field; otherwise, it will be mandatory in the CRUD views.

static constraints = {
    teacher blank: true, nullable: true
}

Also, add these lines of Groovy code to make the Lesson domain show up as the lesson name in the views.

String toString() {
    lessonName
}

Next, open and edit `grails-app/domain/grails/crud/Student.groovy`, then insert these lines of field codes inside the class bracket.

String studentName
static hasMany = [lessons: Lesson]
static belongsTo = [Classroom]

That field has a many-to-many relationship with the Lesson class, and a one-to-many relationship with the Classroom class. Next, add the mapping method after the constraint method to give an index to this MongoDB collection.

static mapping = {
    studentName index: true
}

Add these lines of Groovy code to make the Student domain show up as the student's name in the views.

String toString() {
    studentName
}

Next, open and edit `grails-app/domain/grails/crud/Classroom.groovy`, then insert these lines of field codes inside the class bracket.

String classroomName
static hasMany = [students: Student]

That field has a one-to-many relationship with the Student class. Next, add the mapping method after the constraint method to give an index to this MongoDB collection.

static mapping = {
    classroomName index: true
}

Add these lines of Groovy code to make the Classroom domain show up as the classroom name in the views.

String toString() {
    classroomName
}

The domain classes will generate an ID with an auto-increment number. You will see later in the MongoDB that the ID type will be `NumberLong` type. Optionally, if you want to use a standard MongoDB Object ID for the ID, just add this line to the fields.

ObjectId id

And import that object.

import org.bson.types.ObjectId


Generate the Grails Controller and View for All Domains

The quickest way to create controllers and views is to generate them using this command.

./gradlew runCommand -Pargs="generate-all grails.crud.Teacher" 
./gradlew runCommand -Pargs="generate-all grails.crud.Lesson" 
./gradlew runCommand -Pargs="generate-all grails.crud.Student" 
./gradlew runCommand -Pargs="generate-all grails.crud.Classroom" 

Now, you have a complete CRUD (Create, Read, Update, Delete) web application scaffolding. You may check the controller Groovy file and GSP file (view) to learn how the scaffolding of the Grails web application works.


Run and Test the Complete Grails and MongoDB CRUD Web Application

Before running the application, make sure you have run the MongoDB daemon. If the MongoDB daemon is not running automatically, you can run it manually using this command in a different terminal tab.

mongod

Next, you can start the Grails 4 application inside the Grails 4 interactive console by just typing this command.

./gradlew bootRun

And here we go, in the browser, you can point to `http://localhost:8080/` and you will see the previous Grails page with an additional Grails controller link.

Building a CRUD Web Application Using Grails 6 and MongoDB - Home Page with Controller list
Building a CRUD Web Application Using Grails 6 and MongoDB - Add Data
Building a CRUD Web Application Using Grails 6 and MongoDB - Show Data

It's the tutorial on building a CRUD Web Application using Grails and MongoDB easily. You can get the full source code from our GitHub.

That's just the basics. If you need more deep learning about Groovy and Grails, you can take the following cheap course:

Thanks!