JPA+Mongodb的Example查询不出数据的问题

现象

一次查询中发现一个诡异的问题,用jpa写入到mongodb的数据无法查询出来。

原因分析

查询采用了SpringCloudData的JPA+Mongodb的Example动态拼接查询条件,具体代码如下:

1
2
3
4
5
6
7
8
  public PageDTO<EmployeeInfoDTO> findByCondition(String name, String number, Integer pageNumber, Integer pageSize) {
EmployeeInfoDO query=new EmployeeInfoDO();
//......动态设置query权限
Pageable pageable = PageRequest.of(pageNumber, pageSize, Sort.Direction.DESC, "gmtCreate");
Page<EmployeeInfoDO> ret = employeeInfoRepo.findAll(Example.of(query, ExampleMatcher.matchingAll()), pageable);
//......
return pageDTO;
}

但是这里有个坑,即:jpa的mongodb为了方便将document还原成java对象,会在写入的时候设置一个字段”_class”,而Example在查询时候回将EmployeeInfoDO 的classname作为查询条件,而我们写入DB的时候在注入MappingMongoConverter已经忽略调了_class字段,所以当然就查不到数据了。

MappingMongoConverter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Bean
public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context, BeanFactory beanFactory) {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);

MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
try {
mappingConverter.setCustomConversions(beanFactory.getBean(CustomConversions.class));
} catch (NoSuchBeanDefinitionException ignore) {
}

// Don't save _class to mongo
mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));

return mappingConverter;
}

解决方案

设置有效的ExampleMatcher忽略”_class”

1
public static final ExampleMatcher EXAMPLE_MATCHER_IGNORE_CLASS = ExampleMatcher.matchingAll().withIgnorePaths("_class");