我正在使用Spring Boot和Hibernate,通过中间表管理具有双向@OneToMany关系的实体.以下是我的实体定义:
@Entity
@Table(name = "feedback")
@NamedEntityGraph(name = "full", includeAllAttributes = true)
@Getter
@Setter
@SequenceGenerator(allocationSize = 1, name = "feedback_seq_gen", sequenceName = "feedback_seq")
public class Feedback {
@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "feedback_seq_gen")
private Long id;
@Column(name = "text", length = Integer.MAX_VALUE)
private String text;
@OneToMany(mappedBy = "feedback", fetch = FetchType.LAZY)
private Set<Image> images = new HashSet<>();
}
@Entity
@Table(name = "image")
@Getter
@Setter
@SequenceGenerator(allocationSize = 1, name = "image_seq_gen", sequenceName = "image_seq")
public class Image {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "image_seq_gen")
@Column(name = "id", nullable = false)
private Long id;
@Column(name = "url", length = Integer.MAX_VALUE)
private String url;
@ManyToOne(fetch = FetchType.LAZY)
@JoinTable(name = "feedback_image",
inverseJoinColumns = @JoinColumn(name = "feedback_id"),
joinColumns = @JoinColumn(name = "image_id"))
private Feedback feedback;
public void setFeedback(Feedback feedback) {
feedback.getImages().add(this);
this.feedback = feedback;
}
}
Feedback和Image实体通过使用名为feedback_image
的@JoinTable的@OneToMany关系进行关联.我使用连接表的原因是因为我需要在创建反馈之前上传图像.
存储库:
public interface FeedbackRepository extends JpaRepository<Feedback, Long> {
@EntityGraph("full")
@Query("select f from Feedback f where f.id = :id")
Optional<Feedback> getFullFeedbackById(Long id);
}
在测试关系和获取逻辑时,Hibernate会生成一个复杂的SQL查询,其中包括对子查询的附加联接:
SELECT f1_0.id, i1_0.feedback_id, i1_1.id, i1_1.url, f1_0.text
FROM feedback f1_0
LEFT JOIN feedback_image i1_0 ON f1_0.id = i1_0.feedback_id
LEFT JOIN (image i1_1 LEFT JOIN feedback_image i1_2 ON i1_1.id = i1_2.image_id) ON i1_1.id = i1_0.image_id
WHERE f1_0.id = ?;
然而,我注意到,如果我将关系切换到@ManyToMany,Hibernate会生成一个更简单、更直接的查询:
SELECT f1_0.id, i1_0.feedback_id, i1_1.id, i1_1.url, f1_0.text
FROM feedback f1_0
LEFT JOIN feedback_image i1_0 ON f1_0.id = i1_0.feedback_id
LEFT JOIN image i1_1 ON i1_1.id = i1_0.image_id
WHERE f1_0.id = ?;
但这种方法与我的概念模型不一致.
因此,我的问题是:Hibernate为该设置生成的附加连接子查询正常吗?如果是,为什么会发生这种情况?