I am trying to query JPA with Querydsl (4.1.4) as written here
http://www.querydsl.com/static/querydsl/latest/reference/html/ch02.html#jpa_integration . I use Hibernate (5.2.12.Final) as the JPA backend. I generate Querydsl query types from the JPA annotated classes using the apt-maven-plugin
with the com.querydsl.apt.jpa.JPAAnnotationProcessor
processor.
I have an issue while updating an entity : the updated value does not show up in the Java code. Here is the relevant code snippet that updates a boolean property (named success
) in the 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);
This prints :
Original JpaUpdateRound{id=3; instant=2017-11-06T19:27:01.141Z; success=false}
Updated JpaUpdateRound{id=3; instant=2017-11-06T19:27:01.141Z; success=false}
Also, an identity test on originalRound
and updatedRound
shows that both variables are the same instance.
I checked in the database : the value is really updated. And if I uncomment the following line
entityManager.clear(); // Workaround
The program prints
Original JpaUpdateRound{id=3; instant=2017-11-06T19:39:01.038Z; success=false}
Updated JpaUpdateRound{id=3; instant=2017-11-06T19:39:01.038Z; success=true}
which is the result I expect.
It seems that the entity cache does not get updated when the Querydsl update is performed. Thus, it only returns the original Java object.
Why ? How can I synchronize the JPA backend and Querydsl ?
It appears there is no other way than manually tell the entity manager that it should refresh its data. Whether using entityManager.refresh(entity)
on each entity that needs to be reloaded from the database; whether by clearing the whole entity manager cache by calling entityManager.clear()
.
See Force refresh of collection JPA entityManager
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With