Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在一个查询中获取所有数据_Java_Mysql_Hibernate_Jpa 2.0_Criteria Api - Fatal编程技术网

Java 如何在一个查询中获取所有数据

Java 如何在一个查询中获取所有数据,java,mysql,hibernate,jpa-2.0,criteria-api,Java,Mysql,Hibernate,Jpa 2.0,Criteria Api,我有多个通过JPA2条件查询查询的实体 我能够连接其中两个实体,并立即获得结果: CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); CriteriaQuery<LadungRgvorschlag> criteriaQuery = criteriaBuilder.createQuery(LadungRgvorschlag.class); Root<LadungRgvorschlag> from = crit

我有多个通过JPA2条件查询查询的实体

我能够连接其中两个实体,并立即获得结果:

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);
我得到以下错误:

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]

org.hibernate.QueryException:查询指定的联接获取,但获取的关联的所有者不在选择列表中[FromElement{explicit,非集合联接,获取联接,获取非惰性属性,classAlias=generatedAlias3,role=null,tableName=ladberechnet,tableAlias=ladberechn3,origin=ladungen ladung1,columns={ladung1.id,className=de.schuechen.beans.tms.master.LadBerechnet}][从de.schuechen.beans.tms.master.LadungRgvorschlag中选择generatedAlias0作为generatedAlias0内部连接generatedAlias0.ladung作为generatedAlias1内部连接generatedAlias1.ladBerechnet作为generatedAlias2左连接获取generatedAlias1.ladBerechnet作为generatedAlias3内部连接获取generatedAlias0.ladung作为generatedAlias4其中(generatedAlias0.erledigt为null)和(generatedAlias0.belegart in(:param0,:param1))和(generatedAlias1.fzadresse in(:param2,:param3))和(generatedAlias1.zudatum对于JPA,您不能在标准API查询中链接获取(引用规范):

fetch方法引用的关联或属性必须是 从作为结果返回的实体或可嵌入对象引用 获取联接具有与查询相同的联接语义 对应的内部联接或外部联接,但相关对象是 不是查询结果中的顶级对象,不能被引用 其他地方的查询

JPQL查询中也不支持:

FETCH JOIN子句右侧引用的关联 必须是从引用的关联或元素集合 作为查询结果返回的实体或可嵌入实体

不允许为系统指定标识变量 FETCH JOIN子句右侧引用的对象,以及 因此,不能引用隐式获取的实体或元素 出现在查询的其他位置

使用HQL似乎是可能的:EclipseLink不提供这样的扩展,所以Hibernate接受以下查询的语法,但EclipseLink不接受:

SELECT a FROM A a LEFT JOIN FETCH a.bb b LEFT JOIN FETCH b.cc
在EclipseLink中,同样可以通过。

使用JPA“JPA的某些方言”,您可以链接连接抓取,但我认为您不能/不应该同时执行连接和连接抓取

例如,如果我们有一个
程序
,该程序与一个
奖励
有一对多的关系,该奖励
持续时间
有关系,那么以下JPQL将获得一个预先获取奖励和持续时间的特定实例:

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

}
使用等效标准代码:

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();
CriteriaBuilder-CriteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery-CriteriaQuery=criteriaBuilder.createQuery(Program.class);
Root=criteriaQuery.from(Program.class);
获取奖励=root.Fetch(“奖励”,JoinType.LEFT);
获取持续时间=报酬.Fetch(“持续时间”,JoinType.LEFT);
其中(criteriaBuilder.equal(root.get(“id”),programmaid));
TypedQuery=entityManager.createQuery(criteriaQuery);
返回query.getSingleResult();

请注意,此处不需要中间变量returnal和duration,但它们只是为了提供信息。
root.fetch(“returns”,JoinType.LEFT)。fetch(“duration”,JoinType.LEFT)
也会有同样的效果。

它之所以有效,是因为某些实现中的供应商扩展(例如Hibernate)。在JPA中,通常此JPQL查询不起作用,因为规范不要求支持这种链接和别名。感谢Mikko的澄清。这类扩展被静默激活是相当令人讨厌的,所以您使用它们时没有真正意识到它。@Mikko如果是供应商扩展,那么为什么要这样做criteriaapi返回一个Fetch实例,我们可以在该实例上调用Fetch()再一次?不幸的是,我不知道这些设计决策背后的动机。也许他们更喜欢界面的简单性而不是准确性。也许它甚至可以工作,事情是,如果它可以工作,它可以工作是因为持久性供应商对功能的扩展。实现提供了许多额外的方便的东西,这至少是一样长的时间在HQL中,如何只获取a的某些列和a.bb的某些列?
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();