0

So I have a following situation:

I have a Customer entity which has a tons of fields (over 20). The customer class looks like this (i listed just a first few fields):

@Entity
public class Customer {

    @Id
    @GeneratedValue
    private long id;

    @Version
    private version version;

    private String firstName;

    private String lastName;

    private String email;
    .
    .
    .
}

Now I have a method that should update a Customer by receiving all of it's values trough a RESTful web service. The service method looks something like this:

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

And my updateCustomer looks something like this:

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

    customer.setId(id);

    em.merge(customer);
    .
    .
    .
}

However, when I try to execute the update, I get the following exception:

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

I know I can load the object into persistence context by using oldCustomer = em.find(Customer.class, id);, and then set all the values I need by using oldCustomer.setXXX(customer.getXXX);

But, since I have a lot of fields to update (sometimes all of the 20 fields change, it just doesn't feel right to do it like this.

I am aware I can try to use Reflections, or Apache Bean Utils to do the copying of fields, but there must be some more elegant solution. Any ideas?

user3362334
  • 1,980
  • 3
  • 26
  • 58

1 Answers1

0

I think the main issue here is the version field, you need a valid version value to be able to merge correctly. You could make the rest call pass a the version value it had previously received.

Yazan Jaber
  • 2,068
  • 25
  • 36