2013-06-18 14 views
5

Mam tabeli, która przechowuje hierarchię czynników:Grails/GORM Mapowanie niestandardowym nazwie klucz obcy

create table agent (
    agent_id int not null, 
    agent_name varchar(255), 
    agent_parent_id, 
    constraint pk_agent primary key (agent_id)); 

alter table agent 
    add constraint fk_agent_agent foreign key (agent_parent_id) references (agent_id); 

Mam modelowane jako:

class Agent { 
    String agentName 
    Agent agentParent 
    static mapping = { 
    id column: 'agent_id' 
    id generator: 'sequence', params: [sequence: 'agent_id_seq'] 
    } 
} 

Każdy agent może mają wiele właściwości:

create table agent_property (
    agent_property_id int not null, 
    agent_property_name varchar(255), 
    agent_id int, 
    constraint pk_agent_property primary key (agent_property_id)); 

alter table agent_property (
    add constraint fk_agent_property_agent foreign key (agent_id) references agent(agent_id); 

że mam modelowane jako:

class AgentProperty { 
    String agentPropertyName 
    static hasOne = [agent: Agent] 
    static mapping = { 
    id column: 'agent_property_id' 
    id generator: 'sequence', params: [sequence: 'agent_property_id_seq'] 
    } 
} 

Utworzyłem pogląd łatwo zobaczyć heirarchy agentów:

create view pathogen as 
    select c.agent_id as id, a.agent_name as genus, b.agent_name as species, c.agent_name as strain, d.agent_name as toxin 
    from agent a 
    left join agent b on a.agent_id = b.agent_parent_id 
    left join agent c on b.agent_id = c.agent_parent_id 
    left join agent d on c.agent_id = d.agent_parent_id 
    where a.agent_parent_id is null; 

Mój problem polega na modelowaniu widok patogenu. Robiłem to:

class Pathogen { 
    String genus 
    String species 
    String strain 
    String toxin 
    static hasMany = [agentProperties: AgentProperty] 
} 

Oznacza to, że istnieje klucz obcy „pathogen_id” w tabeli agent_property. Ale tak nie jest. Klucz obcy to identyfikator_agenta. Chcę AgentProperty odnosić się do patogenów na agent_id jakby było ograniczenie:

alter table agent_propery 
    add constraint fk_agent_property_pathogen foreign key (agent_id) references pathogen (id); 

Starałem się odwzorować domniemanych agentProperties własności do agent_id w mojej klasie Pathgeon, coś jak:

static mapping = { 
    agentProperties column: agent_id // or AgentProperty.agent 
} 

ale to nie zadziałało.

W jaki sposób powiedzieć GORM, aby użył agenta_właściwości_agenta jako klucza obcego?

Odpowiedz

6

Rozwiązaniem mojego pierwotnego problemu jest to, że nie udało mi się umieścić argumentu agent_id w cudzysłowie.

agentProperties column: 'agent_id' 

Działa to teraz:

class Pathogen { 
    String genus 
    String species 
    String strain 
    String toxin 

    static hasMany = [agentProperties: AgentProperty] 

    static mapping = { 
    // use agent_id to releate to AgentProperty 
    agentProperties column: 'agent_id' 
    } 
} 

class AgentProperty { 
    String agentPropertyName 

    static belongsTo = [agent: Agent] 
    static hasOne = [pathogen: Pathogen] 

    static mapping = { 
    id column: 'agent_property_id' 
    id generator: 'sequence', params: [sequence: 'agent_property_id_seq'] 
    // use agent_id to relate to Pathogen 
    pathogen column: 'agent_id', insertable: false, updateable: false 
    } 
} 
0

klasach domeny potrzebuje trochę modyfikacji, aby trzymać się projektu masz w bazie danych,

class Agent { 
    String agentName 
    Agent agentParent 

    //agent_id Foreign Key to AgentProperty. Agent has many AgentProperties 
    static hasMany = [agentProperties: AgentProperty] 

    static mapping = { 
    id column: 'agent_id' 
    id generator: 'sequence', params: [sequence: 'agent_id_seq'] 
    } 
} 

class AgentProperty { 
    String agentPropertyName 

    //AgentProperty belongs to an Agent. Cascade delete is enabled 
    static belongsTo = [agent: Agent] 
    static mapping = { 
    id column: 'agent_property_id' 
    id generator: 'sequence', params: [sequence: 'agent_property_id_seq'] 
    } 
} 

class Pathogen { 
    String genus 
    String species 
    String strain 
    String toxin 

    //like foreign key pathogen_id in agent table 
    static hasMany = [agents: Agent] 
} 

Można zdobyć AgentProperty z Pathogen poprzez Agent.

Jeśli dobrze przeczytam twoje pytanie, to jest to, czego potrzebujesz.

Pathogen hasMany Agents 
Agent hasMany AgentProperty 
+0

Dzięki dmahapatro. W tabeli agentów nie ma parametru pathogen_id i nie można tego zmienić. Ponadto patogen-agent nie jest jeden-do-wielu. Jeśli cokolwiek, to byłby 1: 1. Patogen to WIDOK w bazie danych. Można powiedzieć, że patogen majednego agenta, gdzie pathogen.id == agent_id, ale każdy agent nie ma jednego patogenu. –

+0

@MarkAnderson Niestety nie zdawałem sobie sprawy, że 'Pathogen' to db' view'. Czy naprawdę potrzebujesz tego widoku, ponieważ możesz używać zapytań o kryteria na 'Agent' i' AgentProperty', aby uzyskać to, czego chcesz. Kwerendę wyboru używaną w widoku można przekonwertować na [Kryterium] (http://grails.org/doc/2.2.1/ref/Domain%20Classes/createCriteria.html) .Jeśli zostaniesz zmuszony do korzystania z widoku [ Oto w jaki sposób można uzyskać do niego dostęp] (http://stackoverflow.com/questions/425294/sql-database-views-in-grails). – dmahapatro

+0

Aby to zrobić, mógłbym utworzyć "Class Pathogn {String genus; Gatunki smyczkowe; Naprężenie struny; Toksyna smyczkowa; Agent agenta}; mapowanie statyczne = [agent kolumny: 'agent_id']} –