【问题标题】:Using a JPA 2 TypedQuery for updates使用 JPA 2 TypedQuery 进行更新
【发布时间】:2012-05-26 19:32:05
【问题描述】:

假设一个简单的 JPA 实体类是这样的:

@Entity(name="TASK")
public class Task implements Serializable {
    /* getters/setters omitted for brevity */

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    private Date done;
}

如何使用 JPA 2 TypedQueryCriteriaQuery 和元模型来执行与简单的 UPDATE TASK SET done = ? WHERE id = ? SQL 查询等效的操作?我在网上能找到的所有东西都会导致像这样使用 JPA

Query q = em.createQuery(
  "UPDATE TASK SET done = :date WHERE id = :id");
q.setParameter(/* set date and id */);
q.executeUpdate();

这可以用TypedQuery 代替吗?

【问题讨论】:

    标签: java jpa-2.0


    【解决方案1】:

    您应该执行此类操作的 JPA 方式是让 CriteriaQuery 选择要修改的项目,并使用纯 Java 循环遍历它们,然后使用 merge() 方法修改它们。比如:

    Date d;
    CriteriaQuery<Task> cq = cb.createQuery(Task.class);
    ...
    TypedQuery<Task> tq = em.createQuery(cq);
    List<Task> tasks = tq.getResultList();
    for (Task task : tasks) {
        task.setDone(d);
        em.merge(task);
    }
    // or
    Task task = tq.getSingleResult();
    task.setDone(d);
    em.merge(task);
    

    请参阅此answer 以获取更多参考。

    【讨论】:

    • 感谢您的回答。我对这种方法的担忧是,它似乎会导致重复的读取-修改-写入循环,而简单的 SQL 更新语句将允许数据库进行更新,而无需将所有受影响的行传输到客户端并返回到数据库。根据受影响的行数,这可能会产生很大的不同。还是 JPA 层能够优化 RMW 循环?
    • 我理解您的担忧,我认为,对于额外的客户端-服务器往返问题,您是对的。但是,您可以处理许多优化。例如,请参阅此链接:java-persistence-performance.blogspot.com/2011/06/…
    猜你喜欢
    • 1970-01-01
    • 2018-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    相关资源
    最近更新 更多