Spring Data Mongo-继承和可嵌入

时间:2019-07-31 00:26:25

标签: java mongodb spring-boot spring-data spring-data-mongodb

假设我有一个Customer实体,其中包含Vehicles列表:

@Document
public class Customer {
  private List<Vehicle> vehicles;

  //... getters, setters
} 

Vehicle是具有几个子类型的抽象类:

public abstract class Vehicle {
}

@TypeAlias("CAR")
public class Car {
}

@TypeAlias("BOAT")
public class Boat {
}

@TypeAlias("MOTORBIKE")
public class Motorbike {
}

有什么办法让Spring处理这个用例?也就是说,如果我为客户节省了CarBoat,在查询Customer时它们是否正确补水?目前,我得到了java.lang.InstantiationError,因为Spring Data似乎正在尝试创建Vehicle抽象类的实例。

1 个答案:

答案 0 :(得分:0)

设法解决了这个问题。

基本上,我需要添加包含Vehicle类的软件包,以如下方式扫描到我的Mongo Configuration类:

public class CustomerDbConfig extends AbstractMongoConfiguration {

  ... 

  @Override
  protected Collection<String> getMappingBasePackages() {
    Collection<String> mappingBasePackages = new ArrayList<>();
    mappingBasePackages.add(Vehicle.class.getPackageName());

    return mappingBasePackages;
  }

}

我认为以上情况在大多数情况下都有效。我的理解是,如果Configuration类与Vehicle类位于同一包中,则可能不需要上面的内容,但是就我而言,它们位于两个不同的包中。

另外,由于我有多个具有不同配置和不同MongoTemplate Bean的Mongo数据库,这对我来说有点复杂。

最初,我是按照以下方式创建MongoTemplate

@Primary
@Bean(name = "customerMongoTemplate")
public MongoTemplate customerMongoTemplate() {
  MongoTemplate mongoTemplate = new MongoTemplate(mongoClient(), getDatabaseName());
  MappingMongoConverter converter = (MappingMongoConverter) mongoTemplate.getConverter();
  converter.setCustomConversions(customConversions());
  converter.afterPropertiesSet();
  return mongoTemplate;
}

但是,以这种方式通过MappingMongoConverter获得MongoTemplate意味着从未调用过getMappingBasePackages。我尝试通过执行以下操作来获取转换器:

@Primary
@Bean(name = "customerMongoTemplate")
public MongoTemplate customerMongoTemplate() {
  return new MongoTemplate(mongoDbFactory(), mappingMongoConverter());
}

但是它不起作用,因为mongoDbFactory()mappingMongoConverter()返回的bean用于不同的MongoDB配置……这对我来说是理想的解决方案,但不确定如何获得它可以可靠地与多个配置类一起工作。

最后,我设法可靠地进行了如下工作:

@Primary
@Bean(name = "customerMongoTemplate")
public MongoTemplate customerMongoTemplate() throws Exception {
  SimpleMongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClient(), getDatabaseName());

  MongoMappingContext mongoMappingContext = mongoMappingContext();
  mongoMappingContext.setInitialEntitySet(getInitialEntitySet());
  mongoMappingContext.afterPropertiesSet();

  MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory), mongoMappingContext);
  converter.setCustomConversions(customConversions());
  converter.afterPropertiesSet();

  return new MongoTemplate(mongoDbFactory, converter);
}

我对上述方法并不完全满意,它有点挑剔,可能会导致新版本的Spring出现问题,但是,它确实起作用。

相关问题