我在Media
实体和MediaAnalysis
实体之间存在一对一的关系,其中Media
实体是抽象基类:
新闻报道实体
@Entity
@DiscriminatorValue("N")
public class NewsReport extends Media {
@Column(name = "BODY", nullable = false)
private String body;
NewsReport(){}
public NewsReport(String title, String link, String author, String body) {
super(title, link, author);
this.body= body;
}
public String getBody() {
return body;
}
}
媒体实体
@Entity
@Inheritance(
strategy = InheritanceType.SINGLE_TABLE
)
@DiscriminatorColumn(name = "TYPE", length = 1, discriminatorType = DiscriminatorType.STRING)
public abstract class Media {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
@Column(name = "TITLE", nullable = false)
private String title;
@Column(name = "LINK", length = 500, nullable = false)
private String link;
@Column(name = "AUTHOR", length = 45, nullable = false)
private String author;
@OneToOne(mappedBy = "media")
private MediaAnalysis analysis;
Media(){}
public Media(String title, String link, String author) {
this.title = title;
this.link = link;
this.author = author;
}
// getters
public Optional<MediaAnalysis> getAnalysis() {
return Optional.ofNullable(analysis);
}
}
媒体分析
@Entity
public class MediaAnalysis {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
@Column(name = "SUCCESS", nullable = false)
private Boolean success;
@OneToOne
@JoinColumn(
name = "MED_ID",
nullable = false,
foreignKey = @ForeignKey(name="MEA_MED_FK")
)
private Media media;
@Column(name = "CONTENT", nullable = false)
private String content;
MediaAnalysis() { }
public MediaAnalysis(Media media, Boolean success, String content) {
this.media = media;
this.success = success;
this.content = content;
}
// getters
public Media getMedia() {
return media;
}
public String getContent() {
return content;
}
}
现在,当我想使用我的
AnalysisRepository.getByMedia(..a NewsReport...)
时public interface AnalysisRepository extends JpaRepository<MediaAnalysis,Long> {
@Query("SELECT a FROM MediaAnalysis a LEFT JOIN FETCH a.media WHERE a.media = ?1")
Optional<MediaAnalysis> getByMedia(Media media);
}
例如,要通过
MediaAnalysis
查找NewsReport
,我希望hibernate运行单个SELECT
查询,例如:但是,当我启用查询日志记录时,我看到了2:
似乎首先按预期选择了
MediaAnalysis
,但随后又出现了另一个不必要的查询。我可以分辨出这两个查询之间的唯一区别是联接类型。我认为问题与Media
继承有关。为什么会这样呢? +我该怎么做才能确保这是一个查询?
进一步说明,如果我从存储库中删除了
@Query
,则实际上存在三个的查询!最佳答案
我没有JpaRepository的经验,只是(很多)关于Hibernate(主要是&CriteriaBuilder)的经验,但是有一些想法:
@OneToOne
(在您的示例中应为MediaAnalysis)MediaAnalysis
映射为1:n关系(好像每个媒体可能有多个MediaAnalysis
,这在我的理解中可能是正确的,也许不在您的域中)。 查看是否有任何有助于生成查询的信息。