Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deleting an object by its ID and version in JPA

I am learning JPA, and I am trying to use it in a Spring MVC web app. I need to implement a method that deletes an object/record. Currently, I have the following implementation of the method:

@Transactional
public void deleteProduct(int productId, int productVersion) {

    Product product = entityManager.find(Product.class, productId);
    product.setVersion(productVersion);
    entityManager.remove(product);
}

productVersion is used for optimistic locking. It is the old version of the object/record that comes from the web GUI.

This method deletes the record in the DB, but it does not throw any exception when the version of the record in the DB does not match productVersion. (I only have a problem with deleting objects: when I update a record with entityManager.merge(product), I get an exception with the message: Row was updated or deleted by another transaction.)

Hibernate generates the following SQL query: delete from Product where id=? and version=?, i.e. it tries to check the version field.

What am I doing wrong?

Also, is it a correct approach to removing an object by its id? I am concerned that my method generated two SQL queries: a SELECT for entityManager.find(), and a DELETE for entityManager.remove(). Is there a more optimal way to delete an object/record?

Product class

@Entity
public class Product {

    @Id
    @GeneratedValue
    protected int id;

    protected String name;

    protected BigDecimal price;

    @Version
    protected int version;

    // getters and setters
}
like image 353
Alex Avatar asked Aug 21 '14 10:08

Alex


1 Answers

One way is to do it manually in one query as follows:

@Transactional
public void deleteProduct(int productId, int productVersion) {
   int isSuccessful = entityManager.createQuery("delete from Product p where p.productVersion=:productVersion and p.id=:id")
            .setParameter("id", productId)
            .setParameter("productVersion", productVersion)
            .executeUpdate();
    if (isSuccessful == 0) {
        throw new OptimisticLockException(" product modified concurrently");
    }
}
like image 86
Varun Phadnis Avatar answered Sep 18 '22 22:09

Varun Phadnis