没有交叉连接的Spring Jpa Specification子查询



我有一个问题,子查询和JPA花了我很多时间,我找不到一个直接的解决方案,所以我用了两个不同的查询来解决它。

使用Spring和JPA,我有两个类似的实体:

public Class Entity{
@Id
private Long id;
@OneToMany(mappedBy = "entity", fetch = FetchType.LAZY)
private Set<SecondEntity> secondEntities;
}
public class SecondEntity{

@Id
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn
private Entity entityId;

@Column
private Integer number;
}

我想使用JPA和规范来运行这样的查询:

SELECT *
FROM Entity
WHERE id IN (SELECT id FROM Entity LEFT JOIN SecondEntity ON Entity.id = SecondEntity.entityId WHERE number = ?)

请不要关注其他解决方法,而是帮助我理解我们是否可以让Hibernate做我想做的事情。

出现问题是因为像这样初始化subroot:

Subquery<Entity> subquery = query.subquery(Entity.class);
Root<Entity> subroot = subquery.from(Entity.class);

from()方法使Hibernate向查询添加一个crossJoin,它看起来像这样:

SELECT *
FROM Entity
WHERE id IN (SELECT id FROM Entity LEFT OUTER JOIN SecondEntity ON Entity.id = SecondEntity.entityId CROSS JOIN Employee WHERE crossjoincondition AND number = ?)

有人知道如何初始化子查询与另一种方法,以避免交叉连接?我知道其他实现,比如做一个不同的查询和混合的结果,或者写一个@Query专用可以更好地工作,但我只是想知道如何管理这为将来的目的?

我能找到的唯一解决方案是建议删除@JoinColumn注释和mappedBy属性,但我不能修改这个映射,因为我需要它用于另一个方法。

有一个简单的方法,

你可以像下面这样在规范中使用连接。

在我的代码中,我使用了INNER连接,你可以使用你自己的连接类型

public static Specification<Post> byTagNames(String[] tagNames) {
return (root, query, criteriaBuilder) -> {
if (tagNames == null || tagNames.length > 0) {
return criteriaBuilder.conjunction();
}
Join<Post, Tag> postTagsTable = root.join("tags", JoinType.INNER);
return postTagsTable.<String>get("name").in(tagNames);
};
}

我希望这对你有帮助!

相关内容

  • 没有找到相关文章