JPA 2 - 获取@OneToMany关系中列表的最后一个元素

时间:2014-03-24 02:03:07

标签: java hibernate jpa criteria-api

我有一个实体,名为Deadline,与@OneToMany关系,实体名为DeadlineDate。

截止日期实体:

@Entity
@Table(name="deadline")
@Cache(alwaysRefresh=true)
public class Deadline implements Serializable { 
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    @Column(name = "id", nullable = false)
    private Long id;


    @OneToMany(mappedBy = "deadline", cascade = PERSIST)
    @OrderBy("id ASC")
    private List<DeadlineDate> datesList = new ArrayList<DeadlineDate>();

    //...
}

DeadlineDate实体:

@Entity
@Table(name="deadlinedate")
public class DeadlineDate implements Serializable {     
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id")
    private Long id;

    @Basic
    @Column(name = "date", nullable = false)
    @Temporal(DATE)
    private Date date;

    @ManyToOne
    @JoinColumn(nullable = false, name = "deadline_id")
    private Deadline deadline;
    //...
}

getAllDeadlines方法:

private List<Deadline> getAllDeadlines(){
        CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
        CriteriaQuery<Deadline> query = criteriaBuilder.createQuery(Deadline.class);
        Root<Deadline> root = query.from(Deadline.class);

        Join<Deadline, DeadlineDate> joinDeadDate = root.join("datesList");

        List<Predicate> predicateList = new ArrayList<Predicate>();             

        Date date = new Date();

        //other unrelated predicates

        //i'm stuck here - begin
        predicateList.add( criteriaBuilder.lessThan(joinDeadDate.<predicateArray>get("date"), date));       
        //i'm stuck here - end

        Predicate[] predicateArray = new Predicate[predicateList.size()];
        predicateList.toArray(predicateArray);
        query.where(predicateArray);        

        TypedQuery<Deadline> typedQuery = em.createQuery(query);
        return typedQuery.getResultList();
    }

我想查询已经过了当前系统日期的截止日期。截止日期具有存储用户所做更改的历史记录(可以向前或向后修改到期日期)。当前截止日期被视为截止日期表中的最大ID。我试图使用Criteria api,但不知道如何使它只返回要在criteriaBuilder的lessThan方法中使用的datesList的最后一个值。使用当前代码,我可以获得特定截止日期的截止日期的所有记录。

提前致谢!

2 个答案:

答案 0 :(得分:0)

如果您只需要在每个截止日期使用具有最大ID的DeadlineDate,则需要子查询(未经测试):

Subquery<Long> sq = query.subquery(Long.class);
Root<DeadlineDate> deadlineDate = query.from(DeadlineDate.class);
Root<DeadlineDate> deadlineDateSQ = sq.from(DeadlineDate.class);
Path<Deadline> deadline = deadlineDate.get("deadline");
Path<Deadline> deadlineSQ = deadlineDateSQ.get("deadline");
sq.select(criteriaBuilder.max(deadlineSQ.<Long>get("id")));
sq.groupBy(deadlineSQ);
... //create the list of other predicates
sq.where(predicateListSQ);
query.select(deadline);
Predicate predicate1 = criteriaBuilder.in(deadlineDate.get("id")).value(sq);
Predicate predicate2 = criteriaBuilder.lessThan(deadlineDate.<Date>get("date"), date);
query.where(criteriaBuilder.and(predicate1, predicate2));

另见:

答案 1 :(得分:-1)

使用setMaxResults限制返回的记录数。对输出进行排序,使您想要的记录是第一个。

typedQuery.setMaxResults(1);