当前位置: 首页 > 知识库问答 >
问题:

如何使用QueryDSL更新JPA实体?

孙恩
2023-03-14

我正在尝试使用Querydsl(4.1.4)查询JPA,如本文http://www.Querydsl.com/static/Querydsl/latest/reference/html/ch02.html#jpa_integration所述。我使用Hibernate(5.2.12.final)作为JPA后端。我使用apt-maven-plugincom.Querydsl.apt.JPA.jpaAnnotationProcessor处理器从JPA注释类生成Querydsl查询类型。

    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);

这将打印:

原始JpaUpdateRound{id=3;instant=2017-11-06t19:27:01.141z;success=false}
更新的JpaUpdateRound{id=3;instant=2017-11-06t19:27:01.141z;success=false}

此外,对originalroundupdatedround进行的标识测试显示,这两个变量是同一个实例。

我在数据库中检查了一下:值真的更新了。如果我取消对下面一行的注释

    entityManager.clear(); // Workaround

程序打印

原始JpaUpdateRound{id=3;instant=2017-11-06t19:39:01.038z;success=false}
更新的JpaUpdateRound{id=3;instant=2017-11-06t19:39:01.038z;success=true}

在执行Querydsl更新时,实体缓存似乎没有得到更新。因此,它只返回原始Java对象。

为什么?如何同步JPA后端和Querydsl?

共有1个答案

梁修贤
2023-03-14

除了手动告诉实体管理器它应该刷新其数据之外,似乎没有其他方法。是否对需要从数据库中重新加载的每个实体使用EntityManager.Refresh(entity);是否通过调用EntityManager.clear()来清除整个实体管理器缓存。

请参见强制刷新集合JPA entityManager

 类似资料:
  • 问题内容: 这个问题几乎说明了一切。使用JPARepository如何更新实体? JPARepository只有一个 save 方法,它不会告诉我它是否实际上是在创建或更新。例如,我插入一个简单的对象数据库的用户,其中有三个领域:,和: 然后,我简单地调用,这实际上是数据库的插入: 到目前为止,一切都很好。现在,我想更新此用户,例如更改其年龄。为此,我可以使用QueryDSL或NamedQuery

  • 这个问题几乎说明了一切。使用JPARepository,我如何更新一个实体? JPARepository只有一个save方法,它并不告诉我它实际上是create还是update。例如,我向数据库用户插入一个简单的对象,它有三个字段:、和: 然后我只需调用,此时它实际上是对数据库的插入: 到目前为止还不错。现在我想更新这个用户,比如说改变他的年龄。为此,我可以使用查询,无论是QueryDSL还是Na

  • 问题内容: 有没有一种方法可以使字段在使用JPA-Hibernate 4进行更新操作时不持久,但在创建操作时持久化? 我以这种方式尝试过 但是使用@Transient注释时,该字段将在所有CRUD操作中都是瞬态的,我想要一种方法来指定仅在此操作上是持久性的(创建)。 有没有办法做到这一点? 谢谢! 问题答案: 如本文所述,您需要设置为: 该属性指示Hibernate从生成的SQL语句中忽略此列。

  • 主要内容:JPA实体更新示例JPA允许我们通过更新实体来更改数据库中的记录。 JPA实体更新示例 在这里,我们将演示如何根据主键更新学生的年龄。 完整的项目代码如下所示 - 这个例子包含以下步骤 - 第1步: 在包下创建一个名为的实体类,它包含属性:,和。 文件:StudentEntity.java 的代码如下 - 第2步: 将实体类和其他数据库配置映射到文件中。 文件:persistence.xml 的代码如下 - 在包下

  • 我正在尝试更新我的用户实体,我想到了一个错误:错误:NULL值违反了“id”列的Not NULL约束详细信息:失败的行包含(null,1,1) 这个问题肯定源于我在用户和配置文件之间的关系,即n-n