我對規范構造有一些問題。我有兩個物體:
候選人:
@Entity
@Table(name = "candidates")
public class Candidate extends BaseEntity {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_id", insertable = false, updatable = false)
@JsonIgnore
private Category category;
@Column(name = "category_id")
private Long categoryId;
…
}
和類別:
@Entity
@Table(name = "categories")
public class Category extends BaseEntity {
@OneToMany(mappedBy = "category")
@JoinColumn(name = "category_id")
@JsonBackReference(value = "categories-candidates")
private List<Candidate> candidates = new ArrayList<>();
…
}
有些欄位Candidate為空category。而且我需要按類別的name欄位排序,而不是按某些候選人的欄位。同時,我有 where-condition by Candidate's field uploadId。我需要創建規范以等效于 SQL(我檢查了這個請求 - 這正是我需要的):
SELECT * FROM candidates
LEFT JOIN categories ON candidates.category_id = categories.id
WHERE candidates.upload_id = 1
ORDER BY categories."name"
我試圖這樣做:
public static Specification<Candidate> candidatesByUploadId(final long uploadId) {
return ((root, criteriaQuery, criteriaBuilder) -> {
Join<Candidate, Category> join = root.join("category", JoinType.LEFT);
criteriaQuery.orderBy(criteriaBuilder.desc(join.get("name")));
return criteriaBuilder.equal(join.get("uploadId"), uploadId);
});
}
但我不能:
- 連接中沒有“uploadId”欄位,因為這是類別到候選人的左連接,反之亦然
- 我需要所有候選記錄,即使類別為空,所以我不能使用內部連接
- 我不能使用
JoinType.RIGHT- 它不支持,我得到了例外 - 我試圖更改物體中的關系所有者,但這對我沒有幫助
- 我不應該使用
@Query的東西,我需要做Specification<> - 如果我改為寫
return criteriaBuilder.equal(root.get("uploadId"), uploadId);,我還沒有加入結果rootjoin
我怎么能得到這個?
uj5u.com熱心網友回復:
第一件事是第一
您需要將一列指定為updatable = false& insertable = false,因為您在Candidate物體 ( category& categoryId) 中指定了兩個屬性。因此,您的Candidate物體將如下所示
@Entity
@Table(name = "candidates")
public class Candidate extends BaseEntity {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_id", insertable = false, updatable = false)
@JsonIgnore
private Category category;
@Column(name = "category_id", updatable = false, insertable = false)
private Long categoryId;
…
}
然后您的規范將如下所示:
public class CandidateSpecification {
// Specification for upload id clause
public static Specification<Candidate> candidatesByUploadId(final long uploadId) {
if(uploadId == null) return null;
return ((root, query, builder) -> {
return builder.equal(root.get(Candidate_.uploadId), uploadId);
});
}
// Specification for left join category.
public static Specification<Candidate> joinCategory() {
return (root, query, builder) -> {
root.join(Candidate_.category, JoinType.LEFT);
return builder.conjuction();
}
}
...
}
現在查詢部分
public List<Candidate> getCandidatesByUploadIdSortedByCategoryName(Long uploadId) {
Specification<Candidate> specification = Specification.where(CandidateSpecification.candidatesByUploadId(uploadId))
.and(CandidateSpecification.joinCategory);
return candidateRepository.findAll(specification, Sort.by("category.name"));
}
uj5u.com熱心網友回復:
您可以使用Join.getOn()該轉換Join為Predicate.
public static Specification<Candidate> candidatesByUploadId(final long uploadId) {
return ((root, criteriaQuery, criteriaBuilder) -> {
Join<Candidate, Category> join = root.join("category", JoinType.LEFT);
criteriaQuery.orderBy(criteriaBuilder.desc(join.get("name")));
return criteriaBuilder.equal(root.get("uploadId"), uploadId)
// here it is
.and(join.getOn());
});
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/440041.html
