我有以下实体:
@Getter
@Setter
@Entity
@Table(name = "closing_account")
public class ClosingAccount {
@Embedded private AccountParams accountParams = new AccountParams();
}
@Getter
@Setter
@Embeddable
public class AccountParams {
@ToString.Exclude
@EqualsAndHashCode.Exclude
@Fetch(FetchMode.SELECT)
@OneToMany(mappedBy = "closingRequestId", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
@LazyCollection(LazyCollectionOption.FALSE)
private List<CheckBook> checkBooks;
}
@Getter
@Setter
@Entity
@Table(name = "checkbook")
public class CheckBook {
@Column(name = "closing_account_id", nullable = false)
private UUID closingRequestId;
}
我在这里想要的是使用 Spring Data JPA 规范 API(这很重要) 使用
Specification
创建 Predicate
来仅过滤 closing_account
表中没有相应 的记录checkBooks
条目。本质上,从普通 SQL 的角度来看,我想要类似的东西:
SELECT ca.* FROM closing_account ca
LEFT JOIN checkbook cb ON cb.closing_account_id = ca.id
WHERE cb.id IS NULL
可能会有不同的写法,但我只是想表达我需要的东西。
可以只发出:
return (root, query, criteriaBuilder) -> {
return criteriaBuilder.isNull(root.join("checkBooks", JoinType.LEFT).get("closingRequestId"));
};
但是,这是行不通的,因为
checkBooks
不是 ClosingAccount
的直接属性。所以我想我只需要稍微调整一下我的Specification
返回的Predicate
,我只是不知道该怎么做。
欢迎并高度赞赏任何建议
一般来说,以下规范应该符合您的期望,但您的域模型看起来相当奇怪
return (root, query, builder) -> {
return builder.isNull(root.join(ClosingAccount_.ACCOUNT_PARAMS).joinList(AccountParams_.CHECK_BOOKS)
.get(CheckBook_.CLOSING_ACCOUNT_ID));
};