spring-data-jpa JPA的单个事务中的保存和更新操作未按预期工作

oyxsuwqo  于 2022-11-10  发布在  Spring
关注(0)|答案(1)|浏览(201)

把实体看作用户,它有一些字段。这里我使用jpa回调函数来更新用户信息的最后更新信息。在测试类中,我想写junit方法来评估这些回调方法是否工作/不仅仅是为了功能测试和代码覆盖的目的。但是如果我按照下面的方法,我每次都得到相同的时间,有人能帮助我吗?

@Entity
public class User {
     // user setter and getter methods

    @preUpdate
    public void preUpdateFunction() {
      this.lastUpdateDate = new Date();
   }

   @prePersist
   public void prePersistFunction() {
      // setting some user properties
      preUpdateFunction();
   }
}

//请忽略此配置和注解设置,我测试了我的类Spring配置,它工作得很好,Spring配置没有问题。

@SpringConfiguration
@JpaTransactional
public class TestClass {

     @Autowired
     UserDao userDao;  // userDao implements JPA Repository

    // I am worrying about this functionality only
    @Test
    public void saveUpdateTest() {
          User user = userDao.save(new User(constructor arguments));
          user = userDao.findOne(user.getId());

          user.setName("Hello");   // here updating user object with existing property
          User updatedUser = userDao.save(user);

         assertEquals(user.getLastUpdateDate().getTime(), updatedUser.getLastUpdateDate().getTime());   

// assertion is failing, everytime i am getting same Time for two values. even I added //Thread.sleep(1000) between save and update operations, still i am getting same values.

    }

}
jm81lzqq

jm81lzqq1#

简短回答

您需要调用saveAndFlush

User updatedUser = userDao.saveAndFlush(user);

长答案

根据JPA规范(JSR 338 JPA 2.1):
PrePersistTM和PreRemove回调方法是在为给定实体执行相应的EntityManager持久化和删除操作之前为该实体调用的。
PreUpdate和PostUpdate回调分别在对实体数据执行数据库更新操作之前和之后发生。这些数据库操作可能在更新实体状态时发生,也可能在将状态刷新到数据库时发生(可能在事务结束时)。
当执行entityManager持久化操作时调用@ PrePersists。棘手的是,执行通常会延迟到下一个刷新操作或事务提交(Hibernate默认配置)。通常,这取决于刷新配置和jpa实现。
这同样也适用于@PreUpdate。此外,JPA规范更具体地说,它可能在实体状态更新或刷新到DB时发生。

相关链接

https://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf
https://thorben-janssen.com/spring-data-jpa-save-saveandflush-and-saveall

相关问题