【问题标题】:Grails GORM: How do I create a composite primary key and use it for a table relationship?Grails GORM:如何创建复合主键并将其用于表关系?
【发布时间】:2015-06-24 00:20:45
【问题描述】:

我有两个表,其中一个(旧表:A)有两个字段应该用作复合外键,另一个(新表:B)应该为 each row:A has one row:B 关系使用复合主键.我如何用 GORM 来描述这些表?

到目前为止,我已经能够创建一个反映遗留表的域类:A

class A {

    ...
    //composite foreign key to link B class
    String className;
    String eventName;

    B b; //instance of B to be related

    static mapping = {
        table 'a_table';            
        id column: 'id';
        className column: 'class_name';
        eventName column: 'event_name';
        //b: ???
    }
}

这可行,但我无法创建 new class:B 和关系。

我试图将 B 声明为:

class B implements Serializable{

    static auditable = true;

    String name;
    String className;
    String eventName;

    static mapping = {
        //supposed to make a composite PK
        id composite:[className, eventName] 
    }
}

但这不会用 a
ERROR context.GrailsContextLoader - Error executing bootstraps: Error evaluating ORM mappings block for domain [com.package.B]: No such property: eventName for class: org.codehaus.groovy.grails.orm.hibernate.cfg.HibernateMappingBuilder

编译

我想要的是这样的:

static mapping = {
    ...
    b composite: [b.className:className, b.eventName:eventName]
    //or whatever is the right way for this to be done.
}

让 A 类让 GORM 处理这种关系。

【问题讨论】:

    标签: grails grails-orm


    【解决方案1】:

    您是否尝试使用属性名称而不是使用属性值?

    class B implements Serializable{
        String name;
        String className;
        String eventName;
    
        static mapping = {
            //supposed to make a composite PK
            id composite:['className', 'eventName'] 
        }
    }
    

    并在 A 中映射:

    class A {
        static hasMany = [ b : B ]
    }
    

    A 中不需要有 classNameeventName

    【讨论】:

      【解决方案2】:

      B 类必须声明为 Serializable 并实现 equals 和 hashCode 方法

      import org.apache.commons.lang.builder.HashCodeBuilder
      class B implements Serializable{
      
          static auditable = true;
      
          String name;
          String className;
          String eventName;
          boolean equals(other) {
          if (!(other instanceof B)) {
              return false
          }
      
          other.className == className && other.eventName == eventName
          }
      
          int hashCode() {
          def builder = new HashCodeBuilder()
          builder.append className
          builder.append eventName
          builder.toHashCode()
          }
      
          static mapping = {
              //supposed to make a composite PK
              id composite:["className", "eventName"] 
          }
      }
      

      A类只要有B类的一个属性,GORM做复合外键

      class A {
      
          //composite foreign key to link B class
          B b; //instance of B to be related
      
          static mapping = {
              table 'a_table';            
              id column: 'id';
          }
      }
      

      它在数据库中创建两个表

      +--------------------------------------------------+
      |                       A_TABLE                    |  
      +--------+-----------+--------------+--------------+
      |   id   |  version  |  b_className | b_eventName  |
      +--------+-----------+--------------+--------------+
      --where the Primary key is "id" and the foreign key are "b_className and b_eventName" 
      +--------------------------------------------------+
      |                       B                          |  
      +--------+-----------+--------------+--------------+
      |  name  |  version  |  className   | eventName    |
      +--------+-----------+--------------+--------------+
      --where the Primary key are "className and eventName" 
      

      如果您要将列的名称更改为其他名称,只需在映射语句中添加分句

      class A {
      
          //composite foreign key to link B class
          B b; //instance of B to be related
      
          static mapping = {
              table 'a_table';            
              id column: 'id';
              columns {
                    b {
                       column name: "className"
                       column name: "eventName"
                    }
              }
          }
      }
      

      【讨论】:

        【解决方案3】:
        import org.apache.commons.lang.builder.HashCodeBuilder
        class Person implements Serializable {
        
        String firstName
        String lastName
        
        boolean equals(other) {
            if (!(other instanceof Person)) {
                return false
            }
        
            other.firstName == firstName && other.lastName == lastName
        }
        
        int hashCode() {
            def builder = new HashCodeBuilder()
            builder.append firstName
            builder.append lastName
            builder.toHashCode()
        }
        
        static mapping = {
            id composite: ['firstName', 'lastName']
        }
        }
        

        这是你可以从 grails 的官方文档中找到的,

        http://grails.org/doc/latest/guide/GORM.html#compositePrimaryKeys

        只要盲目地遵循这个,你的问题就会得到解决。解释参考上面的链接

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-07-22
          • 1970-01-01
          • 2011-12-02
          • 1970-01-01
          • 2018-11-16
          • 1970-01-01
          • 2010-12-22
          相关资源
          最近更新 更多