如何使用其中一个关联列作为Grails中表的主键?

时间:2015-09-22 23:24:47

标签: grails mapping gorm hibernate-mapping

我们如何为以下场景创建域类。

Package

我开始关注站点域

CREATE TABLE station
(
  store_id integer NOT NULL,
  pos_id integer NOT NULL,
  CONSTRAINT pos_locations_pk PRIMARY KEY (store_id, pos_id)
)

CREATE TABLE header
(
  id serial NOT NULL,
  store_id integer NOT NULL,
  pos_id integer NOT NULL,
  ....
  CONSTRAINT sales_transactions_pk PRIMARY KEY (id, store_id),
  CONSTRAINT sales_transactions_pos_fk FOREIGN KEY (store_id, pos_id)
      REFERENCES station (store_id, pos_id) 
)

CREATE TABLE line_item
(
  id serial NOT NULL,
  sale_id bigint NOT NULL,
  store_id integer NOT NULL,
  .....
  CONSTRAINT transaction_lines_pk PRIMARY KEY (id, store_id),
  CONSTRAINT transaction_lines_sale_fk FOREIGN KEY (sale_id, store_id)
      REFERENCES header (id, store_id)
)

和标题表

class Station {
    int storeId
    int posId

    static mapping = {
        table "station"
        id composite: ['storeId', 'posId']
        storeId column: 'store_id'
        posId column: 'pos_id'
    }
   }

和line_item表

class Header {
int id
Station station

static mapping = {
    cache false
    version false
    table "header"

    columns {
        station {
             column name: 'store_id'
             column name: 'pos_id'
        }
    }
    id composite: ['id', 'station.storeId'] // Where I have to use store_id alone from association column to be included as a part of composite key to header table
}
}

1 个答案:

答案 0 :(得分:1)

问题是数据库模式规定的表关系与域类中的关联之间存在不匹配。

例如,标题电台之间存在多对一关联,但数据库指定:

  1. 标题电台的明确多对一关系,通过外键
  2. 以及从标题 商店 的隐式多对一(未显示的表格,但我和#39; m假设存在),通过复合主键
  3. LineItem 存在相同的情况。

    Grails实际上是无意中泄露了一些关于数据库模式的重要信息。没有糖涂层:它有缺陷。如果意图用简单的英语解释为......

    1. 商店可以有很多站。
    2. 一个电台可以有很多标题。
    3. 标题可以包含多个订单项。
    4. ...然后数据库架构应反映:

      1. 从商店到车站的一对多
      2. 从站到头的一对多
      3. 从标题到订单项的一对多
      4. 使用模式,您的Grails域模型可以无缝映射。要简单回答您的问题,您无法执行您尝试的操作,因为Grails / Hibernate关联基于属性而非属性属性。

        不可变数据库架构

        如果无法修复数据库架构,则必须放弃域类中的关联。您可以将域类设置为Row Data Gateway以上。但这样做会限制您的动态,标准和HQL查询的功能;没有表/域加入。

        如果您只需要只读访问权限并且您被允许创建数据库视图,那么这里有一个甚至可能不起作用的疯狂想法:创建您需要的视图,然后为视图创建域类。