我有两个实体:事件和评论。
@Entity
@Table(name = "events")
public class Event extends BaseEntity {
@Id
@Column(name = "event_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long eventId;
@Column(name = "title", length = 200)
protected String title;
@OneToMany(mappedBy = "event", cascade = CascadeType.REMOVE)
@LazyCollection(LazyCollectionOption.FALSE)
protected List<Comment> comments;
}
@Entity
@Table(name = "comments")
public class Comment extends BaseEntity {
@Id
@Column(name = "comment_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long commentId;
@ManyToOne(optional = false)
@JoinColumn(name = "event_id", referencedColumnName="event_id", nullable = false)
protected Event event;
@Column(name = "update_time", nullable = false)
@Temporal(TemporalType.TIMESTAMP)
protected Date updatedTimestamp;
}
因此每个事件都有一个评论列表,每个评论都有更新时间。
我想使用Criteria API构建一个查询,以便选择至少有一条新注释的所有事件。 (新评论表示其更新时间晚于给定日期时间)
感谢任何帮助我的人。
很抱歉,我上面提到的问题并不完整:我想要的是使用Criteria API构建一个查询,以便选择至少有一条新评论的所有事件且eventId等于某个特定的eventId
我尝试过:(给定Date lastCheckedTime
和Long eventId
)
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Event> cq = cb.createQuery(Event.class);
Root<Comment> c = cq.from(Comment.class);
Predicate lastCheckedTimeCondition = cb.greaterThanOrEqualTo(
c.get(Comment_.updatedTimestamp), lastCheckedTime);
cq.where(lastCheckedTimeCondition);
cq.select(c.get(Comment_.event));
TypedQuery<Event> query = em.createQuery(cq);
result = query.getResultList();
上面的代码可以选择有新评论的事件,但现在我不知道如何添加关于eventId的条件。
答案 0 :(得分:1)
CriteriaBuilder
有and(Predicate...)方法。然后,您将连接两个谓词:
cq.where(cb.and(lastCheckedTimeCondition, someEventIdCondition));
答案 1 :(得分:1)
在事件上创建联接,并对事件的ID应用限制:
Join<Comment, Event> event = c.join(Comment_.event);
Predicate eventIdPredicate = cb.eq(event.get(Event_.eventId), theEventId);
然后使用CriteriaBuilder和方法将两个谓词组合成一个,如Lukas的答案所示。