JPA创建架构后如何使组件初始化?

时间:2019-03-12 22:32:14

标签: java hibernate spring-boot jpa spring-data

上下文

  

服务器在spring-boot上运行并利用spring-data。数据库   正在使用的是postgresql。

问题

  

从information_schema,pg_user,   pg_policies和pg_catalog。 这些组件的PostConstruct是   当前正在运行jpa模式创建之前。   组件正在尝试获取的信息尚未得到   由jpa创建,因此组件崩溃。

先验研究

  

休眠本身不会引发任何错误。运行服务器   两次使有问题的组件正常运行。这意味着   这些组件在jpa之前运行。

     

我的属性文件包括spring.jpa.hibernate.ddl-auto =更新。一世   试图找到spring.jpa.hibernate.ddl-auto背后的代码,以了解如何   我可以通过@DependsOn来获取组件的要求,但是我   尚未找到任何东西。

     

我不能简单地等待带有事件监听器的ApplicationReadyEvent   因为那样会破坏这些组件之间的依赖性。

代码

这些是我的hikari数据源

@RequiredArgsConstructor
@Configuration
@EnableConfigurationProperties
public class DatabaseConfiguration {
    @Bean(name = "server")
    @ConfigurationProperties(prefix = "server.datasource")
    public HikariDataSource server() {
        return (HikariDataSource) DataSourceBuilder.create().build();
    }

    @Bean(name = "client")
    @ConfigurationProperties(prefix = "client.datasource")
    public HikariDataSource client() {
        return (HikariDataSource) DataSourceBuilder.create().build();
    }
}

我有一个自定义的DataSource组件。

@Component
public class DatabaseRouterBean {
    private final AwsCognitoConfiguration cognitoConfiguration;
    private final DatabaseService databaseService;
    private final HikariDataSource server;
    private final HikariDataSource client;
    private final ModelSourceInformation modelSourceInformation;

    public DatabaseRouterBean(
        @Qualifier("server") final HikariDataSource server,
        @Qualifier("client") final HikariDataSource client,
        final AwsCognitoConfiguration cognitoConfiguration,
        final DatabaseService databaseService,
        final ModelSourceInformation modelSourceInformation
    ) {
        this.server = server;
        this.client = client;
        this.cognitoConfiguration = cognitoConfiguration;
        this.databaseService = databaseService;
        this.modelSourceInformation = modelSourceInformation;
    }

    @Bean
    @Primary
    public DatabaseRouter dataSource() {
        return new DatabaseRouter(cognitoConfiguration, databaseService, server, client, modelSourceInformation);
    }
}

以下是数据源的实现。

// could have a better name
@RequiredArgsConstructor
@Log4j2
public class DatabaseRouter implements DataSource {
    private final AwsCognitoConfiguration config;
    private final DatabaseService databaseService;
    private final HikariDataSource superuser;
    private final HikariDataSource user;
    private final ModelSourceInformation modelSourceInformation;

自定义数据源组件用于使用多租户目的,使用数据库上的两个帐户之一为实体管理器创建连接。一个帐户是超级用户,而另一个帐户是受限用户帐户。多租户是通过使用策略来实现的。定制数据源在连接上运行SET_CONFIG。

DatabaseService是一个非常低级的服务类,它支持读取information_schema,pg_user,pg_policies和pg_catalog。

@Service
@Log4j
public class DatabaseServiceImpl implements DatabaseService {
    private final HikariDataSource server;
    private final HikariDataSource client;

ModelSourceInformation没有依赖性。它用于将类类型转换为配置变量名称,反之亦然。定制数据源使用它根据用户类型填充SET_CONFIG。它支持定义配置变量,并通过注释将它们绑定到模型。

AwsCognitoConfiguration只是一个Configuration类,它从属性文件中读取认知设置。

按依赖性定义执行顺序

  1. 数据库配置,ModelSourceInformation,AwsCognitoConfiguration
  2. DatabaseService
  3. DatabaseRouter
  4. JPA
  5. 休息的豆子

以下组件在jpa之前初始化。它们需要在jpa之后初始化。它们之间有依赖性。

  1. ModelDynamismInformation
  2. ModelEntityInformation
  3. ModelInformation
  4. ModelPrimaryKeyInformation
  5. ModelSchemaInformation
  6. ModelSecurityInformation
  7. PolicyInitializer

1 个答案:

答案 0 :(得分:1)

您可以使用@DependsOn来控制Bean初始化的顺序。 Hibernate创建架构后,应初始化依赖EntityManagerFactory的bean。