Criteria API未生成左外连接

时间:2017-03-26 09:10:38

标签: java jpa left-join openjpa

我有3个实体,实际上为了简洁我们联合在一起我正在跳过那些,我正在使用open jpa 2.2.2和oracle 11g。有什么想法在这里出了什么问题?

/Users/me/Projects/different-project

现在,我正在尝试通过RfsTypeMap.rfsName对结果进行排序,我正在以下列方式使用条件构建器创建查询

$pictureObj = file_get_contents('https://graph.facebook.com/' . $page_id . '/picture?type=large&access_token=xxxx');

我的order by子句就像这样

Entity SystemRules{
@OneToMany(mappedBy = "systemRule", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<ServiceActionMap> serviceActionMap;
}

Entity ServiceActionMap{
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "SYSTEM_RULE_ID")
    private SystemRules systemRule;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "RFS_TYPE_ID", nullable = true)
    private RfsTypeMap rfsType;
}

Entity RfsTypeMap{
    @Id
    @Column(name="RFS_TYPE_ID" ,nullable=false)
    private BigDecimal rfsTypeId;

    @Column(name="RFS_NAME")
    private String rfsName;
}

生成JPQL看起来像,我希望在ServiceActionMap和RfsTypeMap之间有一个左外连接子句但是它缺失了。在SQL中翻译相同,我错过那些将ServiceActionMap.rfsType作为空值的记录。

CriteriaQuery<SystemRules> query = cb.createQuery(SystemRules.class);
Root<SystemRules> root= query.from(SystemRules.class);
root.fetch(SystemRules_.serviceActionMap).fetch(ServiceActionMap_.rfsType, JoinType.LEFT);

我尝试在这里找到几个答案,但没有成功,尝试显式为ServiceActionMap.rfsType设置一个where子句,因为几个答案的建议是空的,但它被忽略了,因为连接发生在评估之前。在某处,此问题openJPA outer join on optional many-to-one when have order by clause与我的方案匹配,但无法通过条件API生成建议的JPQL。

我在apache jira https://issues.apache.org/jira/browse/OPENJPA-2318上发现了一个相关的错误。但是,不确定是这样的。

1 个答案:

答案 0 :(得分:0)

我看到每个连接都重复两次,甚至连接别名也总是指SystemRules。可能是orderby导致了重复的内连接,我们可能需要显式使用Join对象来引用扩展列。

CriteriaQuery<SystemRules> query = cb.createQuery(SystemRules.class);
Root<SystemRules> root = query.from(SystemRules.class);
Join<SystemRules, ServiceActionMap> join1 = root.join(SystemRules_.serviceActionMap, JoinType.INNER);
Join<ServiceActionMap, RfsTypeMap> join2 = join1.join(ServiceActionMap_.rfsType, JoinType.LEFT);
query.orderBy(cb.desc(cb.upper(join2.get(RfsTypeMap_.rfsName))));