Java 不支持带有 JPA 更新查询的 DML 操作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31503103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:10:34  来源:igfitidea点击:

Not supported for DML operations with JPA update query

javahibernatespring-mvcjpahql

提问by Mike3355

This has been asked once before but the solution did not solve the issue. I am creating a JUnit test:

这已经被问过一次,但解决方案没有解决问题。我正在创建一个 JUnit 测试:

 @Test
    @Transactional
    @Modifying
    public void updateMaterialInventory() throws Exception{

        // Initialize the database
        materialRepository.saveAndFlush(material);

        long id =  material.getId();
        materialRepository.updateMaterialInventory(id,UPDATED_INVENTORY_COUNT);

        assertEquals(material.getInventory_count(), UPDATED_INVENTORY_COUNT, 0);
    }

The query the above test is calling is:

上述测试调用的查询是:

 @Query("UPDATE Material m SET m.inventory_count = ?2 WHERE m.id = ?1")
    void updateMaterialInventory(Long id,int newInventoryAmount);

Error:

错误:

Caused by: org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML operations [UPDATE com.htd.domain.Material m SET m.inventory_count = ?2 WHERE m.id = ?1]
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.errorIfDML(QueryTranslatorImpl.java:318)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:369)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:231)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1264)
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103)
    at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573)
    at org.hibernate.jpa.internal.QueryImpl.getSingleResult(QueryImpl.java:495)
    ... 55 more

采纳答案by JB Nizet

The @Modifyingannotation must be placed on the updateMaterialInventorymethod, along to the @Queryannotation, to let Spring-data know that the query is not a query used to select values, but to update values.

@Modifying注释必须放在该updateMaterialInventory方法,沿途的@Query注解,让Spring的数据知道查询不是用来选择值的查询,但更新值。

回答by tk_

As far as I understand, you should not use @Transactionalannotation in the repository class. Find the below answer.

据我了解,您不应该@Transactional在存储库类中使用注释。找到下面的答案。

Service Impl class

服务实现类

import org.springframework.transaction.annotation.Transactional;
...
@Test
@Transactional
public void updateMaterialInventory() throws Exception{

    // Initialize the database
    materialRepository.saveAndFlush(material);

    long id =  material.getId();
    materialRepository.updateMaterialInventory(id,UPDATED_INVENTORY_COUNT);

    assertEquals(material.getInventory_count(), UPDATED_INVENTORY_COUNT, 0);
}

Repository class

存储库类

import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
...

  @Modifying
  @Query("UPDATE Material m SET m.inventory_count = ?2 WHERE m.id = ?1")
  void updateMaterialInventory(Long id,int newInventoryAmount);

make sure to use the correct imports. hope this is helpful.

确保使用正确的导入。希望这是有帮助的。

回答by Champika Wijesundara

@Transactional
@Modifying
@Query(DELETE_INVOICE_BY_NUMBER)
public void deleteInvoiceByNumber(@Param("number") int number);

This worked for me, But without @Transactional in the repository class it give an error.

这对我有用,但是在存储库类中没有 @Transactional 它会出错。