Spring Data JPA и Spring Web Updating Entities, избегающие ассоциаций

У меня есть следующие сущности:

  • Область
  • Листинг

Оба они относятся к числу многих-ко-многим:

  • В области может быть много объявлений
  • В листинге может быть много областей

И Area, и Listing имеют другие поля, такие как name, domain и т. д.

Я использую Spring Web RestController как способ обновления сущностей.

Например:

@PutMapping("/{id}")
public Area update(@PathVariable Long id, @RequestBody Area update) {
    return areaRepository.save(update);
}

Однако, поскольку Area может иметь много тысяч Listing, нецелесообразно передавать их все в запросе на обновление, когда я просто хочу обновить имя Area и другие базовые поля в моем веб-приложении.

Например, json update в http-запросе будет выглядеть так:

{
  "id" : 69,
  "name" : "San Francisco",
  "domain" : "foo",
  ...
}

При сериализации приведенный выше экземпляр area будет иметь поле listings, равное null (очевидно), а затем при сохранении все ассоциации удаляются из этого Area.

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

Возникает вопрос: как я могу попытаться сохранить приведенный выше код и HTTP-запрос и не удалить все существующие ассоциации Listing при сохранении области ввода? Это возможно? Я хочу обновить имя и другие основные поля, но не поля ассоциации.

1
0
275
2

Ответы 2

Вы можете использовать BeanUtilBean (org.apache.commons.beanutils.BeanUtilsBean).

Шаг 1. Создайте собственный класс beanutilbean.

@Component
public class CustomBeanUtilsBean extends BeanUtilsBean {
    @Override
    public void copyProperty(Object dest, String name, Object value)
            throws IllegalAccessException, InvocationTargetException {
        if (value==null)return;
        super.copyProperty(dest, name, value);
    }
}

Шаг 2: В вашем контроллере во время обновления. сначала получите Area из базы данных и используйте метод copyProperties, как показано ниже.

@PutMapping("/{id}")
public Area update(@PathVariable Long id, @RequestBody Area update) {
    Area areaDB = areaRepository.findOne(update.getId());
    customBeanUtilsBean.copyProperties(areaDB,update);//it will set not null field values of update to areaDB.
    return areaRepository.save(areaDB);
}

Надеюсь, это поможет вам .. :)

Поскольку вы используете spring-data-jpa repository, вы можете написать новый метод, который принимает объект changed values of Area с аннотациями @Modifying и @Query на нем.

В @Query вы указываете HQL query with update statement как в здесь

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