简体   繁体   English

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

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

I can't save result of select into database using JPA in Spring Boot application. 我无法在Spring Boot应用程序中使用JPA将选择结果保存到数据库中。 The code that I use is below: 我使用的代码如下:

@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();
}

When I call fetchAndSave with a property spring.jpa.show-sql=true I see in logs only select: 当我使用属性spring.jpa.show-sql=true调用fetchAndSave ,仅在日志中看到选择:

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

In a case I don't use @Transactional I can see more requests to database in logs and values are saved: 在不使用@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 (?, ?)

I have a pretty simple table in database, DDL looks like: 我在数据库中有一个非常简单的表,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)
);

Can you help me to identify the reason of such behavior? 您能帮我找出这种行为的原因吗? I expect records to be saved into database when I use @Transactional . 我希望在使用@Transactional时将记录保存到数据库中。

The short answer for "why it does not save" is: because they are already saved. “为什么不保存”的简短答案是:因为它们已经保存。

The longer answer is Hibernate sees that these IDs has already present in DB, and it does not save them. 更长的答案是Hibernate认为这些ID已存在于DB中,并且不保存它们。

If you want to inset another three entities to DB, just create duplicates for these objects, with id=null and save them: 如果要向数据库插入另外三个实体,只需为这些对象创建副本,并使用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