Spring Mongo Populator 一一
Posted
技术标签:
【中文标题】Spring Mongo Populator 一一【英文标题】:Spring Mongo Populator one by one 【发布时间】:2020-06-27 21:51:25 【问题描述】:我在 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
任何关于如何做类似事情的想法都会有所帮助...... 提前致谢。
【问题讨论】:
因此,如果许多资源中的某些资源包含格式错误的 JSON 数据,您想记录错误并跳过“坏”资源吗?你想用Jackson2RepositoryPopulatorFactoryBean
或类似的东西来做吗?
差不多......不仅是格式错误的 JSON 数据,如果它们是有效的 JSON,但不适合实体 _class。
@ShaharWider 您能提供您的反馈吗?
【参考方案1】:
没有内置支持您的请求,但您可以通过调整几个类轻松提供。
添加自定义 Jackson 2 阅读器
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 填充器
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
【讨论】:
【参考方案2】:使用 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
【讨论】:
以上是关于Spring Mongo Populator 一一的主要内容,如果未能解决你的问题,请参考以下文章
从产品展示页面谈谈Hybris系列之二: DTO, Converter和Populator
使用 spring data mongo 插入 Mongo 文档
将 mongo 查询转换为 spring-data-mongo 查询