简体   繁体   中英

Criteria API is not generating left outer join

I have 3 entities, infact many more joined together for brevity i'm skipping those and i'm using open jpa 2.2.2 and oracle 11g. Any thoughts what's going wrong here?

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;
}

Now, I am trying to order the result by RfsTypeMap.rfsName, i'm creating query using criteria builder in following manner

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

My order by clause is like this

cb.desc(cb.upper(systemRules.get("serviceActionMap").get("rfsType").get("rfsName").as(String.class)));

Generate JPQL looks like, where i expect a left outer join clause between ServiceActionMap and RfsTypeMap but it's missing. Same gets translated in SQL and i miss those records which are having ServiceActionMap.rfsType as null value.

SELECT  DISTINCT s FROM SystemRules s INNER JOIN FETCH s.serviceActionMap  INNER JOIN FETCH s.serviceActionMap  INNER JOIN FETCH s.ruleProperty  INNER JOIN FETCH s.ruleProperty where ... ORDER BY UPPER(s.serviceActionMap.rfsType.rfsName)

I tried going over several answers here but no success, tried explicitly putting a where clause for ServiceActionMap.rfsType is null as suggested on few answers but it's getting ignored, since join happens before where evaluation. Somewhere this question openJPA outer join on optional many-to-one when have order by clause matches my scenario but not able to generate suggested JPQL through criteria API.

I found one related bug on apache jira https://issues.apache.org/jira/browse/OPENJPA-2318 . But, not sure that's the case.

I see that every join is repeated twice and even the join alias is always referring to SystemRules. It might be that orderby has caused the repeating inner joins and we may need to explicitly use Join object to refer to extended column.

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))));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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