2009-09-28 40 views
1

有人可以幫我弄清楚如何在grails中創建簡單的一對一映射的域類!Grails中的一對一映射

讓我們說我們有2個表(甲骨文):

create table table_a(long_common_id_name number(5) primary key using index, 
        notes varchar2(10 byte), 
        update_seq number(3)not null); 

create table table_b (long_common_id_name number(5) primary key using index, 
         extra_notes varchar2(200 byte), 
         update_seq number(3) not null); 

alter table table_b add (constraint table_b_fk foreign key (long_common_id_name) 
references table_a (long_common_id_name)); 

我創建了兩個domain類:

class TableA { 
    static mapping = { 
     table 'table_a' 
     columns { 
      id     column:'LONG_COMMON_ID_NAME' 
      data    column:'NOTES' 
      version    column:'UPDATE_SEQ' 
     } 
    } 
    String data 
    TableB extraData 
} 

class TableB { 
    static mapping = { 
     table 'table_b' 
     columns { 
      id     column:'LONG_COMMON_ID_NAME' 
      data    column:'EXTRA_NOTES' 
      version    column:'UPDATE_SEQ' 
     } 
    } 
    String data 
} 

這種特殊的定義是不正確的。 Grails的(或休眠)建立了TableA的一個不正確的SQL:

select this_.LONG_COMMON_ID_NAME as LONG1_66_0_, this_.UPDATE_SEQ as UPDATE2_66_0_, this_.NOTES as NOTES66_0_, this_.extra_data_id as extra4_66_0_ from table_a this_ 

我試過很多東西:屬於關聯,hasManey具有獨特的,但似乎沒有任何工作。

在此先感謝。

回答

1

回答我的問題的方式,也許有人會覺得它有用......

我編寫一個快速的web-ui來對付我們的遺留數據庫,所以不用編寫大量的SQL來回答用戶的問題,而是想自動化它。我無法修改數據結構,通過用戶界面訪問將只能讀取。

這裏是解決方案/變通方法,我可以住在一起:

域/ TableA.groovy

class TableA { 
    static mapping = { 
     table 'table_a' 
     columns { 
      id     column:'LONG_COMMON_ID_NAME' 
      data    column:'NOTES' 
      version    column:'UPDATE_SEQ' 
     } 
    }  
    // will manually handle persistence of TableB 
    static transients = [ 'extraData' ] 

    String data 
    TableB extraData 
} 

域/ TableB.groovy

class TableB { 
    static mapping = { 
     table 'table_b' 
     columns { 
      id     column:'LONG_COMMON_ID_NAME' 
      data    column:'EXTRA_NOTES' 
      version    column:'UPDATE_SEQ' 
     } 

     //actual id is copied from TableA after it is persisted 
     id generator:'assigned' 
    } 

    static transients = [ "parent" ] 

    String data 
    TableA parent 
} 

窗體中的「views/tableA/create」。GSP」具有用於表A表B和屬性輸入字段,所以將獲得表A表B和實例數據


在‘控制器/ TableAController.groovy’我手動更新/刪除/負載表B實例

def list = {  
    ... 
    def rv = TableA.list(params) 
    rv.each() { it.extraData = TableB.get(String.valueOf(it.id)) } 
    ... 
} 

def show = { 
    .... 
    tableAInstance.extraData = TableB.get(tableAInstance.id) 
    ... 
} 
def delete = { 
    ... 
    // delete tableB instance first before tableA 
    def tb = TableB.get(tableAInstance.id) 
    if (tb) tb.delete() 

    tableAInstance.delete() 
    ... 
} 

def save = { 
    .... 
    // after tableAInstance.save() call 
    def tb = new TableB() 
    tb.data = params.extraData?.data 
    // copy id from tableA instance 
    tb.id = tableAInstance.id 
    tb.save() 
    ..... 
} 
0

你是否必須以這種方式設置外鍵?我期望TABLE_A上有一個TABLE_B_ID列。

無論如何,我認爲要做你想做的事情,你需要添加一行到extraData的映射閉包。

我不知道這是否會很好地與它作爲主鍵以及

例如玩

static mapping = { 
    extraData column:'LONG_COMMON_ID_NAME' 
} 
+0

這是一個我正在處理的遺留數據庫 我試過你以前的建議,它不起作用,下面是我得到的錯誤消息: 「實體映射中的重複列:TableA列: LONG_COMMON_ID_NAME(應該使用insert =「false」update =「false」進行映射)「 – mtim 2009-09-29 13:38:44

+0

是否將映射行移動到'c olumns'有所作爲?根據1.1.1文檔,似乎並不需要。 您可能不得不退回到使用Hibenate xml映射類:http://grails.org/Hibernate+Integration – leebutts 2009-09-30 02:58:15

+0

聲明「列」之外的映射列沒有任何區別,相同的「重複列」錯誤。 – mtim 2009-09-30 21:19:49

0

同意leebuts,Grails將在子表中指定一個單獨的FK ID字段。

這個表設置看起來更像是類繼承。您可能能夠創建類TableB,繼承類TableA,其中TableA包含Notes並且TableB包含「數據」。 Grails可能還需要TableB中的鑑別器列,但否則它看起來像表符合Grails約定的繼承。

請看:http://grails.org/GORM+-+Mapping+DSL

查找關閉表,每個層次