it-swarm.com.de

Nicht unterstützt für DML-Vorgänge mit JPA-Aktualisierungsabfrage

Dies wurde schon einmal gefragt, aber das Problem wurde durch die Lösung nicht gelöst. Ich erstelle einen JUnit-Test:

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

Die Abfrage, die der obige Test aufruft, lautet:

 @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
29
Drew1208

Die @Modifying-Annotation muss zusammen mit der @Query-Annotation auf der updateMaterialInventory-Methode platziert werden, damit Spring-data wissen kann, dass die Abfrage keine Abfrage ist, die zum Auswählen von Werten verwendet wird, sondern um Werte zu aktualisieren.

71
JB Nizet

Soweit ich weiß, sollten Sie in der Repository-Klasse keine @Transactional-Annotation verwenden. Hier finden Sie die Antwort.

Klasse "Service Impl"

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-Klasse

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);

stellen Sie sicher, dass Sie die richtigen Importe verwenden. hoffe das ist hilfreich.

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

Das hat für mich funktioniert, aber ohne @Transactional in der Repository-Klasse gibt es einen Fehler.