I have an entity named certificate
@Entity
public class CertificateData {
@Id private String id;
private long expireDate;
private long createDate;
private int status;
private String subjectDN;
...
}
Many certificate can have the same subject and I want to select all certificates that have count of the field subjectId different from 3. I used this code and it worked
public List<CertificateData> findAllByRedundancy() {
Map<String, Integer> subjectDNCount = new HashMap<>();
Map<String, List<CertificateData>> subjectDNCertificates = new HashMap<>();
List<CertificateDto> certificateDataList =
this.certificaterepository
.findAll().forEach(certificateData -> {
String subject = certificateData.getSubjectDN();
if(subjectDNCount.containsKey(subject)){
subjectDNCount.put(subject, subjectDNCount.get(subject)+1);
subjectDNCertificates.get(subject).add(certificateData);
}
else{
subjectDNCount.put(subject, 1);
subjectDNCertificates.put(subject, new ArrayList<>());
subjectDNCertificates.get(subject).add(certificateData);
}
});
List<CertificateDto> result = new ArrayList<>();
subjectDNCount.forEach((s, i) -> {
if(i!=3){
result.addAll(subjectDNCertificates.get(s));
}
});
return result;
}
I tried to do the same thing using a Query-annotated Spring JPA which looks like this:
@Query("select c from CertificateData c group by c.subjectDN Having count(c) <> 3")
List<CertificateData> findAllByRedundancy();
But it doesn't return all the certificates. It returns only certificates by distincts subjectDN.
It looks like the query in your annotation is selecting groups instead of the CertificateData
records. One way to get the CertificateData
records themselves would be to use a sub-query to find the desired subjectDN
values (which is what you already have), and then have the outer query find the records with those subjectDN
values. I haven't tested this yet, but in JPQL it would be something like:
@Query(
"select c from CertificateData c where c.subjectDN in " +
"(" +
" select c.subjectDN from CertificateData c " +
" group by c.subjectDN having count(c) <> 3" +
")"
)
List<CertificateData> findAllByRedundancy();
For reference, the SQL (specifically postgres) to do this would be something like:
select * from certificate_data where subject_dn in
(
select subject_dn from certificate_data
group by subject_dn having count(*) <> 3
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.