1

我正在尝试在 Grails 2.2.1 中使用多个数据源,但在访问其他数据源时遇到了一些问题,然后是默认值。POJO(不是 POGO)文件会出现此问题。

问题是当我尝试从非默认数据源调用任何持久性特定操作(如 save()、list())时,会引发 MissingMethodException(示例如下)。我不知道出了什么问题。我遵循 grails 教程(http://grails.org/doc/latest/guide/conf.html#dataSourcesAndEnvironments)。

def entity = new MyEntity()
entity.myNonDefaultDatasource.save()


这个问题可以通过以下编码流程来解决:
创建一个新的 Grails 应用程序

$ grails create-app TestMultiDB

为我的实体类创建新的(包)

$ mkdir src/java/testmultidb

使用 JPA 注释创建实体代码

$ vim src/java/testmultidb/MyEntity.java
package testmultidb;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class MyEntity {

    @Id
    private long id;

    private String name;

    public void setId(long id) {
        this.id = id;
    }

    public long getId() {
        return this.id;
    }

    public void setName(final String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}

编辑 Grails 数据源配置文件

$ vim grails-app/conf/DataSource.groovy
dataSource {
    pooled = true
    driverClassName = "org.h2.Driver"
    username = "sa"
    password = ""
}

// ***** Added DataSource
dataSource_a2 {
    pooled = true
    driverClassName = "org.h2.Driver"
    username = "sa"
    password = ""
}

hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = false
    cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
}
// environment specific settings
environments {
    development {
        dataSource {
            dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
            url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
        }

        dataSource_a2 {
            dbCreate = "create-drop"
            url = "jdbc:h2:mem:devDbA2;MVCC=TRUE;LOCK_TIMEOUT=10000"
        }
    }
    test {
        dataSource {
            dbCreate = "update"
            url = "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
        }
    }
    production {
        dataSource {
            dbCreate = "update"
            url = "jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
            pooled = true
            properties {
               maxActive = -1
               minEvictableIdleTimeMillis=1800000
               timeBetweenEvictionRunsMillis=1800000
               numTestsPerEvictionRun=3
               testOnBorrow=true
               testWhileIdle=true
               testOnReturn=true
               validationQuery="SELECT 1"
            }
        }
    }
}

为第二个数据源创建休眠 cfg 文件

$ vim grails-app/conf/hibernate/a2_hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          '-//Hibernate/Hibernate Configuration DTD 3.0//EN'
          'http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd'>
<hibernate-configuration>
    <session-factory>
        <mapping class='testmultidb.MyEntity'/>
    </session-factory>
</hibernate-configuration>

创建控制器

$ grails create-controller testmultidb.MultDataSources

编辑控制器

$ vim grails/controllers/testmultidb/MultDataSourcesController.groovy
package testmultidb


import testmultidb.MyEntity

class MultDataSourcesController {

    def index() {

        def entity = new MyEntity()
        entity.id = 0
        entity.name = "Some name"

        MyEntity.a2.save()

        render "-"
    }
}

运行应用程序

$ grails run-app

使用权

http://localhost:8080/TestMultiDB/multDataSources/index
4

1 回答 1

0

这是意料之中的。entity.save()可以从 Java 调用,因为该方法是通过 AST 转换添加到域类中的,所以它在字节码中。但是entity.myNonDefaultDatasource.save()由于数据源是动态的,所以被添加到元类中。Java 不能调用添加到元类的方法或属性。

您可以调用这些方法,但您需要让您的 Java 代码调用 Groovy 类中的非动态辅助方法,然后再调用动态方法。

于 2013-04-18T22:50:01.550 回答