Spring JPA储存库和QueryDsl如何强制左联接

问题描述 投票:0回答:1

假设我有两个实体User和Task,每个用户可以有一个任务。

我面临的问题是,如果用户表中有一条记录的电子邮件以a开头,而任务表中根本没有记录。

以下代码段将不返回任何记录,尽管我希望用户的邮件以a开头。

示例中的UserRepository扩展了QuerydslPredicateExecutor。

        userRepository.findAll(
            QUser.user.email.startsWith("a")
                .or(QUser.user.task.text.contains("something"))
        )

如果检查日志,则Hibernate将使用user.task_id=task.id创建交叉联接,作为where子句的一部分。如果用户未分配任务,则这种类型的加入会自动丢弃其邮件以a开头的用户。

在存储库的findAll方法中是否有一种方法可以强制使用左联接而不是交叉联接?

我知道我可以使用JPAQuery来做到这一点,但随后我将不得不重新实现分页功能...

        JPAQuery query = new JPAQuery(entityManager);
        query
            .from(QUser.user)
            .leftJoin(QTask.task)
        // ...
spring-data-jpa querydsl
1个回答
0
投票
您可以尝试执行以下操作:

QUser qUser = QUser.user; QTask qTask = QTask.task; JPQL<UserEntity> userJpqlQuery = JPAExpressions.selectFrom(qUser) .leftjoin(qUser.task, qTask) .where(qUser.email...., qTask.text...); userRepository.findAll(qUser.in(userJpqlQuery));

在上面的代码中,我使用了

Querydsl,它是

CriteriaBuilder的替代方法,并且类型安全。然后,我创建了一个子查询以进行所需的选择,并返回与该子查询匹配的所有用户。

最后,休眠应生成如下内容:select * from User qUser0 where qUser0.id.in( select qUser1.id from User qUser1 left join Task qTask0 on qUser1.taskId = qTask0.id where ... );
© www.soinside.com 2019 - 2024. All rights reserved.