不同模式中表之间的关系映射

时间:2015-05-14 06:37:31

标签: grails gorm multi-tenant

目前,应用程序正在处理数据库中的多个模式,因此我们有一个存储主表的公共模式,而我们存储客户特定数据的其他模式。

所以,具体情况就像

(下表仅供参考)

AnimalType的主表位于common架构中,而Animal表位于schema1schema2等所有客户端架构上。 。schemaN

我们使用Grails,默认使用Hibernate,因此,关系就像

class AnimalType {
   String type

   static mapping = {
     datasources(['index'])
   }
}

class Animal {
   String name
   AniamlType animalType

}

因此,当我启动应用程序时,它会显示以下异常:

  

引起:org.springframework.beans.factory.BeanCreationException:   创建名为'sessionFactory'的bean时出错:init的调用   方法失败;嵌套异常是org.hibernate.MappingException:An   表动物的关联是指未映射的类:   org.sample.AnimalType

我从中理解的是,Animal尝试在其自己的架构中引用AnimalType,但AnimalType不存在。

所以,基本上我想将Animal映射到指向AnimalType架构的common

如下所示,Grails中的语法

class Animal {
   String name

   @(POINTING TO COMMON SCHEMA)
   AnimalType animalType
}

2 个答案:

答案 0 :(得分:2)

mapping中添加以下内容:

table name: "animal_type", schema: "common"

从当前docs

开始

答案 1 :(得分:1)

修订答案

Hibernate是数据库之上的抽象层。根据您的@(POINTING TO COMMON SCHEMA)表示法,您可能来自Java背景。使用下面的基本方法,我们的组连接到数十个模式和多个数据库。在连接到各种模式时,利用Grails域类在配置上使用约定。请参阅mapping tables to domain classes上的Grails文档。让我尝试通过描述示例数据库模式和域类映射来解释。

希望您通过应用程序用户访问数据库。我们称之为ANIMAL_APP。 ANIMAL_APP可以访问以下表格:

  • ANIMAL_TYPE(公共表,所有动物都可以访问)
  • TIGER(仅适用于老虎)
  • SNAKE(仅适用于蛇)
  • BEE(仅适用于蜜蜂)

其中每个都可以拥有自己的域类。他们也有自己的控制器,可以内置个性化的逻辑.BEE飞行和TIGERS不能在单独的控制器动作中考虑。

AnimalType DOMAIN CLASS

class AnimalType{   
    //AnimalType properties  
    static mapping = {
        table 'ANIMAL_TYPE', schema: 'ANIMAL_APP'
        id column: 'id'
    }
}

TIGER DOMAIN CLASS //可能是任何一种动物

class Tiger{
    Sting name
    String value
    static belongsTo = [animalType:AnimalType]

    static mapping = {
        table 'TIGER', schema: 'ANIMAL_APP'
        //Be aware that you could map to a different schema as follows
        //table TIGER, schema: 'TIGER_SCHEMA'
        id column: 'id'
    }
}

一旦这些类相互链接,就要在数据库中管理应该管理它的表访问权限。为模式ANIMAL_APP可以用于TIGER,SNAKE和BEE的表创建同义词。为每个表授予对ANIMAL_APP的正确权限。

Config.groovyDataSource.groovy

中配置数据源

Config.groovy 为每个环境配置JNDI数据源。请记住,您使用ANIMAL_APP映射到数据库。

grails.naming.entries = [
        "jdbc/devanimalapp": [
                type: "javax.sql.DataSource", //required
                auth: "Container", // optional
                description: "Data source for Production", //optional
                driverClassName: "oracle.jdbc.OracleDriver",
                url: "[replace with your databaseDriver]@[jndi location]",
                username: "ANIMAL_APP",
                password: "secret",
        ],
        "jdbc/prodanimalapp": [
                type: "javax.sql.DataSource", //required
                auth: "Container", // optional
                description: "Data source for Production", //optional
                driverClassName: "oracle.jdbc.OracleDriver",
                url: "[replace with your databaseDriver]@[jndi location]",
                username: "ANIMAL_APP",
                password: "secret",
        ]
]
然后按如下方式配置

DataSource.groovy。请记住,这是一个指南,文档可以在Grails knowledge base

中找到
environments {
    development {
        dataSource {
            dbCreate = "validate" // one of 'create', 'create-drop', 'update', 'validate', ''
            dialect = "[insert your database dialect]"
            jndiName = "java:comp/env/jdbc/devredapp"
        }
    }

    production {
        dataSource {
            dbCreate = "validate" // one of 'create', 'create-drop', 'update', 'validate', ''
            dialect = "[insert your database dialect]"
            jndiName = "java:comp/env/jdbc/prodanimalapp"
        }
    }
}

以这种方式映射域类将允许您利用Grails的配置约定,并且只需通过ANIMAL_APP模式访问必要的表即可安全。控制ANIMAL_APP模式中的权限和同义词将允许您连接到不同的模式甚至远程数据库。

以下原始答案的透明度

我不确定我是否正确理解了这个问题,但如果你想让Animal Class继承(参见Grails GORM Inheritence)AnimalType类,你必须声明Hibernate的关系。

class AnimalType{
    //some properties
    static hasMany = [animals:Animal, ...]
}

class Animal{
    String name
    String value
    static belongsTo = [animalType:AnimalType]
}

class Animal extends AnimalType{
    String animalName
}

如果我严重误解了您的问题,请告诉我,我会再试一次。