Java 与使用join的Spring数据JPA规范不同的结果
我有以下Java 与使用join的Spring数据JPA规范不同的结果,java,hibernate,jpa,spring-data-jpa,criteria-api,Java,Hibernate,Jpa,Spring Data Jpa,Criteria Api,我有以下规范,用于查询与某些ManagedApplication实体关联的任何联系人实体。我传入一个集合,该集合包含我正在搜索的ManagedApplication实体的ID public static Specification<Contact> findByApp(final Collection<Long> appIds) { return new Specification<Contact>() { @Override
规范
,用于查询与某些ManagedApplication
实体关联的任何联系人
实体。我传入一个集合
,该集合包含我正在搜索的ManagedApplication
实体的ID
public static Specification<Contact> findByApp(final Collection<Long> appIds) {
return new Specification<Contact>() {
@Override
public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
final Predicate appPredicate = root.join(Contact_.managedApplications)
.get(ManagedApplication_.managedApplicationId).in(appIds);
}
}
}
下面是我如何调用.findAll()
方法的
final Page<Contact> contacts = pagingAndSortingContactRepository.findAll(ContactSpecification.findByApp(appIds), pageable);
ManagedApplication.java
@StaticMetamodel(ManagedApplication.class)
public class ManagedApplication_ {
public static volatile SingularAttribute<ManagedApplication, Integer> managedApplicationId;
}
@StaticMetamodel(ManagedApplication.class)
公共类管理应用程序{
公共静态属性ManagedApplication ID;
}
使用toPredicate
方法中的query
参数调用distinct方法
样本如下:
public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
final Predicate appPredicate = root.join(Contact_.managedApplications)
.get(ManagedApplication_.managedApplicationId).in(appIds);
query.distinct(true);
...
公共谓词toPredicate(根根、CriteriaQuery查询、CriteriaBuilder cb){
最终谓词appPredicate=root.join(联系.managedApplications)
.get(ManagedApplication_u.managedApplicationId).in(appid);
query.distinct(true);
...
可以添加一个新的静态方法
public static Specification<Object> distinct() {
return (root, query, cb) -> {
query.distinct(true);
return null;
};
}
感谢您提供此解决方案,它非常有效!此外,为了澄清问题,您必须添加
query.distinct(true)
添加到每个需要此独特语句的谓词。仅将此语句添加到任何谓词并使其在整个查询中工作是不够的。这是如何工作的?我的意思是,如果您使用纯MySQL语法连接一些形成多对多关系的表,以便您可以选择左表中具有证书的行在右表的列中的值中,尽管使用了SELECT DISTINCT子句,但如果左表中的一行与右表中的多行相关,仍然会得到重复的结果。
public Predicate toPredicate(Root<Contact> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
final Predicate appPredicate = root.join(Contact_.managedApplications)
.get(ManagedApplication_.managedApplicationId).in(appIds);
query.distinct(true);
...
public static Specification<Object> distinct() {
return (root, query, cb) -> {
query.distinct(true);
return null;
};
}
Specification.where(
YourStaticClassWhereYouCreatedTheUpperMethod.distinct().and(..))