如何使用 Querydsl 更新 JPA 实体?
How to update a JPA entity using Querydsl?
我正在尝试使用此处所写的 Querydsl (4.1.4) 查询 JPA
http://www.querydsl.com/static/querydsl/latest/reference/html/ch02.html#jpa_integration。我使用 Hibernate (5.2.12.Final) 作为 JPA 后端。我使用带有 com.querydsl.apt.jpa.JPAAnnotationProcessor
处理器的 apt-maven-plugin
从注释为 类 的 JPA 生成 Querydsl 查询类型。
我在更新实体时遇到问题:Java 代码中没有显示更新的值。这是更新实体中的布尔值 属性(名为 success
)的相关代码片段:
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);
这会打印:
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}
此外,对 originalRound
和 updatedRound
的身份测试表明这两个变量是同一个实例。
我检查了数据库:值真的更新了。如果我取消注释以下行
entityManager.clear(); // Workaround
程序打印
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}
这是我期望的结果。
执行 Querydsl 更新时,实体缓存似乎没有更新。因此,它只是 returns 原始 Java 对象。
为什么?如何同步 JPA 后端和 Querydsl?
看来除了手动告诉实体管理器它应该刷新其数据之外别无他法。是否在需要从数据库重新加载的每个实体上使用 entityManager.refresh(entity)
;是否通过调用 entityManager.clear()
.
清除整个实体管理器缓存
见Force refresh of collection JPA entityManager
我正在尝试使用此处所写的 Querydsl (4.1.4) 查询 JPA
http://www.querydsl.com/static/querydsl/latest/reference/html/ch02.html#jpa_integration。我使用 Hibernate (5.2.12.Final) 作为 JPA 后端。我使用带有 com.querydsl.apt.jpa.JPAAnnotationProcessor
处理器的 apt-maven-plugin
从注释为 类 的 JPA 生成 Querydsl 查询类型。
我在更新实体时遇到问题:Java 代码中没有显示更新的值。这是更新实体中的布尔值 属性(名为 success
)的相关代码片段:
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);
这会打印:
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}
此外,对 originalRound
和 updatedRound
的身份测试表明这两个变量是同一个实例。
我检查了数据库:值真的更新了。如果我取消注释以下行
entityManager.clear(); // Workaround
程序打印
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}
这是我期望的结果。
执行 Querydsl 更新时,实体缓存似乎没有更新。因此,它只是 returns 原始 Java 对象。
为什么?如何同步 JPA 后端和 Querydsl?
看来除了手动告诉实体管理器它应该刷新其数据之外别无他法。是否在需要从数据库重新加载的每个实体上使用 entityManager.refresh(entity)
;是否通过调用 entityManager.clear()
.
见Force refresh of collection JPA entityManager