使用瞬态实例通过id更新JPA中的实体

时间:2017-12-03 01:21:21

标签: java jpa

所以我有以下情况:

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

@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个字段都会发生变化,所以这样做感觉不对。

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

1 个答案:

答案 0 :(得分:0)

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