繁体   English   中英

JPA不会使用@Transactional批注保存选择结果

[英]JPA doesn't save result of select with @Transactional annotation

我无法在Spring Boot应用程序中使用JPA将选择结果保存到数据库中。 我使用的代码如下:

@Override
@Transactional
public void fetchAndSave() {
    List<TestData> all = testDataRepository.findAllRecords();
    testDataRepository.saveAll(all);
    // let suppose I will save another data here that's why I need @Transactional for roll-back in case of exception
}
@Repository
public interface TestDataRepository extends JpaRepository<TestData, Long> {
    @Query(value = "select raw_values.identificator AS id, raw_values.name as value from test.raw_values", nativeQuery = true)
    List<TestData> findAllRecords();
}

当我使用属性spring.jpa.show-sql=true调用fetchAndSave ,仅在日志中看到选择:

Hibernate: select raw_values.identificator AS id, raw_values.name as value from test.raw_values

在不使用@Transactional的情况下,我可以在日志中看到对数据库的更多请求并保存了值:

Hibernate: select raw_values.identificator AS id, raw_values.name as value from test.raw_values
Hibernate: select testdata0_.id as id1_0_0_, testdata0_.value as value2_0_0_ from test.test_data testdata0_ where testdata0_.id=?
Hibernate: select testdata0_.id as id1_0_0_, testdata0_.value as value2_0_0_ from test.test_data testdata0_ where testdata0_.id=?
Hibernate: select testdata0_.id as id1_0_0_, testdata0_.value as value2_0_0_ from test.test_data testdata0_ where testdata0_.id=?
Hibernate: insert into test.test_data (value, id) values (?, ?)
Hibernate: insert into test.test_data (value, id) values (?, ?)
Hibernate: insert into test.test_data (value, id) values (?, ?)

我在数据库中有一个非常简单的表,DDL看起来像:

create table test_data
(
    id    serial not null
        constraint test_data_pk
            primary key,
    value varchar(256)
);
-- There are 3 records in table raw_values
create table table_name
(
    identificator integer not null
        constraint table_name_pk
            primary key,
    name          varchar(256)
);

您能帮我找出这种行为的原因吗? 我希望在使用@Transactional时将记录保存到数据库中。

“为什么不保存”的简短答案是:因为它们已经保存。

更长的答案是Hibernate认为这些ID已存在于DB中,并且不保存它们。

如果要向数据库插入另外三个实体,只需为这些对象创建副本,并使用id=null并将其保存:

List<TestData> all = testDataRepository.findAllRecords();
List<TestData> copies = all.stream()
   .map(testData -> new TestData(...)) //copy all the fields EXCEPT ID
   .collect(toList());
testDataRepository.saveAll(copies);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM