简体   繁体   中英

Autopopulate Database with Spring Boot

I have a Spring Boot application that uses a large number pre-populated tables. The content of these tables can change between instances. I currently load the tables from JSON files using the following code:

@Configuration
public class PreLoader {
    
    @Bean
    @Conditional(PreloadCondition.class)
    Jackson2RepositoryPopulatorFactoryBean getRespositoryPopulatorNameType() {
        Jackson2RepositoryPopulatorFactoryBean factory = new Jackson2RepositoryPopulatorFactoryBean();
        
        final Logger log = LoggerFactory.getLogger(Jackson2RepositoryPopulatorFactoryBean.class);
        
        Resource[] resources = null;
        
        try {
            resources = new PathMatchingResourcePatternResolver().getResources("classpath*:*-data.json");
            
            log.debug("Found {} resources for preloading:", resources.length);
            for (Resource resource : resources) {
                log.debug(resource.toString());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        factory.setResources(resources);
        return factory;
    }
}

How can I modify this code to run only on initialization of the database? I have tried using @Conditional as follows:

@Configurable
public class PreloadCondition implements Condition {
    
    @PersistenceContext
    private EntityManager entityManager;
    
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return tableExistsService.exists("identity_use");
    }
    
    static boolean tableExistsSQL(Connection connection, String tableName) throws SQLException {
        PreparedStatement preparedStatement = connection.prepareStatement("SELECT count(*) "
          + "FROM information_schema.tables "
          + "WHERE table_name = ?"
          + "LIMIT 1;");
        preparedStatement.setString(1, tableName);

        ResultSet resultSet = preparedStatement.executeQuery();
        resultSet.next();
        return resultSet.getInt(1) != 0;
    }
}

However, the entityManager is null - possibly because the class is not "Spring managed"? @Configurable does not seem to help?

For reference, in case others stumble across this question. I decided to use a different Conditional to solve this issue. The code block follows. Note 1) the "conditional" data was read from application.properties and 2) multiple resource files can be loaded. Hope this helps someone!

@Configuration
@ConditionalOnProperty(
        prefix = "myappname", 
        name = "initialize", 
        havingValue = "true", 
        matchIfMissing = false)
public class PreLoader {
@Bean
Jackson2RepositoryPopulatorFactoryBean getRespositoryPopulatorNameType() {
    Jackson2RepositoryPopulatorFactoryBean factory = new Jackson2RepositoryPopulatorFactoryBean();

    final Logger log = LoggerFactory.getLogger(Jackson2RepositoryPopulatorFactoryBean.class);

    Resource[] resources = null;

    try {
        resources = new PathMatchingResourcePatternResolver().getResources("classpath*:*-data.json");

        log.debug("Found {} resources for preloading:", resources.length);
        for (Resource resource : resources) {
            log.debug(resource.toString());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    factory.setResources(resources);
    return factory;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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