在Grails

时间:2015-09-04 08:02:20

标签: grails datasource multiple-databases

我目前正在使用Grails 2.3.11开发Grails插件,熟悉使用多个数据源。但是现在我想要那个插件提供的域对象可以使用不同的dataSource(由于性能原因,所有数据都可以存储在不同的数据库中)。

问题是,第二个数据源是可选的,这意味着,用户可以在tomcat中定义第二个数据源(可通过JNDI访问),但不是必须的。这一点很重要:用户可以在servlet容器中定义第二个dataSource,Grails应用程序必须检查是否有第二个dataSource可用!

更具体一点:我是一个域类:

class MyDomain {

    static mapping = {
        datasource('optionalDS')
    }
}

我的DataSource.groovy:

dataSource {
    jndiName = "..."
}

dataSource_optionalDS {
    jndiName = "..."
}

问题是,如果用户没有为该可选数据源配置JNDI名称,这将失败(因为它是可选的,他不必)。

我尝试创建一个委托数据源:

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)
    ...

}

在我的插件描述符中:

def doWithSpring = {
    dataSource_optionalDS(OptionalDataSource) {
        // set default DS in case optional can not be created
        dataSource = ref('dataSource')
    }
}

此解决方案的问题是,dataSource optionalDS 不可用。如果我尝试读取数据,即 MyDomain.findAll(),我会收到以下错误:

  

类MyDomain上的Methond是在Grails应用程序之外使用的。       如果使用模拟API在测试环境中运行或       bootstrap Grails正确。

我不明白为什么,因为我可以这样定义默认的dataSource。

所以,我的问题是:如何在Grails中定义可选的dataSource?

1 个答案:

答案 0 :(得分:3)

如何在JNDI dataSource中查找DataSource.groovy,然后查看是否存在声明您的可选dataSource。像下面这样的东西

    //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 = "..."
        }
    }

我一直在寻找另一种光线方法,只是检查JNDI dataSource是否存在而不是查找它。但没有运气。