Обновление нескольких строк с использованием JPA

StackOverflow https://stackoverflow.com/questions/4069513

  •  28-09-2019
  •  | 
  •  

Вопрос

Я хочу обновить все поля таблицы, имеющего значение имени колония как «PCName». Имя таблицы, которое я хочу обновить, это XYZ.I Хотите обновить только некоторые поля и не сохранять некоторые без изменений.

Это повлияет на много строк, а не один ряд, так как будет много строк с именем = 'pcname', как я могу сделать это с помощью JPA.I иметь класс Entity, связанный с этой таблицей.

Это было полезно?

Решение

Вы можете сделать это объектно-ориентированный путь или использование запроса обновления.

Объектно-ориентированный:

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");

}

Очевидно, что вторая версия лучше выполняет.

Другие советы

серизатор отвечать правильно (+1), а объемное обновление было бы действительно приятно для этого случая использования. Но вы должны принять некоторые меры предосторожности с объемными операциями обновления. Перефразировать спецификацию JPA:

  • Обновления объемных обновлений обходят оптимистичные проверки блокировки (Итак, вы должны вручную увеличивать столбец версии и / или вручную проверить столбец версии, если это необходимо)
  • Контекст настойчивости не синхронизируется с результатом объемных операций (Таким образом, объемные операции должны выполняться в отдельной транзакции или в самом начале транзакции, прежде чем загрузка состояния любого объекта, которое может быть затронуто).

Таким образом, мое предложение будет, по крайней мере, увеличивать столбец версии, чтобы избежать проблемы параллелизма с другими потоками:

UPDATE XYZ xyz
SET xyz.name = :newname, xyz.version = xyz.version + 1 

И выполнять его в отдельной транзакции или перед загрузкой любого XYZ, как описано ранее.

использованная литература

  • Спецификация JPA 1.0
    • Раздел 4.10 "Обновление обзора и Удаление операций"
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top