Spring Data JPA 规范 API 通过 @Embedded 属性连接

问题描述 投票:0回答:1

我有以下实体:

@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
,我只是不知道该怎么做。

欢迎并高度赞赏任何建议

java hibernate spring-data-jpa criteria-api
1个回答
0
投票

一般来说,以下规范应该符合您的期望,但您的域模型看起来相当奇怪

return (root, query, builder) -> {
    return builder.isNull(root.join(ClosingAccount_.ACCOUNT_PARAMS).joinList(AccountParams_.CHECK_BOOKS)
                .get(CheckBook_.CLOSING_ACCOUNT_ID));
};
© www.soinside.com 2019 - 2024. All rights reserved.