Перекрестное соединение при построении предиката для QueryDSL

#spring-data-jpa #querydsl #cross-join

#spring-data-jpa #querydsl #перекрестное объединение

Вопрос:

Я использую запрос DSL с Spring Data Jpa с QueryDslPredicateExecutor

У меня есть следующие объекты;

 @Table(name="a_table")
@Entity
public class A {

     @OneToOne
     @JoinColumn(name = "b_id")
     private B b;
}

@Table(name="b_table")
@Entity
public class B {

     @Column(...)
     private String name;
}
  

Когда я создаю Predicate для передачи в мой репозиторий, я делаю что-то вроде этого.

 QA qa = QA.a;
BooleanBuilder booleanBuilder = new BooleanBuilder();       
for(String name : strings) {
    BooleanExpression b_name_eq= qa.b.name.eq(name);
    BooleanExpression some_other_expression = ...;
    booleanBuilder.or(ExpressionUtils.and(b_name_eq, some_other_expression));
}
return booleanBuilder.getValue();
  

Что приводит к запросу, подобному следующему

 select ... , ... , ...
from a_table at
cross join b_table bt  
where at.b_id=bt.id 
and (bt.name=? and some_other_expression or bt.name=? and some_other_expression or ...)
  

Мой вопрос в том, могу ли я контролировать при генерации моего предиката использование соединения, отличного от перекрестного соединения? Поскольку перекрестное соединение, по мнению некоторых экспертов, является медленным. Я знаю, что могу это легко сделать с помощью JPAQuery но мы это не используем. Любая помощь была бы высоко оценена.

Комментарии:

1. Хотелось бы, чтобы у кого-нибудь был ответ на это. Я только что столкнулся с этим в своем приложении. Похоже, что одна из тех совершенно бессмысленных проблем Hibernate JPA «не могу отсюда», которые заставляют меня жалеть, что мне не пришлось ее использовать. Сделайте это хорошим способом, получите глупый план объединения. Напишите план объединения самостоятельно, потеряйте разбивку на страницы. WTF.

2. Пожалуйста, поделитесь сгенерированным запросом JPQL и используемой версией гибернации. Похоже, перекрестное соединение добавлено Hibernate. Я также думаю, что Hibernate делает это только тогда, когда ассоциация отображается как необязательная. Однако в старых версиях Hibernate были некоторые причуды, когда ассоциации OneToOne всегда в значительной степени рассматривались как необязательные.