Обновлять сущность и перезаписывать только ненулевые значения (без динамического запроса) - PullRequest
1 голос
/ 12 мая 2019

Я хочу обновить существующую сущность, передав «неполный» экземпляр этой сущности в JpaRepository.Под неполным я подразумеваю, что установлены только те значения, которые я хочу изменить, а остальные значения null.Теперь, если я сделаю это, все значения null будут сохранены как null и, следовательно, перезапишут значения, которые я хочу сохранить.

Сначала я подумал о загрузке сущности из базы данных и каким-то образом объединить изменения в этот загруженный объект и снова сохранить его, но должен быть лучший подход.

Моя сущность:

@Entity
@Table
public class Location {

    @Id
    @NotNull
    @Type(type = "uuid-char")
    private UUID id = UUID.randomUUID();

    @Column
    @NotEmpty
    private String title;

    @Column
    @NotEmpty
    private String description;
...

Мой репозиторий:

@Repository
public interface LocationRepository extends JpaRepository<Location, UUID>, LocationFilterFragment, JpaSpecificationExecutor {

    Optional<Location> findLocationById(UUID id);
...

Кстати, я использую стандартный метод repo.save(location).

Обновление: Одним из способов может быть использование динамического запроса / критерия, но я ищу что-то более удобное и менее подверженное ошибкам.

Этого было бы достаточночтобы показать мне правильное направление, потому что я не знаю точно, что искать.Заранее спасибо!

1 Ответ

1 голос
/ 13 мая 2019

Мой первый подход: не объединяйте свой незавершенный объект. Если вы вызовете save в своем хранилище (что означает merge в entityManager), Hibernate воспримет это как текущее состояние и обновит все значения.

Я бы поступил следующим образом:

  • найдите сущность, которую вы хотите изменить, по идентификатору
  • установите значения, которые вы хотите изменить, скопировав их из вашего "незавершенного объекта"

Помните, что эти 2 шага должны быть выполнены за одну транзакцию. При выходе из области транзакции hibernate будет полагаться на свой грязный механизм проверки и обновлять сущность (не требуется merge вызов). При таком подходе ваш «неполный объект» не обязательно должен быть сущностью, он никогда не сохраняется.

Обратите внимание, что по умолчанию все поля будут отправлены в запросе на обновление (но теперь неизмененные поля не являются нулевыми, они отражают предыдущее состояние дБ), если вы хотите, чтобы только грязные поля были частью вашего запроса, узнайте о @DynamicUpdate

Еще одно замечание: если вы перейдете к пользовательскому обновлению API jpql или критерия, у вас будет преимущество, если один выбор не будет выполнен. С другой стороны, Hibernate не знает об изменениях и не обновляет свои кэши.

...