Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JPA更新多行_Java_Jpa_Openjpa - Fatal编程技术网

Java 使用JPA更新多行

Java 使用JPA更新多行,java,jpa,openjpa,Java,Jpa,Openjpa,我想更新ColumName值为“PCNAME”的表的所有字段。 我要更新的表名是XYZ。我只想更新一些字段,而不想保持某些字段不变 这将影响许多行,而不是一行,因为将有许多行的名称为='PCNAME' 如何使用JPA实现。我有一个与此表关联的实体类。您可以使用面向对象的方法或使用更新查询来实现 面向对象: public void setNameOfAllEntities(String newname){ List<MyEntity> items = entit

我想更新ColumName值为“PCNAME”的表的所有字段。 我要更新的表名是XYZ。我只想更新一些字段,而不想保持某些字段不变

这将影响许多行,而不是一行,因为将有许多行的名称为='PCNAME'
如何使用JPA实现。我有一个与此表关联的实体类。

您可以使用面向对象的方法或使用更新查询来实现

面向对象:

public void setNameOfAllEntities(String newname){
    List<MyEntity> items =
        entityManager.createQuery("from MyEntity", MyEntity.class)
            .getResultList();
    for(MyEntity entity : items){
        entity.setName(newname);
    }
}
public void setNameOfAllEntities(final String newname){

    final int changes =
        entityManager.createQuery("update MyEntity set name = :name")
            .setParameter("name", newname)
            .executeUpdate();

    System.out.println(changes + " rows changed");

}
显然,第二个版本的性能更好。

seanizer是正确的(+1),对于这个用例,批量更新确实很好。但是,您必须对批量更新操作采取一些预防措施。要解释JPA规范,请执行以下操作:

  • 批量更新绕过乐观锁定检查(因此您必须手动增加版本列和/或手动验证版本列(如果需要))
  • 持久性上下文未与批量操作的结果同步(因此,在加载任何可能受影响的实体的状态之前,批量操作应在单独的事务中或在事务的最开始执行)
因此,我的建议是至少增加version列,以避免与其他线程的并发问题:

UPDATE XYZ xyz
SET xyz.name = :newname, xyz.version = xyz.version + 1 
并在单独的事务中或在加载前面解释的任何XYZ之前执行它

工具书类
  • JPA1.0规范
    • 第4.10节“批量更新和删除操作”

自Java Persistence 2.1以来,您可以使用Criteria API进行批量更新

CriteriaUpdate<Entity> criteriaUpdate = builder.createCriteriaUpdate(Entity.class)
     .set(root.get("field"), value)
     .where(predicates);
int updated = entityManager.createQuery(criteriaUpdate).executeUpdate();
CriteriaUpdate-CriteriaUpdate=builder.createCriteriaUpdate(Entity.class)
.set(根.get(“字段”),值)
.where(谓词);
int updated=entityManager.createQuery(criteriaUpdate.executeUpdate();
请记住:

Criteria API批量更新操作直接映射到数据库更新操作,绕过任何乐观锁定检查。如果需要,使用批量更新操作的便携式应用程序必须手动更新版本列的值,和/或手动验证版本列的值。持久性上下文与批量更新的结果不同步


嗨,帕斯卡,这个答案和你上面的评论是否适用于JPA2.0?我的应用程序需要进行一些乐观的锁定检查。提前感谢。嗨@arthur,我刚刚在GlassFish 4.1/EclipseLink 2.5.2/JPA 2.1上运行了一个批量更新,发现在批量更新中自动使用了一个版本字段(即@version),例如,“update…SET version=(version+?)、fieldToBeUpdate=…”和“?”绑定为1。我想知道为什么会这样做,也许可以预见,在某些情况下,可能会出现不止一个版本计数器增加。当然,wrt持久性上下文同步的危险仍然存在。