[英]How to define multiple Join on condition using ctiteria API spring data JPA Specification?
[英]How to join multiple columns using Specification in JPA?
我正在嘗試將查詢轉換為 JPA 規范,該查詢包含帶有 OR 條件的 JOIN 操作。
這是查詢:
select u from User u inner join Operation o on (u.id = o.verificateur1 or u.id = o.verificateur2) where o.id not in (:ids)
我試圖編寫一個規范,但我被阻止如何使用 OR 條件加入多個列。
public class UserSpecification {
public static Specification<User> UsersNotInSelectedOperations(final List<Long> operationId ){
return new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Join<User, Operation> userJoinOp = root.join("fk_user1_id");
final Path<User> users = userJoinOp.get("id");
return criteriaBuilder.not(users.in(operationId));
}
};
}
}
用戶實體:
@Entity
@Table(name = "aigle_user")
public class User extends AbstractEntity implements UserDetails {
private static final long serialVersionUID = 2840226091237599675L;
@Column(name = "mail", nullable = true)
private String mail;
@Column(name = "password")
private String password;
@Column(name = "is_activated")
private boolean isActivated;
@Column(name = "is_admin")
private boolean isAdmin;
@ManyToMany(cascade = { CascadeType.PERSIST })
@LazyCollection(LazyCollectionOption.FALSE)
@JoinTable(name = "aigle_group_user", joinColumns = @JoinColumn(name = "fk_user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "fk_group_id", referencedColumnName = "id"))
private Set<Group> groups;
@ManyToMany(cascade = { CascadeType.PERSIST })
@LazyCollection(LazyCollectionOption.FALSE)
@JoinTable(name = "aigle_role_user", joinColumns = @JoinColumn(name = "fk_user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "fk_role_id", referencedColumnName = "id"))
private Set<Role> roles;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "destinataire", orphanRemoval = true)
private Set<Tache> taches;
@Column(name = "last_name", unique = false)
private String lastName;
@Column(name = "first_name", unique = false)
private String firstName;
@Column(name = "telephone")
private String telephone;
private String salesforceId;
-----
}
運營實體
public class Operation extends OperationField {
...
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinColumn(name = "fk_user1_id")
private User verificateur1;
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinColumn(name = "fk_user2_id")
private User verificateur2;
.....
}
我希望有一個規范來替換上面的查詢
您可以嘗試使用子查詢而不是連接表達式
public static Specification<User> UsersNotInSelectedOperations(final List<Long> operationIds) {
return (root, query, builder) -> {
Subquery<Operation> subquery = query.subquery(Operation.class);
Root<Operation> operation = subquery.from(Operation.class);
Predicate predicate1_1 = builder.equal(operation.get("verificateur1").get("id"), root.get("id"));
Predicate predicate1_2 = builder.equal(operation.get("verificateur2").get("id"), root.get("id"));
Predicate predicate1 = builder.or(predicate1_1, predicate1_2);
Predicate predicate2 = operation.get("id").in(operationIds).not();
subquery.select(operation).where(predicate1, predicate2);
return builder.exists(subquery);
};
}
使用這個規范,你會得到一個像這樣的 HQL 查詢
from User u
where exists( // subquery ->
from Operation o
where (o.verificateur1.id = u.id or o.verificateur2.id = u.id) // predicate 1
and o.id not in (:ids) // predicate 2
// <- subquery
)
from User u
是來自用戶 u 的select u from User u
的較短替代品
我寫了這段代碼沒有運行,所以它需要修改
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.