通过JPA中的ID和版本删除对象

时间:2014-08-21 10:20:54

标签: spring hibernate spring-mvc jpa

我正在学习JPA,我正在尝试在Spring MVC Web应用程序中使用它。我需要实现一个删除对象/记录的方法。目前,我有以下方法的实现:

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

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

productVersion用于乐观锁定。它是来自Web GUI的旧版本的对象/记录。

此方法删除数据库中的记录,但当数据库中的记录版本与productVersion不匹配时,它不会引发任何异常。 (我只有删除对象时出现问题:当我更新包含entityManager.merge(product)的记录时,我收到一条消息:Row was updated or deleted by another transaction。 )

Hibernate会生成以下SQL查询:delete from Product where id=? and version=?,即它会尝试检查version字段。

我做错了什么?

此外,通过其ID删除对象是否正确?我担心我的方法生成了两个SQL查询:SELECT entityManager.find()DELETE entityManager.remove()。是否有更优化的方法来删除对象/记录?

产品类

@Entity
public class Product {

    @Id
    @GeneratedValue
    protected int id;

    protected String name;

    protected BigDecimal price;

    @Version
    protected int version;

    // getters and setters
}

1 个答案:

答案 0 :(得分:6)

一种方法是在一个查询中手动执行,如下所示:

@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");
    }
}