I recently noticed that some of my team's older code is executing multiple queries when only one is necessary. It can be replicated by calling the Criteria.list or AbstractEntityManagerImpl.find functions for several of our tables, so it's likely something setup incorrectly on the entity. I think it has something to do with how we're doing multiple outer joins to the same table, which is mapped to multiple different entities.
Here's our setup:
Code:
@Table(name="problem")
public class ProblemEntity {
@id
@Column(name = "id")
private long id;
@OneToOne(fetch = FetchType.EAGER, optional = true)
@JoinColumn(name = "comment_id")
private CommentEntity comment;
@OneToOne(fetch = FetchType.EAGER, optional = true)
@JoinColumn(name = "description_id")
private DescriptionEntity description;
@OneToOne(fetch = FetchType.EAGER, optional = true)
@JoinColumn(name = "instruction_id")
private InstructionEntity instruction;
}
@Table(name="special_text")
public class CommentEntity {
@id
@Column(name = "id")
private long comment_id;
@Column(name = "text")
private String comment;
}
@Table(name="special_text")
public class DescriptionEntity {
@id
@Column(name = "id")
private long description_id;
@Column(name = "text")
private String description;
}
@Table(name="special_text")
public class InstructionEntity {
@id
@Column(name = "id")
private long instruction_id;
@Column(name = "text")
private String instruction;
}
What I would expect from a basic search on ProblemEntity for a specific id would be a single query:
Code:
select p.*, c.*, d.*, i.*
from problem p
left outer join special_text c on c.comment_id = p.comment_id
left outer join special_text d on d.description_id = p.description_id
left outer join special_text i on i.instruction_id = p.instruction_id
where p.id = ?
But instead, Hibernate generates the following queries:
Code:
select p.*, c.*, d.*, i.*
from problem p
left outer join special_text c on c.comment_id = p.comment_id
left outer join special_text d on d.description_id = p.description_id
left outer join special_text i on i.instruction_id = p.instruction_id
where p.id = ?
select p.*, c.*, d.*, i.*
from problem p
left outer join special_text c on c.comment_id = p.comment_id
left outer join special_text d on d.description_id = p.description_id
left outer join special_text i on i.instruction_id = p.instruction_id
where c.comment_id = ?
select p.*, c.*, d.*, i.*
from problem p
left outer join special_text c on c.comment_id = p.comment_id
left outer join special_text d on d.description_id = p.description_id
left outer join special_text i on i.instruction_id = p.instruction_id
where d.description_id = ?
select p.*, c.*, d.*, i.*
from problem p
left outer join special_text c on c.comment_id = p.comment_id
left outer join special_text d on d.description_id = p.description_id
left outer join special_text i on i.instruction_id = p.instruction_id
where i.instruction_id = ?
It's running the expected query first. Can anyone tell me why it's running the additional queries and how to prevent that from happening?