java - 当关系为空时,JPA 规范不起作用
问题描述
我正在实现基于两个实体的搜索。
@Entity(name = "user")
public class UserEntity {
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(updatable = false, nullable = false)
private String id;
@Column(unique = true, nullable = false)
private String email;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "foo_id", referencedColumnName = "id")
private FooEntity foo;
private UserType type;
}
@Entity(name = "foo")
public class FooEntity {
@Id
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
@Column(updatable = false, nullable = false)
private String id;
private String identifier;
}
现在我想根据电子邮件地址查找用户,或者当 FooEntity 关系基于该关系中的标识符存在时。AND 基于 UserEntity 中的枚举类型。
我尝试了以下查询:
public static Specification<UserEntity> emailLike(String text) {
return (root, query, criteriaBuilder) -> criteriaBuilder.like(root.get("email"), "%" + text + "%");
}
public static Specification<UserEntity> patientIdentifier(String text) {
return (root, query, criteriaBuilder) -> criteriaBuilder.like(root.join("foo").get("identifier"), "%" + text + "%");
}
public static Specification<UserEntity> userType(UserType type) {
return (root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("type"), type);
}
final Specification<UserEntity> specification = Specification.where(
UserSpecification.patientIdentifier(text)
.or(UserSpecification.emailLike(text))
).and(
UserSpecification.userType(type)
);
final Page<UserEntity> userEntities = userRepository.findAll(specification, pageable);
现在,当与 FooEntity 的关系存在时,此查询似乎有效。当此关系为 null 时,即使电子邮件和类型匹配,也不会返回任何内容。
有人可以帮我吗?
解决方案
你不应该只是加入,而是左加入或右加入。联接是内部联接,这意味着它只匹配符合联接条件的记录。在 SQL 中任何等于 null 的东西总是假的,所以我希望任何一个连接站点都为 null,记录不在结果集中。因此,左连接表示,响应所有左站点实体并仅在存在时匹配右站点,如果不存在,则右站点为空。
所以加入应该看起来像root.join("foo", JoinType.LEFT)
(未经测试)
推荐阅读
- python - (Django) 如何创建一个引用两个模型的验证 mixin?
- python - 我通过 Heroku 部署了我的 Django 服务器,构建成功,但在部署的 URL 上不断出现“应用程序错误”
- python - 为什么找不到版本“GLIBCXX_3.4.28”(/usr/lib/libQt5Widgets.so.5 需要)
- mysql - mysqldump:出现错误:重新安装数据库后出现 1045
- netty - 是否有比处理程序更低级别的接口?我想要更多地控制内存分配
- ios - 如何在 iOS 14 中以编程方式获取视图的安全区域坐标?
- python - Python如何使用变量访问列表项
- javascript - node_modules/@angular/material/table/cell.d.ts 中的错误 -Typescript 版本问题 angular
- css - 将数据映射到 CSS 网格 - 如何在每个网格正方形中返回一个元素?
- angular - 如何测试 Angular Material 对话框是否打开