简体   繁体   English

JPA Criteria API:LEFT JOIN用于可选关系

[英]JPA Criteria API: LEFT JOIN for optional relationships

I'm using the Criteria API basically the first time. 我第一次使用Criteria API。 It's about abstracting queries for a generic builder: 它是关于抽象通用构建器的查询:

public TypedQuery<T> newQuery( Manager<?,T> manager )
{
    CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();

    Class<T> genericClass = ( Class<T> ) ( ( ParameterizedType ) manager.getClass().getGenericSuperclass() ).getActualTypeArguments()[1];

    CriteriaQuery<T> criteriaQuery = builder.createQuery( genericClass );
    Root<T> root = criteriaQuery.from( genericClass );

    ...
}

The call criteriaQuery.from( genericClass ); 调用criteriaQuery.from( genericClass ); generates SQL INNER JOIN for all relationships found on the entity by default. 默认情况下,为实体上找到的所有关系生成SQL INNER JOIN This is a problem, because every relationship being null (DB NULL or a DB that doesn't use foreign keys and has an invalid reference) those entities will be missing in the result list, effectively producing wrong search results. 这是一个问题,因为每个关系都为null(DB NULL或不使用外键且具有无效引用的DB)这些实体将在结果列表中丢失,从而有效地产生错误的搜索结果。

An example can be found here: JPA Criteria query Path.get left join is it possibile 可以在此处找到一个示例: JPA Criteria query Path.get left join is it possibile

What I'd like to happen for queries instantiated by this class/method is that all relationships on the entity, here genericClass , that are mapped as optional = true 对于由此类/方法实例化的查询,我希望发生的是实体上的所有关系,这里是genericClass ,映射为optional = true

@ManyToOne( FetchType.EAGER, optional = true )
@JoinColumn( name = "CLOSE_USER_ID", referencedColumnName = "USER_ID" )
private User              closer;

to generate an SQL LEFT (OUTER) JOIN instead of INNER JOIN . 生成SQL LEFT (OUTER) JOIN而不是INNER JOIN

Question : 问题

Is there standard JPQ way to get this done? 是否有标准的JPQ方式来完成这项工作? If so, how? 如果是这样,怎么样?

PS: there's generally no way to know the concrete type beforehand, so the only way I might be able to achieve what I need is to use the metamodel of some sort and generate the joins manually (which I'd like to avoid). PS:通常没有办法事先知道具体的类型,所以我能够实现我需要的唯一方法是使用某种元模型并手动生成连接(我想避免)。


We are using EclipseLink 2.3 我们正在使用EclipseLink 2.3

.from(class) does not use an INNER join for all relationships, it only queries the class. .from(class)不对所有关系使用INNER连接,它只查询类。

A relationship will only be queried if you use the join() or fetch() API, to use an outer join use join() with a JoinType.LEFT. 只有在使用join()或fetch()API时,才会查询关系,以使用JoinType.LEFT的外连接使用join()。

https://en.wikibooks.org/wiki/Java_Persistence/Criteria#Join https://en.wikibooks.org/wiki/Java_Persistence/Criteria#Join

I'm not sure why you are seeing joins if you are not calling join(). 如果你没有调用join(),我不确定你为什么会看到连接。 Some JPA providers automatically join fetch all EAGER relationships, this may be what you are seeing. 一些JPA提供程序自动加入获取所有EAGER关系,这可能就是您所看到的。 I have always though this odd, perhaps your JPA provider has a away to be configured not to do this, or you can make the relationships LAZY. 我总是这么奇怪,也许你的JPA提供者有一个配置不要这样做,或者你可以建立关系LAZY。

我遇到了同样的问题......经过调查后得出结论是你必须在你的jpql中使用左连接来处理这个问题请参阅: http ://www.objectdb.com/java/jpa/query/jpql/path#Navigation_through_a_NULL_value_

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM