【问题标题】:Grails/GORM Mapping To Non-Standard-Named Foreign KeyGrails/GORM 映射到非标准命名的外键
【发布时间】:2013-06-18 18:38:48
【问题描述】:

我有一个存储代理层次结构的表:

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);

我将其建模为:

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

每个代理可能有许多属性:

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);

我将其建模为:

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

我创建了一个视图来轻松查看代理的层次结构:

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;

我的问题在于对病原体视图进行建模。我已经这样做了:

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

这意味着在 agent_property 表中有一个外键“pathogen_id”。但事实并非如此。 外键是agent_id。 我希望 AgentProperty 与 agent_id 上的 Pathogen 相关,就好像存在约束一样:

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

我尝试在我的 Pathgeon 类中将隐含的属性 agentProperties 映射到 agent_id,类似于:

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

但这没有用。

如何告诉 GORM 使用 agent_property.agent_id 作为外键?

【问题讨论】:

    标签: grails grails-orm


    【解决方案1】:

    我最初的问题的解决方案是我没有将 agent_id 放在引号中。

    agentProperties column: 'agent_id'
    

    现在可以了:

    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
      }
    }
    

    【讨论】:

      【解决方案2】:

      您的域类需要稍作修改才能坚持您在数据库中的设计,

      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]
      }
      

      你可以通过AgentPathogen获取AgentProperty

      如果我正确阅读了您的问题,那么这就是您所需要的。

      Pathogen hasMany Agents
      Agent hasMany AgentProperty
      

      【讨论】:

      • 感谢 dmahapatro。代理表中没有病原体 ID,我无法更改它。此外,病原体对药剂不是一对多的。如果有的话,那将是 1:1。病原体是数据库中的一个视图。你可以说病原体有一个病原体,其中病原体.id == agent_id,但每个病原体没有一个病原体。
      • @MarkAnderson 抱歉,我没有意识到 Pathogen 是一个 db view。你真的需要那个视图吗,因为你可以在AgentAgentProperty 上使用标准查询来获得你想要的。视图中使用的选择查询可以转换为Criteria。如果您被强制使用视图here is how you can access it
      • 为了建模,我可以制作 'class Pathogn { String genus;弦种;弦应变;弦毒素;代理代理};静态映射 = [列代理:'agent_id']}
      • @MarkAnderson 是的,你可以试试,但我不确定如何使用 db view 而不是 table
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 2014-05-08
      • 2022-11-23
      相关资源
      最近更新 更多