обновление нескольких строк с использованием JPA - PullRequest
10 голосов
/ 01 ноября 2010

Я хочу обновить все поля таблицы со значением столбца NAME как «PCNAME».Имя таблицы, которую я хочу обновить, - XYZ. Я хочу обновить только некоторые поля и не оставлять некоторые без изменений.

Это повлияет на множество строк, а не на одну строку, так как будет много строк с ИМЯ = 'PCNAME 'Как я могу сделать это с помощью JPA. У меня есть класс сущностей, связанный с этой таблицей.

Ответы [ 2 ]

21 голосов
/ 01 ноября 2010

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

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

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

}

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

16 голосов
/ 02 ноября 2010

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

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

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

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

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

Ссылки

  • JPA 1.0 спецификация
    • Раздел 4.10 «Операции массового обновления и удаления»
...