Spring Boot Data JPA - Aktualisierungsabfrage ändern - Persistenzkontext aktualisieren

Ich arbeite mit Spring Boot 1.3.0.M4 und einer MySQL-Datenbank.

Ich habe ein Problem beim Ändern von Abfragen. Der EntityManager enthält veraltete Entitäten, nachdem die Abfrage ausgeführt wurde.

Original JPA Repository:
public interface EmailRepository extends JpaRepository<Email, Long> {

    @Transactional
    @Modifying
    @Query("update Email e set e.active = false where e.active = true and e.expire <= NOW()")
    Integer deactivateByExpired();

}

ngenommen, wir habenEmail [id = 1, a, ctive = true, expire = 2015/01/01] in DB.

Nach der Ausführung:

emailRepository.save(email);
emailRepository.deactivateByExpired();
System.out.println(emailRepository.findOne(1L).isActive()); // prints true!! it should print false
Erster Lösungsansatz: @ hinzufügclearAutomatically = true
public interface EmailRepository extends JpaRepository<Email, Long> {

    @Transactional
    @Modifying(clearAutomatically = true)
    @Query("update Email e set e.active = false where e.active = true and e.expire <= NOW()")
    Integer deactivateByExpired();

}

Dieser Ansatz löscht den Persistenzkontext, um keine veralteten Werte zu haben, löscht jedoch alle nicht gelöschten Änderungen, die im EntityManager noch ausstehen. Da ich nur @ benutsave() Methoden und nichtsaveAndFlush() Einige Änderungen gehen für andere Entitäten verloren:

Zweiter Ansatz zur Lösung des Problems: benutzerdefinierte Implementierung für das Repository
public interface EmailRepository extends JpaRepository<Email, Long>, EmailRepositoryCustom {

}

public interface EmailRepositoryCustom {

    Integer deactivateByExpired();

}

public class EmailRepositoryImpl implements EmailRepositoryCustom {

    @PersistenceContext
    private EntityManager entityManager;

    @Transactional
    @Override
    public Integer deactivateByExpired() {
        String hsql = "update Email e set e.active = false where e.active = true and e.expire <= NOW()";
        Query query = entityManager.createQuery(hsql);
        entityManager.flush();
        Integer result = query.executeUpdate();
        entityManager.clear();
        return result;
    }

}

Dieser Ansatz funktioniert ähnlich wie@Modifying(clearAutomatically = true) erzwingt jedoch zuerst, dass der EntityManager alle Änderungen in die Datenbank schreibt, bevor das Update ausgeführt wird, und löscht dann den Persistenzkontext. Auf diese Weise gibt es keine veralteten Entitäten und alle Änderungen werden in der Datenbank gespeichert.

Ich würde gerne wissen, ob es eine bessere Möglichkeit gibt, Update-Anweisungen in JPA auszuführen, ohne dass das Problem der veralteten Entitäten auftritt und ohne dass das manuelle Flush in die Datenbank erfolgt. Deaktivieren Sie möglicherweise den Cache der zweiten Ebene? Wie kann ich das im Spring Boot machen?

Update 2018

Spring Data JPA hat meine PR genehmigt, es gibt einflushAutomatically Option in@Modifying() jetzt

@Modifying(flushAutomatically = true, clearAutomatically = true)

Antworten auf die Frage(4)

Ihre Antwort auf die Frage