假设我有一个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处理这个用例?也就是说,如果我为客户节省了Car
和Boat
,在查询Customer
时它们是否正确补水?目前,我得到了java.lang.InstantiationError
,因为Spring Data似乎正在尝试创建Vehicle
抽象类的实例。
答案 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出现问题,但是,它确实起作用。