(Quick Reference)

11 Multiple Data Sources

Version: 2023.3.0-SNAPSHOT

11 Multiple Data Sources

GORM supports the notion of multiple data sources where multiple individual SQL DataSource instances can be configured and switched between.

11.1 Configuring Multiple Data Sources

To configure multiple data sources you need to use the dataSources setting. For example in application.yml:

dataSource:
    pooled: true
    dbCreate: create-drop
    url: jdbc:h2:mem:books
    driverClassName: org.h2.Driver
    username: sa
    password:
dataSources:
    moreBooks:
        url: jdbc:h2:mem:moreBooks
        hibernate:
            readOnly: true
    evenMoreBooks:
        url: jdbc:h2:mem:evenMoreBooks

You can configure individual settings for each data source. If a setting is not specified by default the setting is inherited from the default data source, so in the example above there is no need to specify the driverClassName for each data source if the same driver is used for all.

For more information on configuration see the Configuration section.

11.2 Mapping Domain Classes to Data Sources

If a domain class has no DataSource configuration, it defaults to the standard 'dataSource'. Set the datasource property in the mapping block to configure a non-default DataSource. For example, if you want to use the ZipCode domain to use a DataSource called 'lookup', configure it like this:

class ZipCode {

   String code

   static mapping = {
      datasource 'lookup'
   }
}

A domain class can also use two or more configured DataSource instances. Use the datasources property with a list of names to configure more than one, for example:

class ZipCode {

   String code

   static mapping = {
      datasources(['lookup', 'auditing'])
   }
}

If a domain class uses the default DataSource and one or more others, you can use the ConnectionSource.DEFAULT constant to indicate that:

import org.grails.datastore.mapping.core.connections.*

class ZipCode {

   String code

   static mapping = {
      datasources(['lookup', ConnectionSource.DEFAULT])
   }
}

If a domain class uses all configured DataSource instances use the value ALL:

import org.grails.datastore.mapping.core.connections.*

class ZipCode {

   String code

   static mapping = {
      datasource ConnectionSource.ALL
   }
}

11.3 Data Source Namespaces

If a domain class uses more than one DataSource then you can use the namespace implied by each DataSource name to make GORM calls for a particular DataSource. For example, consider this class which uses two DataSource instances:

class ZipCode {

   String code

   static mapping = {
      datasources(['lookup', 'auditing'])
   }
}

The first DataSource specified is the default when not using an explicit namespace, so in this case we default to 'lookup'. But you can call GORM methods on the 'auditing' DataSource with the DataSource name, for example:

def zipCode = ZipCode.auditing.get(42)
...
zipCode.auditing.save()

As you can see, you add the DataSource to the method call in both the static case and the instance case.

11.4 The ConnectionSources API

Introduced in GORM 6.0, the ConnectionSources API allows you to introspect the data sources configured for the application:

@Autowired
HibernateDatastore hibernateDatastore
...
ConnectionSources<SessionFactory, HibernateConnectionSourceSettings> connectionSources
                                        = hibernateDatastore.getConnectionSources()

for(ConnectionSource<SessionFactory, HibernateConnectionSourceSettings> connectionSource in connectionSources) {
        println "Name $connectionSource.name"
        SessionFactory sessionFactory = connectionSource.source
}