Home > Net >  Spring Data JPA - JPQL update query - printing out unupdated value
Spring Data JPA - JPQL update query - printing out unupdated value

Time:05-02

Trying out doing update Queries in Spring Data JPA. In my test method (see below) I'm saving one student with firstName="Bill" and lastName="Smith". How can it be that I'm getting "Bill" printed out to the console (very last line), given that studentRespository.findByFirstName("John") actually gives a list with one member? Any help appreciated...

    @Modifying(flushAutomatically = true)
    @Transactional
    @Query("update Student s set s.firstName = ?1 where s.lastName= ?2")
    public void updateFirstNameByLastName(String firstName, String lastName)

    @Test
    public void updateStudentFirstNameByLastName() {
        studentRepository.save(student); //student.firstName="Bill", student.lastName="Smith"
        studentRepository.updateFirstNameByLastName("John", "Smith");
        List<Student> studentList = studentRepository.findByFirstName("John"); // size 1
        System.out.println(studentList.get(0).getFirstName()); // "Bill"
    }

CodePudding user response:

I guess your test didn't commit anything to the database

Try to add @Rollback(value = false) to the test class may help

Spring boot with JUnit 5 test

CodePudding user response:

According to the JPA’s entity lifecycle states save() method may not write your changes to database immediately.

Since we use @Modifying in update query, this triggers the query annotated to the method as an updating query instead of a selecting one.

Reason for above issue is, when we save(), the persistence context of this with outdated entities may still there after the execution of the modifying query. EntityManager do not automatically clear it. If you wish the EntityManager to be cleared/flushed automatically, you can set the @Modifying annotation’s clearAutomatically and flushAutomatically attribute to true. Check this official doc Modifying Queries.

Annotation Type Modifying

clearAutomatically(true/false) - Defines whether we should clear the underlying persistence context after executing the modifying query. (Default -false)

flushAutomatically(true/false) - Defines whether we should flush the underlying persistence context before executing the modifying query. (Default -false)

Add this @Modifying(clearAutomatically = true, flushAutomatically = true) to the updateFirstNameByLastName method as below.

@Modifying(clearAutomatically = true, flushAutomatically = true)
@Transactional
@Query("update Student s set s.firstName = ?1 where s.lastName= ?2")
public void updateFirstNameByLastName(String firstName, String lastName)
  • Related