Spring Data ReactiveCrudRepository save operation not persisting data in Postgres Database
Asked Answered
K

5

5

For the below code, Get and update operation in the repository work fine. But save operation is not persisting the data into the tables. It works fine if I implement the Repository myself. After the replaced it with the interface extending ReactiveCrudRepository, this problem started. Am I missing something?

@SpringBootApplication
public class ReactiveSqlApplication {
public static void main(String[] args) {
    SpringApplication.run(ReactiveSqlApplication.class, args);
}

}

@Data
@AllArgsConstructor
@NoArgsConstructor
@Table("store")
class Store {

@Id
private String id;

private String name;

private String description;

}

interface StoreRepository extends ReactiveCrudRepository<Store, String> {
}

@Configuration
@EnableR2dbcRepositories
class R2dbcConfiguration extends AbstractR2dbcConfiguration {

private final ConnectionFactory connectionFactory;



   R2dbcConfiguration(ConnectionFactory connectionFactory) {
        this.connectionFactory = connectionFactory;
    }

    @Override
    public ConnectionFactory connectionFactory() {
        return this.connectionFactory;
    }
}


@Configuration
class ConnectionFactoryConfiguration {

@Bean
ConnectionFactory connectionFactory() {
    PostgresqlConnectionConfiguration config = PostgresqlConnectionConfiguration.builder()
            .host("localhost")
            .port(5433)
            .database("testdb")
            .username("postgres")
            .password("root")
            .build();
    return new PostgresqlConnectionFactory(config);
}

}

The code is tested as below:

@SpringBootTest
@RunWith(SpringRunner.class)

public class StoreRepositoryTest {
@Autowired
private StoreRepository repository;

@Test
public void all() {

    Flux<Store> storeFlux = Flux.just(new Store("1", "a1", "a1"), new Store("2", "a2", "a2"))
            .flatMap(store -> repository.save(store));

    StepVerifier
            .create(storeFlux)
            .expectNextCount(2)
            .verifyComplete();

    Flux<Store> all = repository.findAll();

    StepVerifier
            .create(all)
            .expectNextCount(2)
            .verifyComplete();

}

}
Koosis answered 29/1, 2019 at 8:12 Comment(5)
Hi, can you post the code where you call the save() methodPumping
I have updated the Test class.Koosis
@Pumping Thanks for checking out. Any idea on this behaviour?Koosis
Posted answer, please confirm if this also is the case when using String as id typePumping
@taneesh shanand if my answer is the solution to your problem, please mark it as the accepted answer :)Pumping
P
3

The save() method does not save the given entity if you set the id yourself. Try setting the id value to null. (This at least works when using Long as type for the id.)

Pumping answered 8/2, 2019 at 9:18 Comment(0)
B
2

I found some solution on github issues: https://github.com/spring-projects/spring-data-r2dbc/issues/218 It seems that you might want to implement Persistable for your model objects, because you should tell the framework somehow that your classes are new and should be stored. Here is an example code form the link above:

@Data
@Table("sessions")
@NoArgsConstructor
public class Session implements Persistable<UUID> {

    @Id
    private UUID id;
    private String name, speakers;

    @Override
    public boolean isNew() {
        boolean result = Objects.isNull(id);
        this.id = result ? UUID.randomUUID() : this.id;
        return result;
    }
}

If you already received an id you can use some @Transient field in your entities and set it in the code to indicate that the objects are new by returning that field from isNew() method.

Bowrah answered 19/3, 2021 at 23:22 Comment(0)
U
1

I faced this the same problem recently. It is because its making update instead of insert. You need to handle it by yourself. See related question: Why does Spring-data-jdbc not save my Car object?

Udall answered 28/2, 2019 at 10:8 Comment(1)
Welcome to Stack Overflow. Links to external resources are encouraged, but please add context around the link so your fellow users will have some idea what it is and why it’s there. Always quote the most relevant part of an important link, in case the target site is unreachable or goes permanently offline. How to Answer. Thanks.Aquatint
T
0

set the r2dbc connection pooling in your application to false spring.r2dbc.pool.enabled=false This by default is always true and mainly it is not stable because its in early stage thus yields intermittent results

Tiebold answered 8/6, 2022 at 15:41 Comment(0)
L
0

You don't need custom implementation for reactive save / delete. Just ensure that you return that Mono after save or delete, that would do the trick.

Lucilius answered 12/5 at 20:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.