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
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.
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.
@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.