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

标签 java hibernate jpa spring-data-jpa spring-data

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

相关文章:

java - 来自 Java 的 Flex 图表的 ArrayCollections

Java Read 如何读取输入的第一个单词然后读取其余部分

java - Spring 启动 PostgreSQL

Eclipse – Hibernate 工具 – 新的连接配置文件

java - 获取ManyToMany映射表的id

sql-server-2005 - JPA/Hibernate/MS SQL Server 不返回生成的 id 值

java - 我无法在 JPQL/Hibernate 中沮丧 - 无法找到 ID 为 16 的域。Scoreable

java - J2EE - 动态 Web 项目 - 无法运行我的 helloworld 应用程序

java - 使用 XSD 进行 XML 验证如何工作?

java - JPA2中需要使用按位“&”运算符