【问题标题】:Updating entities in JPA by id by using transient instance [duplicate]使用瞬态实例按 id 更新 JPA 中的实体 [重复]
【发布时间】:2023-04-03 21:20:02
【问题描述】:

所以我有以下情况:

我有一个包含大量字段(超过 20 个)的客户实体。客户 类看起来像这样(我只列出了前几个字段):

@Entity
public class Customer {

    @Id
    @GeneratedValue
    private long id;

    @Version
    private version version;

    private String firstName;

    private String lastName;

    private String email;
    .
    .
    .
}

现在我有一个方法可以通过 RESTful Web 服务接收客户的所有值来更新客户。服务方法看起来像这样:

@PUT
@Path("{id}")
@Consumes("application/json")
@Produces("application/json")
public Response editCustomer(@PathParam("id") long id, Customer customer) {
    return FacadeUtils.buildResponse(updateCustomer(customer, id));
}

我的 updateCustomer 看起来像这样:

public Result updateCustomer(Customer customer, long id) {
    @PersistenceContext
    private EntityManager em;

    customer.setId(id);

    em.merge(customer);
    .
    .
    .
}

但是,当我尝试执行更新时,出现以下异常:

org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

我知道我可以使用oldCustomer = em.find(Customer.class, id); 将对象加载到持久化上下文中,然后使用oldCustomer.setXXX(customer.getXXX); 设置我需要的所有值

但是,由于我有很多字段要更新(有时所有 20 个字段都会更改,所以这样做感觉不对。

我知道我可以尝试使用反射或 Apache Bean Utils 来复制字段,但必须有一些更优雅的解决方案。有什么想法吗?

【问题讨论】:

    标签: java jpa


    【解决方案1】:

    我认为这里的主要问题是版本字段,您需要一个有效的版本值才能正确合并。您可以让 rest 调用传递它之前收到的版本值。

    【讨论】:

      猜你喜欢
      • 2020-01-11
      • 1970-01-01
      • 2012-01-25
      • 2012-05-03
      • 2023-04-05
      • 2018-04-01
      • 2019-02-09
      • 2011-06-21
      • 1970-01-01
      相关资源
      最近更新 更多