How about using what you've just read?

Grails has a lot of features making it near impossible to you use all of them in your project. The framework covers almost all need I have ever had in the last 10 years, but as I said, there is a lot of features I have never touched. So, I decided to re-read the whole Grails User Guide — yes — , and make some simple examples and code snippets using these features I've never did.

You know… All Grails users should do this, because those features you don’t need it all time, you just forgot how to use it, and when you need, you’ll probably find some struggles to fight.

Reading on Multiple Datasources, I thought: Why in the hell I have never had a chance to use this? In fact, I have one project that have multiple databases, but we have different deploys that points to the different databases. (In this case we needed to deploy a cluster of machines querying in readonly replica of our master database — to do this we’ve used AWS RDS Read Replicas. If you haven’t had a chance to look on this yet, go ahead now, it is an awesome aws feature).

So, let’s do this and configure our application. I’ve commited all this code in this repo: https://github.com/lucastex/grails-multids/ and you can find detailed docs in this gorm doc page and in this grails doc page.

Configuration

The first point is to create more than one node in our datasource configuration in the application.yml file. You have to name your first datasource as datasource, there is no other option. You can have different names for your second, third, and others datasources, but you’ll have to have one named this way. This is necessary so grails can handle this datasource as your default one.

environments:
development:
dataSources:
dataSource:
dbCreate:
update
driverClassName: org.mariadb.jdbc.Driver
username: root
password: root
url: jdbc:mariadb://localhost:3306/grails-multids-1
serverdb:
dbCreate:
update
driverClassName: org.mariadb.jdbc.Driver
username: root
password: root
url: jdbc:mariadb://localhost:3306/grails-multids-2
userdb:
dbCreate:
update
driverClassName: org.mariadb.jdbc.Driver
username: root
password: root
url: jdbc:mariadb://localhost:3306/grails-multids-3

You’ll have to select which domain classes you’ll handle with more than one datasources, you’ll do this using the mapping declaration in your domain class as show below

package multids

class Contact {

String name

static mapping = {
datasource 'ALL'
}
}

Usage

That’s it, after that you’ll have to add the datasource name (when not using the default one) between the domain class name and operation name like this

<domain class>.<datasource name>.<operaration>

Bringing to our real world example

Contact.serverdb.findAll()

or

contact.userdb.save()

That's it

Watch out!

In my first experiments, when trying to query the non-default datasources, grails was throwing an error, that classic no session found for current threaderror. I’ve googled a little bit and found this issue: https://github.com/grails/grails-core/issues/10383 where Graeme Rocher (the grails creator and leader at OCI) explain that since Gorm 6, the OpenSessionInViewInterceptor is not multi datasource anymore. He says

Because it is wasteful to open a connection for every request for every data source and it doesn’t scale, so it isn’t a sensible default.

And this is for sure correct, you don’t want to waste resources, do you? So, when querying and saving in the non-default datasource, for now you’ll have to use withTransaction method, like I’ve did in my controller here https://github.com/lucastex/grails-multids/blob/master/grails-app/controllers/multids/ContactController.groovy

Keep reading what you think you already know

That’s it, I’ve read and done this example in a couple hours, finding some issues and difficulties and searching for how to handle them. I recommend you all the same, get some time and re-read the grails user guide, try to use features you know exists but have never tried.

Keep coding.