2017-02-06 15 views
0

У меня есть три класса, как эти:CriteriaQuery подзапрос с максимальной

Class A { 
    Long id; 
    Date d; 
    String e; 
} 

Class B { 
    Long id; 
} 

Class AB { 
    Long aId; 
    Long bId; 
} 

И я Havet о построить CriteriaQuery для достижения следующих:

select distinct(b.id) from b b 
inner join ab ab on ab.bid = b.id 
inner join a a on a.id = ab.aid 
where e = 'SOMETHING' 
and a.d in (
    select max(aa.d) 
    from a aa 
    inner join ab aabb on aa.id = aabb.aid 
    inner join b bb on bb.id = aabb.bid 
    where bb.id = b.id 
) 

Но я что-то не хватает, потому что с:

List<Predicate> predicates = new ArrayList<Predicate>(); 
Join<B, A> joinAB = root.join("a", JoinType.INNER); // root is Root<B> 
Subquery<A> sqA = query.subquery(A.class); // query is CriteriaQuery 
Root<A> rootSqA = sqA.from(A.class); 

sqA.select(builder.max((Expression)rootSqA.get("d"))); 
sqA.where(builder.and(joinAB.get("id").in(rootSqA.get("id))));      
predicates.add(builder.in(sqA).value((Expression)joinAB.get("d"))); 

predicates.add(builder.equal(joinAB.get("e"), "SOMETHING")); 

Я не получаю то, что хочу. Я думаю, что я получаю все объекты C (со своим последним объектом A), которые в какой-то момент имели объект A с e = «SOMETHING». Но я хочу, чтобы все объекты C имели свой последний объект A с e = «SOMETHING».

ответ

0

Как часто бывает, после публикации вопроса здесь я понимаю, что я просто тупой, и мне нужно только полностью понять проблему и, самое главное, структуру, которую я использую (я был новичком в CriteriaBuilder), и я прихожу с ответом на мой собственный вопрос.

Так вот:

Join<B, A> joinAB = root.join(B_.a, JoinType.INNER); 
Subquery<Date> sqB = query.subquery(Date.class); 
Root<B> rootSq = sqB.from(B.class); 
Join<B, A> joinSq = rootSq.join(B_.lastA, JoinType.INNER); 
sqB.select(builder.max((Expression)joinSq.get(A_.date))); 
sqB.where(builder.equal((Expression)rootSq.get(A.id), root.get(A_.id))); 
predicates.add(builder.and(
     builder.equal(joinAB.get(A_.d), sqB), 
     builder.equal(joinAB.get(A_.e), "SOMETHING"))); 

 Смежные вопросы

  • Нет связанных вопросов^_^