JPA2无法获得所需的sql

时间:2013-04-20 11:42:54

标签: jpa-2.0 eclipselink criteria-api

我正在尝试使用Criteria APi实现等效的内联sql。

select distinct t1 
from tbl_ticket t1 
left join tbl_tickets_updates t2 on t1.ticketnr = t2.ticketnr 
 where (t1.description ilike '%teste%' or t1.summary ilike '%teste%' or t2.description ilike '%teste%');

我的日志产生的结果

  

FINE:SELECT DISTINCT t0.ticketnr,t0.activity,t0.closereason,   t0.contact,t0.contactfrom,t0.contactphone,t0.description,   t0.enddate,t0.farea,t0.priority,t0.product,t0.release,   t0.repgroup,t0.solution,t0.startdate,t0.status,t0.summary,   t0.closer,t0.originator,t0.researcher FROM   supportdb.public.tbl_ticket t0,supportdb.public.tbl_tickets_updates   t2,supportdb.public.tbl_ticket t1 WHERE(((LOWER(t0.description)LIKE   ?或更低(t0.summary)喜欢?)或更低(t1.description)喜欢?)和   (t1.ticketnr = t2.ticketnr))ORDER BY t0.startdate DESC

至于我的代码:

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

            query.distinct(true);
                Subquery<TicketsUpdates> subquery = query.subquery(TicketsUpdates.class);
                Root<TicketsUpdates> rootTicketsUpdates = subquery.from(TicketsUpdates.class);
                Join<Tickets, TicketsUpdates> tupdates = rootTicketsUpdates.join("tickets");
                //subquery.select(rootTicketsUpdates);
                EntityType<TicketsUpdates> typeTU = em.getMetamodel().entity(TicketsUpdates.class);
                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")));

我开始相信我做了一些令人难以置信的错误,尽管它应该很容易被发现,我想我可能会遗漏一些非常基本的东西。 这更像是对这个问题的跟进:JPA2, LEFT JOIN, Criteria API当时我没有注意到生成的sql代码不正确并且有5k记录但有400k记录......不完全正确。 :)

任何提示都非常受欢迎。 :)

编辑1 我的Tickets.class关系定义:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "tickets")
private Collection<TicketsUpdates> ticketsUpdatesCollection;

我的TicketsUpdates.class关系定义:

    @JoinColumn(name = "ticketnr", referencedColumnName = "ticketnr", insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private Tickets tickets;

并将代码更新为:

CriteriaBuilder builder = em.getCriteriaBuilder();
            CriteriaQuery<Tickets> query = builder.createQuery(Tickets.class).distinct(true);

            EntityType<Tickets> type = em.getMetamodel().entity(Tickets.class);
            Root<TicketsUpdates> root = query.from(TicketsUpdates.class);

            EntityType<TicketsUpdates> typeTU = em.getMetamodel().entity(TicketsUpdates.class);
            Join<Tickets, TicketsUpdates> rootTickets = root.join("tickets");
            List<Predicate> predicatesAnd = new ArrayList<Predicate>();
                String test = "%test%";
                Predicate p1 = builder.like(builder.lower(rootTickets.get("description").as(String.class)),test);
                Predicate p2 = builder.like(builder.lower(rootTickets.get("summary").as(String.class)), test);
                Predicate p3 = builder.like(builder.lower(root.get(typeTU.getDeclaredSingularAttribute("description", String.class))),test);
                Predicate p4 = builder.or(p1, p2);
                Predicate p5 = builder.or(p4, p3);

                predicatesAnd.add(p5);
                query.where(p5);

            return em.createQuery(query).getResultList();

0 个答案:

没有答案