2

我希望能够通过简单的属性更改在 EclipseLink 和 Hibernate 之间交换我的 JPA 实现。我可以做到这一点,但导致我出现问题的是命名查询验证。使用 EclipseLink 我必须像这样编写获取连接:

SELECT id 
FROM IndexDefinition id 
JOIN FETCH id.index 
JOIN id.index i
JOIN FETCH i.indexVersions

但是当使用 Hibernate 验证这个查询时,我得到以下异常:

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

所以我可以将查询更改为对 HQL 友好,如下所示:

SELECT id 
FROM IndexDefinition id 
JOIN FETCH id.index i
JOIN FETCH i.indexVersions

但这会在 EclipseLink 中导致以下异常:

Exception Description Syntax error parsing the query [IndexDefinition.getForIndex] SELECT id FROM IndexDefinition id JOIN FETCH id.index i, syntax error at [id].
Internal Exception MismatchedTokenException(78!=-1)

我知道我可以在我的 DAO 级别使用查询提示来执行 fetch join,但是有没有一种方法可以使用特定的 fetch join 语法来取悦两个 JPA 实现?

4

1 回答 1

0

好吧,JPA 1.0 似乎不支持嵌套连接。从 JPA 1.0 规范:

4.4.5.3 获取连接

FETCH JOIN 允许获取关联作为执行查询的副作用。FETCH JOIN 在实体及其相关实体上指定。

获取连接的语法是

fetch_join ::= [ LEFT [OUTER] | INNER ] JOIN FETCH join_association_path_expression

FETCH JOIN 子句右侧引用的关联必须是属于作为查询结果返回的实体的关联。不允许为 FETCH JOIN 子句右侧引用的实体指定标识变量,因此对隐式获取的实体的引用不能出现在查询的其他地方

以下查询返回一组部门。作为副作用,这些部门的关联员工也会被检索,即使他们不是显式查询结果的一部分。急切获取的员工的持久字段或属性已完全初始化。检索到的员工关系属性的初始化由 Employee 实体类的元数据决定。

SELECT d
FROM Department d LEFT JOIN FETCH d.employees
WHERE d.deptno = 1

获取连接与相应的内连接或外连接具有相同的连接语义,只是连接操作右侧指定的相关对象不会在查询结果中返回或在查询中以其他方式引用。因此,例如,如果部门 1 有五名员工,则上述查询返回对部门 1 实体的五个引用。

因此,虽然某些 JPA 提供程序可能支持嵌套连接,但其行为并未标准化。

参考

  • JPA 1.0 规范
    • 第 4.4.5.3 节“获取连接”
  • JPA 维基书
于 2010-08-16T11:25:12.293 回答