【问题标题】:Spring JPA derived delete querySpring JPA 派生的删除查询
【发布时间】:2016-02-14 06:02:00
【问题描述】:

我在 Spring JPA 中使用 Spring Data rest。我有一个 Spring JPA 派生的删除查询,它应该删除项目列表,但是当我执行它并注意到控制台时,我发现它正在执行选择查询,而不是我遇到过的非常奇怪的情况。

@RepositoryRestResource(collectionResourceRel="revision", path="revision")
interface RevisionRepository extends JpaRepository<Revision, Long> {

     List<Revision> deleteByContentId(long contentId)
}

我什至尝试使用 Long 而不是 List&lt;Revision&gt; 不起作用,也尝试过 removeByContentId 它也不起作用,并继续执行选择查询而不是删除查询。

当我运行此方法时,这就是我在控制台上得到的结果

Hibernate: select revision0_.id as id1_2_, revision0_.body as body2_2_, revision0_.content_id as content_3_2_, revision0_.content_type as content_4_2_, revision0_.date_created as date_cre5_2_, revision0_.file_name as file_nam6_2_, revision0_.folder_id as folder_i7_2_, revision0_.force_ssl as force_ss8_2_, revision0_.is_active as is_activ9_2_, revision0_.lookup as lookup10_2_, revision0_.meta_description as meta_de11_2_, revision0_.meta_keywords as meta_ke12_2_, revision0_.meta_title as meta_ti13_2_, revision0_.nav_item as nav_ite14_2_, revision0_.nav_order as nav_ord15_2_, revision0_.regions_objects as regions16_2_, revision0_.summary as summary17_2_, revision0_.title as title18_2_, revision0_.updated_by as updated19_2_, revision0_.user_id as user_id20_2_ from revisions revision0_ where revision0_.content_id=?

有没有人知道为什么它的行为很奇怪?

【问题讨论】:

  • 它真的“删除”了吗?我的意思是,这个方法真的有效吗?
  • 不,它不起作用。它不会删除任何内容。
  • 您使用的是哪个版本的 JPA?
  • 请给我们看看 deleteByContentId 方法的代码好吗?
  • @Bonifacio - 我正在使用 JPA 派生查询,没有代码,我只需要使用 deleteByFieldName 就可以了。

标签: spring hibernate spring-mvc jpa spring-data-rest


【解决方案1】:

您需要在删除方法中添加@Modifying 注释。您还需要确保它在事务中执行,因此如果您不在事务中调用此方法,您可能还需要添加 @Transactional 注释。

请看一个例​​子:

@Modifying
@Transactional
int deleteByFieldName( Long fieldValue );

【讨论】:

  • 当我使用这个 JPA 查询时它已经可以正常工作了
  • 让它没有明确的 JPA 查询...您的问题缺少 @Modifying 注释
  • 哇,好用...我有另一个存储库,其中我有删除方法,但没有这些注释仍然可以工作,但在这里没有工作。
  • 这可能是因为 JPA 版本。见这里:stackoverflow.com/questions/23723025/…
  • 这可能是因为您已经在事务上下文中调用该方法(在您的其他地方)
【解决方案2】:

在最新的 Spring >=5 和 Spring Boot >=2.

@Transactional
int deleteByFieldname( Long fieldValue );

工作正常。

注 1: @Modififyng 注释对此完全没有影响。它仅适用于 @Query 注释。没有@Query,它会被忽略。

注意 2: 在命名约定中,这取决于配置的 NamingStrategy,CamelCase 可能被解释和嵌套实体关系或字段名称中的“_”。所以“Fieldname”和“FieldName”的意思是完全不同的。

注 3: 像这样的派生删除查询有一个非常讨厌的 n+1 副作用。他们总是首先对行进行选择,然后使用单独的删除词条逐一删除每一行/实体。没有办法解决这个问题,除非使用带有手动删除语句的 @Query()。然后使用@Query 需要@Modifying 进行删除查询。

【讨论】:

    猜你喜欢
    • 2021-03-15
    • 2020-05-20
    • 2016-05-27
    • 2020-12-17
    • 1970-01-01
    • 2021-06-28
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多