gpt4 book ai didi

java - 更新实体并仅覆盖非空值(无需动态查询)

转载 作者:行者123 更新时间:2023-11-30 05:38:51 25 4
gpt4 key购买 nike

我想通过将现有实体的“不完整”实例传递给 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)方法。

更新:一种方法可能是使用动态查询/条件查询,但我正在寻找更方便且不易出错的方法。

这足以向我展示正确的方向,因为我不知道到底要寻找什么。提前致谢!

最佳答案

我的第一个方法是:不要合并不完整的对象。如果您在存储库上调用save(这会转换为在entityManager 上进行merge),Hibernate 会将其视为当前状态,并将更新所有值。

我将继续执行以下操作:

  • 通过 ID 查找要更改的实体
  • 通过从“不完整对象”复制值来设置要更改的值

请记住,这两个步骤必须在一个事务中执行。当退出事务范围时,hibernate将依赖其脏检查机制并更新实体(不需要合并调用)在这种方法中,您的“不完整对象”不一定是实体,它永远不会坚持下来了。

请注意,默认情况下,所有字段都将在更新查询中发送(但现在未更改的字段不为空,它们反射(reflect)了 dB 的先前状态)如果您只想脏字段成为查询的一部分,请了解@DynamicUpdate

另一个注意事项:如果您进行自定义 jpql 或条件 API 更新,您将获得一个不执行的选择的好处。不利的一面是,Hibernate 不知道这些更改,也不会更新其缓存。

关于java - 更新实体并仅覆盖非空值(无需动态查询),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56101572/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com