2017-11-06 2 views
0

Ich versuche, JPA mit Querydsl (4.1.4) wie hier geschrieben http://www.querydsl.com/static/querydsl/latest/reference/html/ch02.html#jpa_integration. Ich benutze Hibernate (5.2.12.Final) als JPA-Backend. Ich erzeuge Querydsl-Abfragetypen aus den mit JPA-Anmerkungen versehenen Klassen unter Verwendung des apt-maven-plugin mit dem com.querydsl.apt.jpa.JPAAnnotationProcessor-Prozessor.Wie wird eine JPA-Entität mit Querydsl aktualisiert?

Ich habe ein Problem beim Aktualisieren einer Entität: der aktualisierte Wert wird nicht im Java-Code angezeigt. Hier ist der relevante Code-Schnipsel, die eine Boolesche Eigenschaft aktualisiert (benannt success) im Entity:

final EntityManagerFactory entityManagerFactory = PersistenceTestUtils.buildEntityManagerFactory(); 
    final EntityManager entityManager = entityManagerFactory.createEntityManager(); 
    final EntityTransaction transaction = entityManager.getTransaction(); 
    transaction.begin(); 
    final QJpaUpdateRound qJpaUpdateRound = QJpaUpdateRound.jpaUpdateRound; 
    final JPQLQueryFactory queryFactory = new JPAQueryFactory(entityManager); 

    final QJpaUpdateRound qJpaUpdateRound = QJpaUpdateRound.jpaUpdateRound; 
    final JPQLQueryFactory queryFactory = new JPAQueryFactory(entityManager); 
    final long roundId = 3L; 

    System.out.println("Original " +originalRound); 

    queryFactory // 
     .update(qJpaUpdateRound) // 
     .set(qJpaUpdateRound._success, true) // 
     .where(qJpaUpdateRound._id.eq(roundId)) // 
     .execute(); 

    // entityManager.clear(); // Workaround 

    // Fetch the updated value 
    final UpdateRound updatedRound = queryFactory // 
     .selectFrom(qJpaUpdateRound) // 
     .where(qJpaUpdateRound._id.eq(roundId)) // 
     .fetchOne(); 
    transaction.commit(); 
    System.out.println("Updated "+ updatedRound); 

Diese Drucke:

Original-JpaUpdateRound {id = 3; sofort = 2017-11-06T19: 27: 01.141Z; Erfolg = falsch}
Aktualisiert JpaUpdateRound {id = 3; instant = 2017-11-06T19: 27: 01.141Z;

Erfolg = false}

Auch ein Identitätstest auf originalRound und updatedRound zeigt, dass beide Variablen dieselbe Instanz sind.

Ich habe in der Datenbank überprüft: der Wert ist wirklich aktualisiert. Und wenn ich kommentieren Sie die folgende Zeile

entityManager.clear(); // Workaround 

Das Programm druckt

Original-JpaUpdateRound {id = 3; sofort = 2017-11-06T19: 39: 01.038Z; Erfolg = falsch}
Aktualisiert JpaUpdateRound {id = 3; instant = 2017-11-06T19: 39: 01.038Z; Erfolg = wahr}

was ist das Ergebnis, das ich erwarte.

Es scheint, dass der Entitätscache nicht aktualisiert wird, wenn das Querydsl-Update durchgeführt wird. Daher gibt es nur das ursprüngliche Java-Objekt zurück.

Warum? Wie kann ich das JPA-Backend und Querydsl synchronisieren?

Antwort

0

Es scheint, dass es keinen anderen Weg gibt, als dem Entity Manager manuell mitzuteilen, dass er seine Daten aktualisieren soll. Ob mit entityManager.refresh(entity) für jede Entität, die von der Datenbank neu geladen werden muss; ob durch Löschen des gesamten Entity Manager-Caches durch Aufruf von entityManager.clear().

Siehe Force refresh of collection JPA entityManager