2015-09-25 23 views
1

我有一个名为FileEntity的实体,其中包含类型为ReportEntity的报告列表。JPA - 使用组合条件查找嵌套实体

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的组合。但我无法使用以下标准检索单个结果:

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; 
} 

有人知道我在做什么错了吗?

回答

1

首先,不要在这里使用多个根,因为它们会生成所有元素的笛卡尔积,而不加入它们。改为使用连接或Path。其次,在第一个谓词中。 join object表示报告的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)}; 
+0

感谢您的回答!你确定这个班级在你的第三行加入吗?此外,您正在谓词数组中使用对象'join'。这应该是“报告”? – padde

+0

在第三行中加入类应该可以正常工作,但是我已经修复了类型参数。是的,在谓词中你必须使用报告。让我修复它 – perissf

+0

编辑版本按预期工作。谢谢! – padde