I am currently developing a Grails plugin using Grails 2.3.11 and familiar using multiple datasources. But now I want that my domain objects provided by that plugin CAN use a different dataSource (because of performance reasons all data can be stored in a different database).
The problem is, that this second datasource is optional, which means, the user can define a second datasource in tomcat (accessible via JNDI), but doesn't have to. This is an important point: the user can define a second dataSource in the servlet container and the Grails application has to check if there is a second dataSource available!
Be to more specific: I've a domain class:
class MyDomain {
static mapping = {
datasource('optionalDS')
}
}
My DataSource.groovy:
dataSource {
jndiName = "..."
}
dataSource_optionalDS {
jndiName = "..."
}
The problem is, that this will fail if the user hasn't configured the JNDI name for that optional datasource (because it is optional, he doesn't have to).
I tried to create a delegating datasource instead:
class OptionalDataSource extends DelegatingDataSource {
...
// the main purpose is to check, if the optional DS
// can be created using JNDI. If this fails, the default
// DS is used
setTagetDataSource(dataSource)
...
}
And in my Plugin descriptor:
def doWithSpring = {
dataSource_optionalDS(OptionalDataSource) {
// set default DS in case optional can not be created
dataSource = ref('dataSource')
}
}
The problem with this solution is, that the dataSource optionalDS is not available. If I try to read data, i.e. MyDomain.findAll() I get the following error:
Methond on class MyDomain was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.
I don't understand why, because I can define the default dataSource that way.
So, my question is: How can I define an optional dataSource in Grails?
How about looking up the JNDI dataSource
in DataSource.groovy
and then if it exists declaring your optional dataSource
. Something like following
//default dataSource
dataSource {
jndiName = "..."
}
//optional dataSource
//let's first lookup the JNDI dataSource
def jndiDataSource
try {
jndiDataSource = InitialContext.doLookup("...")
}
catch(NamingException ne) {}
//now if jndiDataSource exists we can declare the optional dataSource
if(jndiDataSource) {
dataSource_optionalDS {
jndiName = "..."
}
}
I was looking for an alternate lightwight method for just checking if the JNDI dataSource
exists instead of looking it up. But no luck.