Spring Data JPA 删除查询不起作用。

32

我正在尝试在我的仓库中创建一个自定义的deleteBy方法查询。看起来Hibernate并没有执行删除操作,而是生成了一个select语句。

public interface ContactRepository extends JpaRepository<Contact, Integer> {

    Integer deleteByEmailAddress(String emailAddress);

    //and this one works
    Contact findContactByName(String name);
}

以下是Hibernate的操作:

Hibernate:select contact0_.id as id1_2_,contact0_.emailAddress as emailAddress2_2_,contact0_.name as name3_2_ from Contact contact0_ where contact0_.emailAddress=?

我错过了什么?我需要做特殊的配置才能使删除操作生效吗?

3个回答

47

您的删除操作是否无法正常工作或不符合您的期望?通常在删除实体之前,需要先对其进行管理,因此JPA提供程序(在您的情况下为Hibernate)将首先加载实体(查询您看到的内容),然后发出删除操作。

如果您仅看到查询而没有相应的删除操作,则可能有以下几种可能性:

  1. 没有要删除的内容,请确保记录存在于数据库中。
  2. 删除操作需要成为事务的一部分。我相信Spring数据CRUD操作默认是事务性的,如果不是,请确保调用deleteByEmailAddress的任何内容都是事务性的。

注意:您可以使用修改查询删除来避免选择实体, 以下是一个示例:

// NOTE: you have return void
@Modifying
@Transactional
@Query(value="delete from Contact c where c.emailAddress = ?1")
void deleteByEmailAddress(String emailAddress)

6
在我给该方法加上@transactional注解之后,它可以正常工作。非常感谢您,先生!注意:使用查询(Query)也可以使其工作,但我只想要一个功能性的方法查询。 - Alexandru Pirvu
2
感谢关于 // NOTE: you have return void 的提醒 - 我已尝试了所有方法,但没有想到这一点,这正是我的问题所在! - yetanothercoder
@ikumen 查询使用修改和事务注释运行良好,但在数据库中仍然存在该行。 - Abhij
只是要添加此列表的更多内容:在实体中,您可能希望添加 entityManager.flush() 和 entityManager.clear()。 也许一个原因是因为上下文尚未刷新,所以没有看到 delete。当使用复合键时,deleteBy...不会生成“按预期”的查询。 - Martin Mucha
1
在我的情况下,我有一个事务方法调用了一个非事务方法,并调用了deleteBy。我认为事务会被传播(这是Spring事务的默认行为),但在这种情况下,deleteBy没有起作用。当我也用@transactional注释第二个方法时,它就起作用了。 - ihebiheb
我的问题在添加 @Transactional 后得到了解决。 - Morteza

3

3
那是我开始的地方,但它没有回答我的问题。 - Alexandru Pirvu
1
Spring首先调用查询行的方法,然后使用主键进行第二次调用以删除行......如果id是主键,则应该看到类似于Hibernate: delete from conatact where id =?的内容。 - Cristian J. Brito

-3
尝试将删除查询调用移动到专门的服务类中:
@FunctionalInterface
public interface DeleteService {

    public int deleteIfExists(Date fechaProceso);

}

例如,在DeleteServiceImpl.java中实现它


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接