Jpa存储库save()不更新现有数据

时间:2019-11-27 08:24:29

标签: java spring-boot jpa spring-data-jpa

我正在尝试更新数据,并且据我所知,如果id为null,则save()方法将保存实体;如果在数据库中找到了给定的id,则将更新数据库中的现有实体。

但是,当我尝试保存数据时,它不会更新:

public Employer update() {
    Employer emp = Employer.builder()
        .id(2L) // it exists in database
        .name('new company name')
        .build();

    return repository.save(emp);
}

但是,当我从数据库中检索数据并更新其字段并再次保存时,它会更新:

public Employer update() {
    Employer emp = repository.getOne(2L);
    emp.setName('new company name');

    return repository.save(emp);
}

有人可以解释这种现象的原因吗?我阅读了文档,但找不到与此相关的任何内容。

这是我的存储库:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface Employer extends JpaRepository<Employer, Long> {

}

和实体:

@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(schema = "public", name = "employer")
public class Employer {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @NotBlank
  @Size(max = 50)
  private String name;

}

3 个答案:

答案 0 :(得分:2)

您的实体Employer看起来处于分离/瞬态状态,并且您正在手动传递id值,该值不允许,因为它被标记为@GeneratedValue(strategy = GenerationType.IDENTITY)

您需要做的是,当您知道主键值(即id值)时,首先您要使用findById()方法从数据库中获取实体,该实体进入托管状态,然后尝试更新通过调用save()方法创建实体。这将更新您的实体。

有关实体状态的更多信息,您可以参考以下内容:    https://vladmihalcea.com/a-beginners-guide-to-jpa-hibernate-entity-state-transitions/

答案 1 :(得分:0)

要通过JPA更新现有实体对象,应首先使其对实体管理器可用。

通读文章

https://www.objectdb.com/java/jpa/query/jpql/update

摘录自同一

1.Retrieving the entity objects into an EntityManager.
2.Updating the relevant entity object fields within an active transaction.
3.Applying changes to the database by calling the commit method.

我假设在没有发生更新的情况下,该实体还不是托管实体。

有关受管实体的更多信息:https://www.baeldung.com/hibernate-entity-lifecycle#managed-entity

答案 2 :(得分:0)

这个问题已经得到解答,但这是我最近开始研究该主题时对主题的理解。

可以根据瞬态和持久/受管理实体来回答。

临时实体:创建了一个新的实体对象,该对象到目前为止尚未与任何会话相关联。由于该对象是新创建的,因此它与数据库中存储的任何数据都不相关。

从数据库中获取记录时,记录将以托管或永久状态获取,对其所做的任何更改将反映回映射到的记录。

建议1:您不应手动添加主键值,因为它已经自动递增。

建议2:如果您已经有回收ID,请先从数据库中获取它,然后再对其进行更新。

这里是关于该主题的Stackoverflow讨论,以使您获得更多见解:What are detached, persistent and transient objects in hibernate?