Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
spring数据jpa saveandflush方法_Spring_Hibernate_Spring Data Jpa - Fatal编程技术网

spring数据jpa saveandflush方法

spring数据jpa saveandflush方法,spring,hibernate,spring-data-jpa,Spring,Hibernate,Spring Data Jpa,我确实理解类JpaRepository Spring Data JPA的save方法和saveAndFlush方法之间的区别。根据我的理解,save方法将仅在事务结束时运行并提交sql,而saveAndFlush方法将通过运行sql语句(但不提交)将持久性上下文与数据库同步。下面是一个示例代码,我想在其中体验一下,请查看 这是更新的存储库类 @Repository public interface ClassRepository extends JpaRepository<ClassA,

我确实理解类JpaRepository Spring Data JPA的save方法和saveAndFlush方法之间的区别。根据我的理解,save方法将仅在事务结束时运行并提交sql,而saveAndFlush方法将通过运行sql语句(但不提交)将持久性上下文与数据库同步。下面是一个示例代码,我想在其中体验一下,请查看

这是更新的存储库类

@Repository
public interface ClassRepository extends JpaRepository<ClassA, Long> {

    @Modifying(clearAutomatically = true)
    @Query(value = "UPDATE class e SET e.class_name = ? WHERE e.employee_id = ?", nativeQuery = true)
    int updateClassNative(String className, String empId);

}
在上述测试用例中,测试通过。我不希望记录被保存,因为我正在使用save方法。在源代码中,save方法用@Transactional包装。是否因为save方法已经在提交insert语句


Ashley

测试场景的问题是JPA总是在执行本机查询之前刷新持久性上下文(这也是JPQL查询的默认行为,尽管它可以被覆盖)。其基本原理是,查询应报告反映当前工作单元中已做更改的状态

要查看
save/saveAndFlush
之间的差异,可以使用以下测试用例:

@Repository
public interface ClassRepository extends JpaRepository<ClassA, Long> {

    @Query("SELECT COUNT(c.id) FROM ClassA c")
    @QueryHints({
        @QueryHint(name = org.hibernate.annotations.QueryHints.FLUSH_MODE, value = "COMMIT")
    })
    int countClassAEntities();
}

@Test
@Transactional
void saveAndUpdate() {
    int initialCount = classRepository.countClassAEntities(); 
    ClassA classA = ClassA.builder().className("Test").employeeId("S0810").build();
    classRepository.save(classA);
    int finalCount = classRepository.countClassAEntities();
    assertEquals(initialCount, finalCount);
}

@Test
@Transactional
void saveAndUpdateWithFlush() {
    int initialCount = classRepository.countClassAEntities(); 
    ClassA classA = ClassA.builder().className("Test").employeeId("S0810").build();
    classRepository.saveAndFlush(classA);
    int finalCount = classRepository.countClassAEntities();
    assertEquals(initialCount + 1, finalCount);
}
@存储库
公共接口类存储库扩展了JpaRepository{
@查询(“从ClassA c中选择计数(c.id))
@牢骚({
@QueryHint(name=org.hibernate.annotations.QueryHints.FLUSH_MODE,value=“COMMIT”)
})
int countclassaenties();
}
@试验
@交易的
void saveAndUpdate(){
int initialCount=classRepository.countClassAEntities();
ClassA ClassA=ClassA.builder().className(“Test”).employeeId(“S0810”).build();
classRepository.save(classA);
int finalCount=classRepository.countClassAEntities();
资产质量(初始计数、最终计数);
}
@试验
@交易的
void saveAndUpdateWithFlush(){
int initialCount=classRepository.countClassAEntities();
ClassA ClassA=ClassA.builder().className(“Test”).employeeId(“S0810”).build();
classRepository.saveAndFlush(classA);
int finalCount=classRepository.countClassAEntities();
资产质量(初始计数+1,最终计数);
}

在上述设置中,计数查询的刷新模式设置为
COMMIT
,这意味着执行查询不会触发刷新。如果改用默认的
repository.count()
方法,第一个测试用例将失败,因为默认情况下,刷新模式设置为
AUTO

,测试场景的问题是JPA总是在执行本机查询之前刷新持久性上下文(这也是JPQL查询的默认行为,尽管它可以被覆盖)。其基本原理是,查询应报告反映当前工作单元中已做更改的状态

要查看
save/saveAndFlush
之间的差异,可以使用以下测试用例:

@Repository
public interface ClassRepository extends JpaRepository<ClassA, Long> {

    @Query("SELECT COUNT(c.id) FROM ClassA c")
    @QueryHints({
        @QueryHint(name = org.hibernate.annotations.QueryHints.FLUSH_MODE, value = "COMMIT")
    })
    int countClassAEntities();
}

@Test
@Transactional
void saveAndUpdate() {
    int initialCount = classRepository.countClassAEntities(); 
    ClassA classA = ClassA.builder().className("Test").employeeId("S0810").build();
    classRepository.save(classA);
    int finalCount = classRepository.countClassAEntities();
    assertEquals(initialCount, finalCount);
}

@Test
@Transactional
void saveAndUpdateWithFlush() {
    int initialCount = classRepository.countClassAEntities(); 
    ClassA classA = ClassA.builder().className("Test").employeeId("S0810").build();
    classRepository.saveAndFlush(classA);
    int finalCount = classRepository.countClassAEntities();
    assertEquals(initialCount + 1, finalCount);
}
@存储库
公共接口类存储库扩展了JpaRepository{
@查询(“从ClassA c中选择计数(c.id))
@牢骚({
@QueryHint(name=org.hibernate.annotations.QueryHints.FLUSH_MODE,value=“COMMIT”)
})
int countclassaenties();
}
@试验
@交易的
void saveAndUpdate(){
int initialCount=classRepository.countClassAEntities();
ClassA ClassA=ClassA.builder().className(“Test”).employeeId(“S0810”).build();
classRepository.save(classA);
int finalCount=classRepository.countClassAEntities();
资产质量(初始计数、最终计数);
}
@试验
@交易的
void saveAndUpdateWithFlush(){
int initialCount=classRepository.countClassAEntities();
ClassA ClassA=ClassA.builder().className(“Test”).employeeId(“S0810”).build();
classRepository.saveAndFlush(classA);
int finalCount=classRepository.countClassAEntities();
资产质量(初始计数+1,最终计数);
}


在上述设置中,计数查询的刷新模式设置为
COMMIT
,这意味着执行查询不会触发刷新method相反,第一个测试用例将失败,因为默认情况下,刷新模式设置为
AUTO

这是否回答了您的问题?save方法可能只保留在内存中?这是您的观点。@silentsudo请仔细阅读问题。@silentsudo对此我深表歉意,但我只编辑了问题的第一行。就几句话。我想我不明白。如何使用与
save/saveAll
方法相关的本机更新查询?您的代码不调用它们。这是否回答了您的问题?save方法可能只保留在内存中?这是您的观点。@silentsudo请仔细阅读问题。@silentsudo对此我表示歉意,但我只编辑了它我的问题的第一行。就几句话。我想我没有听懂。如何使用与
save/saveAll
方法相关的本机更新查询?您的代码不调用它们。是否需要
@Transactional
saveAndFlush
?@MahmoudOdeh?好吧,我添加它是为了说明目的,两个测试都有相同的I初始条件。如果测试不是事务性的,每个存储库方法调用都会创建自己的事务,因此
save
saveAndFlush
@QueryHint(name=org.hibernate.annotations.QueryHints.FLUSH_模式,value=“COMMIT”)之间没有区别这一行给出了编译错误。不适用于方法。哦,对不起,我的不好,请参阅更新的答案。我尝试了你说的不起作用的方法。你的想法非常有用。对我有效的方法是将spring.jpa.properties.org.hibernate.flushMode设置为在application.properties文件中提交。非常感谢你的帮助。是否需要
@TRansional
saveAndFlush
?@MahmoudOdeh我添加它是为了说明目的,以便两个测试具有相同的初始条件