Java JPA规范+多对多字段动态排序,无重复项
我有一个有很多字段的类,多对一和多对多关系,我需要通过这个类中的一些列和连接类中的字段添加动态过滤器,并通过这些字段添加排序 我对按多对多字段进行过滤和排序有问题Java JPA规范+多对多字段动态排序,无重复项,java,jpa,Java,Jpa,我有一个有很多字段的类,多对一和多对多关系,我需要通过这个类中的一些列和连接类中的字段添加动态过滤器,并通过这些字段添加排序 我对按多对多字段进行过滤和排序有问题 @Entity class EntityA { ... @ManyToMany @JoinTable ( name = "EntityA_EntityB", joinColumns = { @JoinColumn(name = "EntityB") }, inverseJoinColum
@Entity
class EntityA {
...
@ManyToMany
@JoinTable (
name = "EntityA_EntityB",
joinColumns = { @JoinColumn(name = "EntityB") },
inverseJoinColumns = { @JoinColumn(name = "entityb_id") }
)
private List<EntityB> bEntities;
...
}
作为EntityB.name连接到EntityA的字段失败。此外,我还有其他一些带有@ManyTone的字段失败,出现下一个异常:
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: ORDER BY items must appear in the select list if SELECT DISTINCT is specified
如果我删除criteriaQuery.distincttrue;一切都会好的,但我会有副本,我不想有他们
如何修复它,同时又不产生重复的结果 获取EntityA重复结果的原因是将EntityA与EntityB连接起来,并且谓词基于EntityB中的一个字段。因此,如果有多个EntityB条目满足您的条件,并且它们都属于同一个EntityA,那么您将得到多个EntityA条目。因此,解决方案是使用exists,而不是连接两个表,并且不再需要使用distinct。您的规格可以如下所示:
public class EntityASpecifications {
//other specifications
...
public static Specification<EntityA> entityBNameContains(String query) {
return (root, criteriaQuery, criteriaBuilder) -> {
if (query == null) {
return criteriaBuilder.conjunction();
}
Subquery< EntityB> subquery = query.subquery(EntityB.class);
Root< EntityB> subqueryRoot = subquery.from(EntityB.class);
subquery.select(subqueryRoot);
subquery.where(criteriaBuilder.and(criteriaBuilder.equal(root, subqueryRoot.get("entitya_id")),
criteriaBuilder.like(criteriaBuilder.lower("name"), getContainsPattern(query)))
);
return criteriaBuilder.exists(subquery);
};
}
private static String getContainsPattern(String searchTerm) {
return (searchTerm.isEmpty()) ? "%" : "%" + searchTerm.toLowerCase() + "%";
}
}
你看到这篇文章了吗?typedQueryThintQueryHints.HINT\u传递\u DISTINCT\u,false可能对您有效。@chromanoid看起来我不能使用它,因为我使用规范,无法从那里访问实体管理器。请注意,在我的示例中,criteriaBuilder.equalroot,subqueryRoot.getentitya\u id应该是criteriaBuilder.equalroot.getid,subqueryRoot.joinaEntities.getid,这样它就可以工作了
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: ORDER BY items must appear in the select list if SELECT DISTINCT is specified
public class EntityASpecifications {
//other specifications
...
public static Specification<EntityA> entityBNameContains(String query) {
return (root, criteriaQuery, criteriaBuilder) -> {
if (query == null) {
return criteriaBuilder.conjunction();
}
Subquery< EntityB> subquery = query.subquery(EntityB.class);
Root< EntityB> subqueryRoot = subquery.from(EntityB.class);
subquery.select(subqueryRoot);
subquery.where(criteriaBuilder.and(criteriaBuilder.equal(root, subqueryRoot.get("entitya_id")),
criteriaBuilder.like(criteriaBuilder.lower("name"), getContainsPattern(query)))
);
return criteriaBuilder.exists(subquery);
};
}
private static String getContainsPattern(String searchTerm) {
return (searchTerm.isEmpty()) ? "%" : "%" + searchTerm.toLowerCase() + "%";
}
}