Составной ключ и сопоставление в Grails 2.2.5 с устаревшей базой данных

У меня 4 стола. осигуранье_пакет, атрибут, тип_уноса, разна_поля. osiguranje_paket, атрибут, tip_unosa являются Родителями таблицы razna_polja. Таблица razna_polja имеет составной ключ, который состоит из двух первичных ключей (osgp_id = таблица osiguranje_paket + atr_id = таблица атрибутов). Отношения между ними являются двунаправленными «один ко многим», и я использую базу данных Legacy PostgreSQL с динамическим формированием шаблонов, я не могу вносить какие-либо изменения в базу данных, таблицы или что-либо еще. Как я могу сопоставить свои классы с использованием составного ключа, что мне нужно добавить или изменить в моих доменах? Любая помощь будет оценена по достоинству.

CREATE TABLE revoco.osiguranje_paket
  (
  osgp_id serial NOT NULL,
  osg_id integer NOT NULL,
  osgp_napomena character varying(500),
  tpo_id integer NOT NULL,
  osgp_link character varying(155),
  osgp_oznaka character varying(10),
  CONSTRAINT osgp_pk PRIMARY KEY (osgp_id),
  CONSTRAINT osg_osgp_fk FOREIGN KEY (osg_id)
      REFERENCES revoco.osiguranje (osg_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT tpo_osgp_fk FOREIGN KEY (tpo_id)
      REFERENCES revoco.tip_osiguranja (tpo_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
) 

CREATE TABLE revoco.atribut
(
  atr_id serial NOT NULL,
  atr_naziv character varying(155) NOT NULL,
  lab_id integer,
  atr_rbr integer,
  CONSTRAINT atr_pk PRIMARY KEY (atr_id),
  CONSTRAINT atr_lab_labela_fk FOREIGN KEY (lab_id)
      REFERENCES common.labela (lab_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

CREATE TABLE common.tip_unosa
(
  tpu_id serial NOT NULL,
  tpu_val character varying(32) NOT NULL,
  CONSTRAINT tpu_pk PRIMARY KEY (tpu_id),
  CONSTRAINT tpu_vrijednost_unique UNIQUE (tpu_val)
)

CREATE TABLE common.razna_polja
(
  osgp_id integer NOT NULL,
  atr_id integer NOT NULL,
  tpu_id integer NOT NULL,
  rap_odjel integer NOT NULL DEFAULT 0,
  rap_vidljiv boolean NOT NULL DEFAULT true,
  CONSTRAINT rap_pk PRIMARY KEY (osgp_id, atr_id),
  CONSTRAINT rap_atr_atribut_fk FOREIGN KEY (atr_id)
      REFERENCES revoco.atribut (atr_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT rap_osgp_paket_fk FOREIGN KEY (osgp_id)
      REFERENCES revoco.osiguranje_paket (osgp_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT rap_tpu_tip_unosa_fk FOREIGN KEY (tpu_id)
      REFERENCES common.tip_unosa (tpu_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT rap_ispravan_odjel_ck CHECK (rap_odjel >= 0 AND rap_odjel <= 1)
)

Это мои классы домена

OsiguranjePaket.groovy

import common.RaznaPolja

   class OsiguranjePaket {

    Integer id
    String osgp_napomena
    String osgp_link
    String osgp_oznaka


    static belongsTo = [osg: Osiguranje, tpo: TipOsiguranja]
    static hasMany = [raznaPolja: RaznaPolja]

        String toString(){
            "${osgp_oznaka}"
        }

    static fetchMode = [raznapolja: 'eager']


    static constraints = {

        id(unique: true)
        osgp_link (nullable: true, blank: false, size: 0..155)
        osgp_napomena (nullable: true, blank: false, size: 0..500)
        osgp_oznaka (nullable: true, blank: false, size: 0..10)     
    }

    static mapping = {
        table name: 'osiguranje_paket', schema: 'revoco'
        version false       
        id generator :'identity', column :'osgp_id', type:'integer'
    }   
}

Атрибут.groovy

import common.RaznaPolja
import common.Labela

class Atribut {

Integer id
String atr_naziv
Integer atr_rbr



static hasMany = [raznaPolja: RaznaPolja]
static belongsTo = [lab: Labela]

static fetchMode = [raznaPolja: 'eager']


String toString(){
    "${atr_naziv}"
}

static mapping = {
    table name: "atribut", schema: "revoco"
    version false
    id generator :'native', column :'atr_id'
}

static constraints = {

    id(blank: false, unique: true)
    atr_naziv (blank: false, size: 0..155)
    atr_rbr (nullable: true)
    }
}

TipUnosa.groovy

class TipUnosa {

    Integer id
    String tpu_val


    static hasMany = [raznaPolja: RaznaPolja]

    static fetchMode = [raznaPolja: 'eager']

        String toString(){
            "${tpu_val}"
        }

    static constraints = {
        id (blank:false, size: 0..10)
        tpu_val (blank:false, unique:true, size:0..32)
    }

    static mapping = {
        table name: "tip_unosa", schema: "common"
        version false
        id generator :'identity', column :'tpu_id', type:'integer'
}

}

РазнаПоля.groovy

import java.io.Serializable;

import revoco.Atribut
import revoco.OsiguranjePaket

class RaznaPolja implements Serializable  {


    Integer rap_odjel
    Boolean rap_vidljiv     

//without this getting common.RaznaPolja(unsaved) 
    String toString(){
        "${id}" //Getting null
    }   

    static belongsTo = [atr: Atribut, osgp: OsiguranjePaket, tpu: TipUnosa]

    static mapping = {
        table name: 'razna_polja', schema: 'common'

        id composite: ['osgp', 'atr']
//      cache usage:'read-only'
        version false
        rap_odjel column: 'rap_odjel', type: 'integer'
        rap_vidljiv column:'rap_vidljiv', type: 'boolean'
}
}

person 03Ronnie04    schedule 12.08.2015    source источник


Ответы (1)


Составной ключ

Чтобы установить составной ключ, вам нужно использовать свойство сопоставления вашего класса домена, и ваш класс домена должен реализовать интерфейс Serializable. Вот пример из документации по Grails.

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 должны быть в состоянии справиться с вашими потребностями.

person Emmanuel Rosa    schedule 17.08.2015