具有复杂连接的JPA CriteriaQuery没有返回预期的内容

时间:2018-02-21 20:35:54

标签: java jpa hibernate-criteria

我有这些实体

@MappedSuperclass
public abstract class AbstractPersistentObject implements IdentifiablePersistentObject {
    ...
    @GeneratedValue(strategy = GenerationType.TABLE)
    @SequenceGenerator(name="my_seq_gen", sequenceName="ENTITY_SEQ")
    @Column(name = "ID")
    private Long id;
    ...
}

@Entity
@Table(name = "CLASS")
public class ClassBO extends AbstractPersistentObject {
    ...
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinColumn(name="CLASS_ID")
    private List<SolvedActivity> solvedActivities;
    ...
}

@Entity
@Table(name = "SOLVED_ACTIVITY")
public class SolvedActivity extends AbstractPersistentObject {
    ...
    private Student student;
    @ManyToOne(cascade = CascadeType.ALL, fetch=FetchType.LAZY)
    @JoinColumn(name = "ACTIVITY_ID", foreignKey = @ForeignKey(name = "FK_SOLVED_ACTIVITY__ACTIVITY"), nullable = false)
    private Activity activity;
    ...
}

@Entity
@Table(name="ACTIVITY")
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class Activity extends AbstractPersistentObject {
    ...
}

给定一个classID和一个activityID,我想获得所有SolvedActivities,它们包含一个与classBO匹配classID的activityID匹配的活动。

这就是我的尝试:

public List<SolvedActivity> solvedActivityByClassAndActivity(Long classId, Long activityId) {
    List<SolvedActivity> solvedActivities = Lists.newArrayList();

    CriteriaBuilder builder = this.getEntityManager().getCriteriaBuilder();
    CriteriaQuery<SolvedActivity> criteriaQuery = builder.createQuery(SolvedActivity.class).distinct(true);

    Root<ClassBO> classRoot = criteriaQuery.from(ClassBO.class);

    Join<ClassBO, SolvedActivity> solvedActivityRoot = classRoot.join("solvedActivities", JoinType.INNER);
    Join<SolvedActivity, Activity> solvedActivityActivity = solvedActivityRoot.join("activity", JoinType.INNER);

    criteriaQuery.where(builder.equal(classRoot.get("ID"), classId));
    criteriaQuery.where(builder.equal(solvedActivityActivity.get("ID"), activityId));

    criteriaQuery.select(classRoot.get("solvedActivities"));

    final TypedQuery<SolvedActivity> query = this.getEntityManager().createQuery(criteriaQuery);

    solvedActivities.addAll(query.getResultList());

    return solvedActivities;
}

似乎查询忽略了带有activityID的where子句。 我确信对于有这类查询经验的人来说,错误一定是显而易见的。

先谢谢!

1 个答案:

答案 0 :(得分:0)

愚蠢的错误。 解决方案:

此:

criteriaQuery.select(solvedActivityRoot);

而不是:

criteriaQuery.select(classRoot.get("solvedActivities"));