我有一个存储代理层次结构的表:
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);
我尝试将隐含的属性agentProperties映射到我的Pathgeon类中的agent_id,如:
static mapping = {
agentProperties column: agent_id // or AgentProperty.agent
}
但这不起作用。
如何告诉GORM使用agent_property.agent_id作为外键?
答案 0 :(得分:6)
我原来问题的解决方案是我没有将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
}
}
答案 1 :(得分:0)
您的域类需要进行一些修改才能坚持数据库中的设计,
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]
}
您可以AgentProperty
通过Pathogen
抓住Agent
。
如果我正确地阅读了您的问题,那么这就是您所需要的。
Pathogen hasMany Agents
Agent hasMany AgentProperty