JPA - 使用组合标准查找嵌套实体
JPA - Finding nested entities using combined criterias
我有一个名为 FileEntity
的实体,其中包含 ReportEntity
类型的报告列表。
FileEntity
有一个字段确定哪个用户创建了包含多个报告的文件。
@Entity
public class FileEntity {
@Id
private Long id;
@JoinColumn(name = "user")
@ManyToOne(optional = true)
@NotNull
private User user;
@OneToMany(cascade = CascadeType.ALL,
fetch = FetchType.EAGER,
orphanRemoval = true)
@NotNull
private List<Report> reports = new ArrayList<>(5);
...
}
@Entity
public class Report {
@Id
private Long id;
...
}
我目前正在尝试获取具有给定报告 ID 和发布包含该报告的文件的人员的 ID 的单个报告。该组合是唯一的,因此对于特定的报告和用户 ID 组合,它应该只有 return 个报告。但是我无法使用以下条件检索单个结果:
public Report findReportByUserAndReportId(Long reportId, Long userId) {
Objects.nonNull(reportId);
Objects.nonNull(userId);
try {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Report> cq = cb.createQuery(Report.class);
final Root<FileEntity> fileEntity = cq.from(FileEntity.class);
final Root<Report> report = cq.from(Report.class);
final Join<FileEntity, Report> join = fileEntity.join(FileEntity_.reports);
final Predicate[] predicates = new Predicate[]{
cb.equal(join.get("id"),
userId),
cb.equal(join.get(Report_.id),
reportId)};
cq.select(report).where(predicates);
return entityManager.createQuery(cq).getSingleResult();
} catch (NoResultException |
NonUniqueResultException ne) {
LOG.log(Level.WARNING,
"Could not find report: {0}",
ne.getMessage());
}
return null;
}
有人知道我做错了什么吗?
首先,不要在这里使用多个根,因为它们会生成所有元素的笛卡尔积,而无需连接它们。请改用联接或 Path
s。第二,在第一个谓词中。 join
对象表示 Path
的报告,而不是用户,因此在那里寻找 userid
没有意义。
Root<FileEntity> fileEntity = cq.from(FileEntity.class);
Path<User> user = fileEntity.get(FileEntity_.user);
Join<FileEntity, Report> reports = fileEntity.join(FileEntity_.reports);
Predicate[] predicates = new Predicate[]{
cb.equal(user.get(User_.id),
userId),
cb.equal(reports.get(Report_.id),
reportId)};
我有一个名为 FileEntity
的实体,其中包含 ReportEntity
类型的报告列表。
FileEntity
有一个字段确定哪个用户创建了包含多个报告的文件。
@Entity
public class FileEntity {
@Id
private Long id;
@JoinColumn(name = "user")
@ManyToOne(optional = true)
@NotNull
private User user;
@OneToMany(cascade = CascadeType.ALL,
fetch = FetchType.EAGER,
orphanRemoval = true)
@NotNull
private List<Report> reports = new ArrayList<>(5);
...
}
@Entity
public class Report {
@Id
private Long id;
...
}
我目前正在尝试获取具有给定报告 ID 和发布包含该报告的文件的人员的 ID 的单个报告。该组合是唯一的,因此对于特定的报告和用户 ID 组合,它应该只有 return 个报告。但是我无法使用以下条件检索单个结果:
public Report findReportByUserAndReportId(Long reportId, Long userId) {
Objects.nonNull(reportId);
Objects.nonNull(userId);
try {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Report> cq = cb.createQuery(Report.class);
final Root<FileEntity> fileEntity = cq.from(FileEntity.class);
final Root<Report> report = cq.from(Report.class);
final Join<FileEntity, Report> join = fileEntity.join(FileEntity_.reports);
final Predicate[] predicates = new Predicate[]{
cb.equal(join.get("id"),
userId),
cb.equal(join.get(Report_.id),
reportId)};
cq.select(report).where(predicates);
return entityManager.createQuery(cq).getSingleResult();
} catch (NoResultException |
NonUniqueResultException ne) {
LOG.log(Level.WARNING,
"Could not find report: {0}",
ne.getMessage());
}
return null;
}
有人知道我做错了什么吗?
首先,不要在这里使用多个根,因为它们会生成所有元素的笛卡尔积,而无需连接它们。请改用联接或 Path
s。第二,在第一个谓词中。 join
对象表示 Path
的报告,而不是用户,因此在那里寻找 userid
没有意义。
Root<FileEntity> fileEntity = cq.from(FileEntity.class);
Path<User> user = fileEntity.get(FileEntity_.user);
Join<FileEntity, Report> reports = fileEntity.join(FileEntity_.reports);
Predicate[] predicates = new Predicate[]{
cb.equal(user.get(User_.id),
userId),
cb.equal(reports.get(Report_.id),
reportId)};