gpt4 book ai didi

java - Spring Data/Hibernate 生成两个查询而不是 JOIN

转载 作者:行者123 更新时间:2023-11-30 12:04:53 24 4
gpt4 key购买 nike

上下文:我有两个表:问卷和问题部分。问卷可以有很多问题部分。问卷和问题部分都有开始和结束日期以确定它们是否是 Activity 记录。

这是我写的实体:

@Entity
@Data
public class Questionnaire {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
private String name;
private Date startDate;
private Date endDate;
private String description;

@OneToMany(cascade = CascadeType.All,
fetch = FetchType.LAZY,
mappedBy = "questionnaire")
@JsonManagedReference
private List<QuestionSection> questionSections = new ArrayList<QuestionSection>();
}

@Entity
@Data
public class QuestionSection {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
private String name;
private String description;
private int sectionLevel;
private Date startDate;
private Date endDate;

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "QUESTIONNAIRE_ID", nullable = false)
@JsonBackReference
private Questionnaire questionnaire;
}

这是我的 Spring Data Repository,只有一个声明的方法:

public interface QuestionnaireRepository extends JpaRepository<Questionnaire, UUID> {

Questionnaire findByNameAndEndDateIsNull(String name);

// Previous goal query, but worked all the way back to the above simple query
// Questionnaire findByIdAndQuestionSectionsEndDateIsNull(UUID id);
}

上面的派生查询生成如下所示的两个查询:

-- For brevity

select questionnaire.id as id
questionnaire.description as description
questionnaire.end_date as end_date
questionnaire.start_date as start_date
from questionnaire
where questionnaire.name='Foo' and (questionnaire.end_date is null)

select questionsection.questionnaire_id as questionnaire id
...rest of fields here...
from question_section
where questionsection.questionnaire_id = id from above query

然后 Spring Data 或 Hibernate 将上述两个查询组合成一个代表问卷对象的数据对象并返回它。

我的问题是,我希望 One 查询在两个表之间运行 Join,而不是两个,然后将结果组合到内存中。一般来说,我对 Spring Data 和 ORM 非常有经验,并且无法找到任何文档来说明为什么会发生这种情况。老实说,我不在乎,除非我的初衷是查询父实体并“过滤”出具有结束日期(不活动)的子实体。此派生查询(上面已注释掉)表现出相同的行为,最终导致返回的数据集包含结束日期的问题部分。我知道还有 100 种其他方法可以解决这个问题(这很好),所以如果有人对这种行为有任何了解,这对我来说更像是一种教育兴趣。我可能会遗漏一些非常简单的东西。

最佳答案

您应该能够使用 JPA 2.1 中引入的实体图功能来执行此操作。

https://www.baeldung.com/jpa-entity-graph

Spring Data 通过 @NamedEntityGraph@EntityGraph 注释提供对实体图的支持:

https://www.baeldung.com/spring-data-jpa-named-entity-graphs

所以在你的代码中:

实体:

@Entity
@NamedEntityGraph(name = "Questionnaire.questionSections",
attributeNodes = @NamedAttributeNode("questionSections ")
)
public class Questionnaire{
//...
}

存储库:

public interface QuestionnaireRepository extends JpaRepository<Questionnaire, UUID> {

@NamedEntityGraph("Questionnaire.questionSections")
Questionnaire findByNameAndEndDateIsNull(String name);
}

关于java - Spring Data/Hibernate 生成两个查询而不是 JOIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56819984/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com