【问题标题】:How to build a JPA 2.0 query如何构建 JPA 2.0 查询
【发布时间】:2011-12-29 12:05:15
【问题描述】:

我有两个实体:事件和评论。

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

所以每个事件都有一个 cmets 列表,每个评论都有一个更新时间。

我想使用 Criteria API 来构造一个查询,以便选择具有至少一个新 cmets 的所有事件。 (新评论意味着它的更新时间晚于给定的日期时间)

感谢任何人帮助我。


抱歉,我上面问的问题不完整:我想要的是使用 Criteria API 构造一个查询,以便选择具有至少一个新 cmets 并且 eventId 等于某个特定 eventId 的所有事件.

我试过了:(给定Date lastCheckedTimeLong 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();

上面的代码可以选择有新cmet的事件,但是现在不知道怎么添加eventId的条件。

【问题讨论】:

  • 我认为这不适合这里的 q/a 格式。你不应该只是发布一个任务并要求人们去做。更好的是尝试一些东西,当你遇到困难时寻求具体的帮助。
  • JPQL 更容易用于这样的静态查询。你为什么不使用JPQL?此外,一旦有了 JPQL 查询,将其转换为条件会更容易。
  • @ArjanTijms 好的,我会发布到目前为止我尝试过的内容。
  • @Thomas 我已经发布了到目前为止我尝试过的内容。
  • @JBNizet 感谢您的建议,但是为了与之前的代码保持一致,我需要使用 Criteria API。

标签: java sql hibernate jpa jpa-2.0


【解决方案1】:

在事件上创建一个连接,并对事件的 ID 应用限制:

Join<Comment, Event> event = c.join(Comment_.event);
Predicate eventIdPredicate = cb.eq(event.get(Event_.eventId), theEventId);

然后使用 CriteriaBuilder 的 and 方法将两个谓词合二为一,如 Lukas 的回答所示。

【讨论】:

  • 啊,疯了,在这种情况下我错过了加入的需要。 JPA 的冗长总是让我...
  • 您好,当我使用上面的代码检索事件时,我无法获取关联的 cmets。有一个异常:com.sun.jdi.InvocationException 发生调用方法。你知道为什么会这样吗?
  • 没有。拥有堆栈跟踪会有所帮助。
  • 它没有堆栈跟踪。我可以得到事件列表,但是关联的 cmets 变成了 Persistence bag。
  • 对不起,现在没问题,是其他地方的错误,我已经修复了。
【解决方案2】:

CriteriaBuilder 有一个 and(Predicate...) 方法。然后,您将连接您的两个谓词:

cq.where(cb.and(lastCheckedTimeCondition, someEventIdCondition));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 1970-01-01
    • 1970-01-01
    • 2011-11-16
    • 2018-08-30
    • 1970-01-01
    相关资源
    最近更新 更多