2012-05-26 50 views
1

假设一个简单的JPA实体类是这样的:使用JPA 2 TypedQuery更新

@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,而不是做什么?

回答

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以供进一步参考。

+1

感谢您的回答。我对这种方法的担心是,它似乎会导致重复的读 - 修改 - 写周期,而一个简单的SQL更新语句将允许数据库进行更新,而不会将所有受影响的行传输到客户端并返回到数据库。根据受影响的行数,这可能会有很大的不同。或者JPA层能够优化RMW周期吗? – Waldheinz

+0

我理解你的担忧,我认为,对于额外的客户端 - 服务器往返的事情,你是对的。然而,你可以处理一些优化。请参阅此链接,例如:http://java-persistence-performance.blogspot.com/2011/06/how-to-improve-jpa-performance-by-1825.html – perissf