JPA2, LEFT JOIN, Criteria API

亡梦爱人 提交于 2019-12-13 04:15:34

问题


I have the following situation SQL that I need to implement into my criteria builder for dynamic query creation.

select t1.ticketnr 
from tbl_ticket t1 
left join tbl_tickets_updates t2 on t1.ticketnr = t2.ticketnr 
where t1.description ilike '%EXAMPLE%' or t2.description ilike '%EXAMPLE%';

In my code I have the following:

tbl_ticket = Tickets.class PK = ticketnr

tbl_tickets_updates = TicketsUpdates.class and TicketsUpdatesPK.class PK = ticketnr, updatedby, timeofupdate

        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<Tickets> query = builder.createQuery(Tickets.class);
        EntityType<Tickets> type = em.getMetamodel().entity(Tickets.class);
        Root<Tickets> root = query.from(Tickets.class);
        List<Predicate> predicatesAnd = new ArrayList<Predicate>();
...
    if (text.length() != 0) {
                    predicatesAnd.add(builder.or(
                            builder.like(
                            builder.lower(
                            root.get(
                            type.getDeclaredSingularAttribute("description", String.class))), "%" + text.toLowerCase() + "%"),
                            builder.like(
                            builder.lower(
                            root.get(
                            type.getDeclaredSingularAttribute("summary", String.class))), "%" + text.toLowerCase() + "%")));
                    Join<Tickets, TicketsUpdates> tupdates = root.join("ticketnr", JoinType.LEFT);
                    predicatesAnd.add(builder.like(builder.lower(tupdates.get("description").as(String.class)), "%" + text.toLowerCase() + "%"));
                }

My code is failing at the Left Join with: java.lang.IllegalStateException: CAN_NOT_JOIN_TO_BASIC

I believe this is happening due to having a separate class for the composite PK, but so far I have not found a way to implement this properly.

Any ideas?


回答1:


Based on the comment of Chris, I was providing column name instead of the relationship name from the Entity Class ( marked as Mapped in the entity class )

 CriteriaBuilder builder = em.getCriteriaBuilder();
            CriteriaQuery<Tickets> query = builder.createQuery(Tickets.class);
            EntityType<Tickets> type = em.getMetamodel().entity(Tickets.class);
            EntityType<TicketsUpdates> typeTU = em.getMetamodel().entity(TicketsUpdates.class);
            Root<Tickets> root = query.from(Tickets.class);
            Root<TicketsUpdates> rootTicketsUpdates = query.from(TicketsUpdates.class);

            Join<Tickets,TicketsUpdates> tupdates = rootTicketsUpdates.join("tickets");

I had to add the second from ( it was missing ) and change my query to:

if (text.length() != 0) {
                predicatesAnd.add(builder.or(
                        builder.like(
                        builder.lower(
                        root.get(
                        type.getDeclaredSingularAttribute("description", String.class))), "%" + text.toLowerCase() + "%"),
                        builder.like(
                        builder.lower(
                        root.get(
                        type.getDeclaredSingularAttribute("summary", String.class))), "%" + text.toLowerCase() + "%"),
                        builder.like(
                        builder.lower(
                        tupdates.get(
                        typeTU.getDeclaredSingularAttribute("description", String.class))), "%"+text.toLowerCase()+"%")
                        ));
            }

    query.orderBy(builder.desc(root.get("startdate")));
    query.distinct(true);

Now all works as expected!



来源:https://stackoverflow.com/questions/16035662/jpa2-left-join-criteria-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!