1

Ich habe die folgende Methode in einem JpaRepository, die einfach die parent_id Spalte für jede Zeile mit einem bestimmten Wert in dieser Spalte aktualisiert. Es funktioniert perfekt in reinem SQL, aber es ist in Spring Data fehlgeschlagen. Ich denke, es liegt nur an einem Problem mit dem Transaktionsumfang, weil das Update fertig ist (erstes Assert passiert). Es ist nur ich kann nicht sehen, welcher Code in DB geändert wird. Ich möchte die@Transaction Annotation für Integrationstest in Spring Boot

@Transactional 
@Rollback 

verwenden, weil ich denke, das ist Best Practice. Gibt es irgendeine Möglichkeit, was ich im Code von meiner Testmethode sehen kann?

@Modifying 
@Query("update MovementCategory mc set mc.parentId = :newParentId where mc.parentId = :previousParentId and mc.userId = :userId") 
int updateChildrenParentId(@Param("userId") long userId, @Param("previousParentId") long previousParentId, @Param("newParentId") long newParentId); 

Ich habe eine einfache Integrationstest erstellt, die überprüft, ob Änderungen in DB richtig eingestellt, aber es scheint nicht zu arbeiten, und ich kann nicht, warum zu sehen bekommen. Ich dachte, es könnte wegen des Umfangs der Transaktion sein, aber ich habe einen kleineren Test gemacht und ihn verworfen, also keine Ahnung. Das Folgende ist der Integrationstest.

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = MySpringBootMavenApplication.class) 
@WebAppConfiguration 
@IntegrationTest("server.port:0") 
@Transactional 
@Rollback 
public class MovementCategoryRepositoryIT { 

private static final long USER_ID = -1L; 

@Autowired MovementCategoryRepository repo; 

@Test 
public void testUpdateChildrenParentId() { 

    long newParentId= -9723854; 
    long previousParentId = -1239842; 

    MovementCategory mc1 = getFilled(null, "DELETE ME"); 
    mc1.setParentId(previousParentId); 
    mc1 = repo.saveAndFlush(mc1); 

    int updates = repo.updateChildrenParentId(USER_ID, previousParentId, newParentId); 

    // First assert passes, so there update is done 
    assertEquals(1, updates); 

    MovementCategory children1 = repo.findOneByIdAndUserId(mc1.getId(), USER_ID); 

    // Second one fails 
    assertEquals(newParentId, children1.getParentId().longValue()); 

} 

Ergebnis:

java.lang.AssertionError: expected:<-9723854> but was:<-1239842> 
    at org.junit.Assert.fail(Assert.java:88) 
    at org.junit.Assert.failNotEquals(Assert.java:834) 
    at org.junit.Assert.assertEquals(Assert.java:645) 
    at org.junit.Assert.assertEquals(Assert.java:631) 
    at com.ldepablo.repository.MovementCategoryRepositoryIT.testUpdateChildrenParentId(MovementCategoryRepositoryIT.java:171) 
    ... 

Antwort

0

Sie müssen die Transaktion starten explizit zu lesen und auch explizit Rollback der Transaktion wie der Rest Anrufe in einer anderen Sitzung als der Test sind. Verwenden Sie TransactionTemplate wie in this answer beschrieben.

(Beantworten zu spät, natürlich, aber das war der erste Treffer auf der Suchmaschine)