I have a table that stores a hierarchy of agents:
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);
I've modeled it as:
class Agent {
String agentName
Agent agentParent
static mapping = {
id column: 'agent_id'
id generator: 'sequence', params: [sequence: 'agent_id_seq']
}
}
Each agent may have many properties:
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);
I've modeled that as:
class AgentProperty {
String agentPropertyName
static hasOne = [agent: Agent]
static mapping = {
id column: 'agent_property_id'
id generator: 'sequence', params: [sequence: 'agent_property_id_seq']
}
}
I've created a view to easily see the heirarchy of agents:
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;
My problem is in modeling the pathogen view. I've done this:
class Pathogen {
String genus
String species
String strain
String toxin
static hasMany = [agentProperties: AgentProperty]
}
This implies that there is a foreign key 'pathogen_id' in the agent_property table. But, that is not the case. The foreign key is agent_id. I want AgentProperty to relate to Pathogen on agent_id as if there were the constraint:
alter table agent_propery
add constraint fk_agent_property_pathogen foreign key (agent_id) references pathogen (id);
I tried to map the implied property agentProperties to agent_id in my Pathgeon class, something like:
static mapping = {
agentProperties column: agent_id // or AgentProperty.agent
}
but that didn't work.
How do I tell GORM to use agent_property.agent_id as the foreign key?
The solution to my original problem is that I failed to to put agent_id in quotes.
agentProperties column: 'agent_id'
This works now:
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
}
}
Your domain classes needs little bit of modification to stick to the design you have in database,
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]
}
You can get hold of AgentProperty
from Pathogen
via Agent
.
If I read your question correctly, then this is what you need.
Pathogen hasMany Agents
Agent hasMany AgentProperty
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With