【问题标题】:Spring R2DBC proper way to initialize database with postgresSpring R2DBC 使用 postgres 初始化数据库的正确方法
【发布时间】:2021-01-08 02:20:51
【问题描述】:

我有以下代码:

@Component
public class TemplateDatabaseLoader {
    private Logger LOGGER = LoggerFactory.getLogger(TemplateDatabaseLoader.class);

    @Bean
    public CommandLineRunner demo(DatabaseClient databaseClient, ItemRepository itemRepository) {
        return args -> {
            databaseClient.execute(
                    "CREATE TABLE item (" +
                            "id SERIAL PRIMARY KEY," +
                            "name VARCHAR(255)," +
                            "price REAL" +
                        ");"
            ).fetch().all().blockLast(Duration.ofSeconds(10));
            itemRepository.save(new Item("Alf alarm clock", 19.99)).block();
            LOGGER.debug("COMMAND LINE RUNNER");
            itemRepository.save(new Item("Smurf TV tray", 24.99)).block();
        };
    }
}

还有:

@SpringBootApplication
public class DemoApplication extends AbstractR2dbcConfiguration {

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

    @Bean
    public ConnectionFactory connectionFactory() {
        PostgresqlConnectionFactory connectionFactory = new PostgresqlConnectionFactory(PostgresqlConnectionConfiguration.builder()
                .host("127.0.0.1")
                .database("cart")
                .username("cart")
                .password("cart").build());
        return connectionFactory;
    }

    @Bean(name={"r2dbcDatabaseClient"})
    DatabaseClient databaseClient() {
        return DatabaseClient.create(connectionFactory());
    }
}

我收到以下错误:

Suppressed: java.lang.Exception: #block terminated with an error
Caused by: io.r2dbc.postgresql.ExceptionFactory$PostgresqlBadGrammarException: relation "item" already exists

以及前面的错误:

Caused by: java.lang.ClassNotFoundException: org.springframework.jdbc.CannotGetJdbcConnectionException

如果我修改我的代码说:

CREATE TABLE IF NOT EXISTS item

然后我不再收到有关项目关系存在的错误,但是,似乎交易被完全取消了?

我得到以下输出:

2020-09-21 17:31:58.476 DEBUG 16639 --- [  restartedMain] com.example.demo.TemplateDatabaseLoader  : COMMAND LINE RUNNER
2020-09-21 17:31:58.476 DEBUG 16639 --- [actor-tcp-nio-2] i.r.postgresql.util.FluxDiscardOnCancel  : received cancel signal

所以我的问题是

  1. 这样做的正确方法是什么?

  2. 为什么我的 CommandLineRunner 代码似乎执行了两次?该表在运行代码后不会持续存在,因此似乎必须执行两次才能获得有关该表存在的第一个错误。

谢谢。

【问题讨论】:

    标签: spring spring-data-r2dbc r2dbc r2dbc-postgresql


    【解决方案1】:

    我让它工作了。我添加了一个新类来从文件加载架构:

    @Configuration
    public class InitializerConfiguration {
        private Logger LOGGER = LoggerFactory.getLogger(InitializerConfiguration.class);
    
        @Bean
        public ConnectionFactoryInitializer initializer(ConnectionFactory connectionFactory) {
    
            ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
            initializer.setConnectionFactory(connectionFactory);
    
            CompositeDatabasePopulator populator = new CompositeDatabasePopulator();
            populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("schema.sql")));
            initializer.setDatabasePopulator(populator);
    
            return initializer;
        }
    }
    

    这会加载资源下的 schema.sql。我的 TemplateDatabaseLoader 现在看起来像这样:

    @Component
    public class TemplateDatabaseLoader {
        private Logger LOGGER = LoggerFactory.getLogger(TemplateDatabaseLoader.class);
    
        @Bean
        public CommandLineRunner demo(ItemRepository itemRepository) {
            return args -> {
                itemRepository.save(new Item("Alf alarm clock", 19.99)).block();
                itemRepository.save(new Item("Smurf TV tray", 24.99)).block();
            };
        }
    }
    

    这会加载这两个项目。

    【讨论】:

      猜你喜欢
      • 2021-12-04
      • 1970-01-01
      • 2023-03-12
      • 2021-03-28
      • 2015-03-16
      • 1970-01-01
      • 1970-01-01
      • 2019-10-24
      • 2019-10-03
      相关资源
      最近更新 更多