java - 如何在一次查询中获取所有数据

标签 java mysql hibernate jpa-2.0 criteria-api

我有多个通过 JPA2 Criteria Query 查询的实体。

我能够加入其中两个实体并立即获得结果:

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<LadungRgvorschlag> criteriaQuery = criteriaBuilder.createQuery(LadungRgvorschlag.class);
Root<LadungRgvorschlag> from = criteriaQuery.from(LadungRgvorschlag.class);
Join<Object, Object> ladung = from.join("ladung");

from.fetch("ladung", JoinType.INNER);

然后我尝试加入一个额外的表:

ladung.join("ladBerechnet");
ladung.fetch("ladBerechnet", JoinType.LEFT);

我收到以下错误:

org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=generatedAlias3,role=null,tableName=ladberechnet,tableAlias=ladberechn3_,origin=ladungen ladung1_,columns={ladung1_.id ,className=de.schuechen.beans.tms.master.LadBerechnet}}] [select generatedAlias0 from de.schuechen.beans.tms.master.LadungRgvorschlag as generatedAlias0 inner join generatedAlias0.ladung as generatedAlias1 inner join generatedAlias1.ladBerechnet as generatedAlias2 left join fetch generatedAlias1.ladBerechnet as generatedAlias3 inner join fetch generatedAlias0.ladung as generatedAlias4 where ( generatedAlias0.erledigt is null ) and ( generatedAlias0.belegart in (:param0, :param1) ) and ( generatedAlias1.fzadresse in (:param2, :param3) ) and ( generatedAlias1.zudatum<=:param4 ) and ( 1=1 ) order by generatedAlias0.belegart asc, generatedAlias1.fzadresse asc, generatedAlias1.zudatum asc, generatedAlias1.zulkw asc]

我如何告诉 JPA/Hibernate,它应该一次选择所有实体?

最佳答案

使用 JPA 'some dialects of JPA' 您可以链接连接提取,但我认为您不能/不应该同时进行连接和连接提取。

例如,如果我们有一个 ProgramReward 有一对多关系,而 Reward 又与 Duration 有关系>,以下 JPQL 将获得一个特定的实例,其中奖励和持续时间已预先获取:

SELECT DISTINCT
    program
FROM
    Program _program
        LEFT JOIN FETCH
    _program.rewards _reward
        LEFT JOIN FETCH
    _reward.duration _duration
WHERE
    _program.id = :programId

}

使用等效的 Criteria 代码:

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Program> criteriaQuery = criteriaBuilder.createQuery(Program.class);
Root<Program> root = criteriaQuery.from(Program.class);

Fetch<Program, Reward> reward = root.fetch("rewards", JoinType.LEFT);
Fetch<Reward, Duration> duration = reward.fetch("duration", JoinType.LEFT);

criteriaQuery.where(criteriaBuilder.equal(root.get("id"), programId));

TypedQuery<program> query = entityManager.createQuery(criteriaQuery);

return query.getSingleResult();

请注意,此处不需要中间变量奖励和持续时间,但它们仅供引用。 root.fetch("rewards", JoinType.LEFT).fetch("duration", JoinType.LEFT) 会有同样的效果。

关于java - 如何在一次查询中获取所有数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8521338/

相关文章:

运行多个进程时 MySQL 连接被拒绝

hibernate - Spring嵌套@Transactional方法和回滚

java - 按多个值排序 hibernate

java - ZXING - "barcode not found"和 "impossible to decode barcode"的处理

java - 使用 Jackson 反序列化树形结构 JSON 中的值

java - quartz spring集成调度,是否可以动态设置cron触发器

java - 在Java中,我如何知道主机上的某个端口是否打开?(除了如果可能的话使用套接字)

python - 从 mysql 导出 json 作为嵌套 json

mysql - 使用子字符串条件连接表

java - hibernate 缓存 : Are objects returned by a cached query stored in L2 cache?