gpt4 book ai didi

java - JPA Criteria API - 设置连接并从连接实体中获取数据

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

我有两个实体 FooFooDerivedData,如下所述。

实体Foo:

@Entity
@Table(name="FOO")
public class Foo {

// skipping property declarations

@OneToOne
@PrimaryKeyJoinColumn(name = "FOO_ID")
@Fetch(FetchMode.JOIN)
public getFooDerivedData() {
return fooDerivedData;
}

实体 FooDerivedData

@Entity
@Table(name = "FOO_DERIVED_VW")
@Immutable
public class FooDerivedData {

@Id
@Column(name = "FOO_ID")
long fooId;

@Column(name = "FOO_COUNT")
private Integer fooCount;

@Column(name = "FOO_SUM")
private BigDecimal fooSum;


// Getters left out here

我正在使用 JPA Criteria API(Hibernate 是 JPA 实现),并且我需要将 FooDerivedData 的实例加载到 Foo 中。默认情况下会急切地获取它,但我希望使用内部联接来获取它,而不是为 FooDerivedData 的每个实例使用单独的 select 语句。我成功地添加了针对 FooDerivedData 的内部联接。

CriteriaQuery<Foo> criteriaQuery = criteriaBuilder.createQuery(Foo.class);
Root<Foo> root = criteriaQuery.from(Foo.class);
root.join("fooDerivedData");
Predicate p = getPredicate(); // details omitted here
criteriaQuery.select(root).where(p);

虽然我可以从日志中的 SQL 中看到为 FOO_DERIVED_VW 添加了内联接,但没有选择任何列。对于 Foo 的每个实例,我仍然需要一个单独的 select 语句来获取我随时可用的数据。

目前的查询是这样的:

select f.foo_id, f.foo_bar from from FOO f
inner join FOO_DERIVED_VW d on d.foo_id = f.foo_id;
select d.foo_id, d.foo_count, d.foo_sum from FOO_DERIVED_VW d where foo_id = ?;
select d.foo_id, d.foo_count, d.foo_sum from FOO_DERIVED_VW d where foo_id = ?;

请注意,我没有从连接的 FOO_DERIVED_VW 中选择任何数据,并且该数据是通过其他数据库命中来实现的。我希望查询是这样的:

select f.foo_id, f.foo_bar, d.foo_count, d.foo_sum from from FOO f
inner join FOO_DERIVED_VW d on d.foo_id = f.foo_id;

如何从 Criteria API 中的联接实体中选择属性?我可以指示 javax.persistence.criteria.Root 选择我要加入的属性吗?

我尝试从联接更改为提取,或者在指定联接类型的情况下更改提取。无论哪种情况,它都会失败并出现 Hibernate QueryException。

Root<Foo> root = criteriaQuery.from(Foo.class);
root.fetch("fooDerivedData");

Caused by: org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list

最佳答案

我认为你有几个选择。如果您的 where 条件不使用连接表中的任何列,那么您尝试的提取应按如下方式工作:

CriteriaQuery<Foo> criteriaQuery = criteriaBuilder.createQuery(Foo.class);
Root<Foo> root = criteriaQuery.from(Foo.class);
root.fetch("fooDerivedData");
Predicate p = getPredicate(); // details omitted here
criteriaQuery.select(root).where(p);

如果您的谓词确实包含连接表中的列,那么您可以像您所做的那样进行连接(当前无法使用 fetch),然后还可以通过将其添加到您的内容来指定动态实体图(从 JPA 2.1 开始)曾经:

CriteriaQuery<Foo> criteriaQuery = criteriaBuilder.createQuery(Foo.class);
Root<Foo> root = criteriaQuery.from(Foo.class);
root.join("fooDerivedData");
Predicate p = getPredicate(); // details omitted here
criteriaQuery.select(root).where(p);
EntityGraph<Foo> fetchGraph = entityManager.createEntityGraph(Foo.class);
fetchGraph.addSubgraph("fooDerivedData");
EntityManager.createQuery(criteriaQuery).setHint("javax.persistence.loadgraph", fetchGraph);

关于java - JPA Criteria API - 设置连接并从连接实体中获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30178100/

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