Spring Mongo人口一一
Spring Mongo Populator one by one
我在 Kotlin 上使用 MongoDB 和 Spring,我希望我的应用程序在启动时填充 MongoDB 集合。 (并在每次启动时清理它)
我的问题是,如果我正在填充的某些数据有问题,我如何才能一个一个地填充数据以实现容错?
我的代码:
@Configuration
class IndicatorPopulator {
@Value("classpath:indicatorData.json")
private lateinit var data: Resource
@Autowired
private lateinit var indicatorRepository: IndicatorRepository
@Bean
@Autowired
fun repositoryPopulator(objectMapper: ObjectMapper): Jackson2RepositoryPopulatorFactoryBean {
val factory = Jackson2RepositoryPopulatorFactoryBean()
indicatorRepository.deleteAll()
factory.setMapper(objectMapper)
factory.setResources(arrayOf(data))
return factory
}
我要找的是这样的:
@Bean
@Autowired
fun repositoryPopulator(objectMapper: ObjectMapper): Jackson2RepositoryPopulatorFactoryBean {
val factory = Jackson2RepositoryPopulatorFactoryBean()
indicatorRepository.deleteAll()
factory.setMapper(objectMapper)
val arrayOfResources: Array<Resource> = arrayOf(data)
for (resource in arrayOfResources){
try{
factory.setResources(resource)
} catch(e: Exception){
logger.log(e.message)
}
}
return factory
}
任何关于如何做类似事情的想法都会有所帮助...
提前致谢。
您的请求没有内置支持,但您可以通过微调 类 轻松提供。
添加自定义杰克逊 2 Reader
public class CustomJackson2ResourceReader implements ResourceReader {
private static final Logger logger = LoggerFactory.getLogger(CustomJackson2ResourceReader.class);
private final Jackson2ResourceReader resourceReader = new Jackson2ResourceReader();
@Override
public Object readFrom(Resource resource, ClassLoader classLoader) throws Exception {
Object result;
try {
result = resourceReader.readFrom(resource, classLoader);
} catch(Exception e) {
logger.warn("Can't read from resource", e);
return Collections.EMPTY_LIST;
}
return result;
}
}
添加自定义 Jackson 2 Populator
public class CustomJackson2RepositoryPopulatorFactoryBean extends Jackson2RepositoryPopulatorFactoryBean {
@Override
protected ResourceReader getResourceReader() {
return new CustomJackson2ResourceReader();
}
}
配置
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public AbstractRepositoryPopulatorFactoryBean repositoryPopulator(ObjectMapper objectMapper, KeyValueRepository keyValueRepository) {
Jackson2RepositoryPopulatorFactoryBean factory = new CustomJackson2RepositoryPopulatorFactoryBean();
keyValueRepository.deleteAll();
factory.setMapper(objectMapper);
factory.setResources(new Resource[]{new ClassPathResource("badclassname.json"), new ClassPathResource("good.json"), new ClassPathResource("malformatted.json")});
return factory;
}
}
我上传了一个工作示例here
使用 Sagar 的 Reader & Factory 我只是调整它以满足我的需要(Kotlin,并从同一个 JSON 文件中读取资源)得到了这个答案:
@Configuration
class IndicatorPopulator {
@Value("classpath:indicatorData.json")
private lateinit var data: Resource
@Autowired
private lateinit var indicatorRepository: IndicatorRepository
@Autowired
@Bean
fun repositoryPopulator(objectMapper: ObjectMapper): Jackson2RepositoryPopulatorFactoryBean {
val factory: Jackson2RepositoryPopulatorFactoryBean = CustomJackson2RepositoryPopulatorFactoryBean()
factory.setMapper(objectMapper)
// inject your Jackson Object Mapper if you need to customize it:
indicatorRepository.deleteAll()
val resources = mutableListOf<Resource>()
val readTree: ArrayNode = objectMapper.readTree(data.inputStream) as ArrayNode
for (node in readTree){
resources.add( InputStreamResource(node.toString().byteInputStream()))
}
factory.setResources(resources.toTypedArray())
return factory
}
}
我在 Kotlin 上使用 MongoDB 和 Spring,我希望我的应用程序在启动时填充 MongoDB 集合。 (并在每次启动时清理它)
我的问题是,如果我正在填充的某些数据有问题,我如何才能一个一个地填充数据以实现容错?
我的代码:
@Configuration
class IndicatorPopulator {
@Value("classpath:indicatorData.json")
private lateinit var data: Resource
@Autowired
private lateinit var indicatorRepository: IndicatorRepository
@Bean
@Autowired
fun repositoryPopulator(objectMapper: ObjectMapper): Jackson2RepositoryPopulatorFactoryBean {
val factory = Jackson2RepositoryPopulatorFactoryBean()
indicatorRepository.deleteAll()
factory.setMapper(objectMapper)
factory.setResources(arrayOf(data))
return factory
}
我要找的是这样的:
@Bean
@Autowired
fun repositoryPopulator(objectMapper: ObjectMapper): Jackson2RepositoryPopulatorFactoryBean {
val factory = Jackson2RepositoryPopulatorFactoryBean()
indicatorRepository.deleteAll()
factory.setMapper(objectMapper)
val arrayOfResources: Array<Resource> = arrayOf(data)
for (resource in arrayOfResources){
try{
factory.setResources(resource)
} catch(e: Exception){
logger.log(e.message)
}
}
return factory
}
任何关于如何做类似事情的想法都会有所帮助... 提前致谢。
您的请求没有内置支持,但您可以通过微调 类 轻松提供。
添加自定义杰克逊 2 Reader
public class CustomJackson2ResourceReader implements ResourceReader {
private static final Logger logger = LoggerFactory.getLogger(CustomJackson2ResourceReader.class);
private final Jackson2ResourceReader resourceReader = new Jackson2ResourceReader();
@Override
public Object readFrom(Resource resource, ClassLoader classLoader) throws Exception {
Object result;
try {
result = resourceReader.readFrom(resource, classLoader);
} catch(Exception e) {
logger.warn("Can't read from resource", e);
return Collections.EMPTY_LIST;
}
return result;
}
}
添加自定义 Jackson 2 Populator
public class CustomJackson2RepositoryPopulatorFactoryBean extends Jackson2RepositoryPopulatorFactoryBean {
@Override
protected ResourceReader getResourceReader() {
return new CustomJackson2ResourceReader();
}
}
配置
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public AbstractRepositoryPopulatorFactoryBean repositoryPopulator(ObjectMapper objectMapper, KeyValueRepository keyValueRepository) {
Jackson2RepositoryPopulatorFactoryBean factory = new CustomJackson2RepositoryPopulatorFactoryBean();
keyValueRepository.deleteAll();
factory.setMapper(objectMapper);
factory.setResources(new Resource[]{new ClassPathResource("badclassname.json"), new ClassPathResource("good.json"), new ClassPathResource("malformatted.json")});
return factory;
}
}
我上传了一个工作示例here
使用 Sagar 的 Reader & Factory 我只是调整它以满足我的需要(Kotlin,并从同一个 JSON 文件中读取资源)得到了这个答案:
@Configuration
class IndicatorPopulator {
@Value("classpath:indicatorData.json")
private lateinit var data: Resource
@Autowired
private lateinit var indicatorRepository: IndicatorRepository
@Autowired
@Bean
fun repositoryPopulator(objectMapper: ObjectMapper): Jackson2RepositoryPopulatorFactoryBean {
val factory: Jackson2RepositoryPopulatorFactoryBean = CustomJackson2RepositoryPopulatorFactoryBean()
factory.setMapper(objectMapper)
// inject your Jackson Object Mapper if you need to customize it:
indicatorRepository.deleteAll()
val resources = mutableListOf<Resource>()
val readTree: ArrayNode = objectMapper.readTree(data.inputStream) as ArrayNode
for (node in readTree){
resources.add( InputStreamResource(node.toString().byteInputStream()))
}
factory.setResources(resources.toTypedArray())
return factory
}
}