为什么Spring Data MongoDB无法实例化这种嵌套类型结构?

时间:2014-10-14 12:50:43

标签: mongodb spring-data spring-data-mongodb

我的文档结构如下:

{
    _id: "A",
    groups:[{
        groupId: "someId",
        groupName: "someName",
        params: {
            type1: ["a", "b"],
            type2: ["c", d]
        }
    }],
    config: {
        person: {}
        dataDetails: {
            dataTypeDetails: {},
            dataList: ["dt1", "dt2"]
        }
    }
}

My Spring Data MongoDB模型类型如下所示:

// Imports etc.
@Document
public class Entity {

    @Id
    private String _id;

    private List<Group> groups;
    private Config config;
    // setters and getters

    public class Group {
        private String groupId;
        private String groupName;
        private ParamData params;

        // setter and getters
    }

    public class ParamData {
        private List<String> type1;
        private List<String> type2;
    }

    public class Config {
        private Map person;
        private DataConfig dataDetails;
    }

    public class DataConfig {
        private Map dataTypeDetails;
        private List<String> dataList;
    }
}

堆栈跟踪:

org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate com.****.common.models.Entity$ParamData using constructor public com.****.common.models.Entity$ParamData(com.****.common.models.Entity) with arguments com.****.common.models.Entity$Group@2eb61a7b
    at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:78)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:257)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:237)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1136)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.access$100(MappingMongoConverter.java:78)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1085)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getValueInternal(MappingMongoConverter.java:816)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$1.doWithPersistentProperty(MappingMongoConverter.java:270)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$1.doWithPersistentProperty(MappingMongoConverter.java:263)
    at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:261)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:263)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:237)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readCollectionOrArray(MappingMongoConverter.java:861)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1134)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.access$100(MappingMongoConverter.java:78)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1085)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getValueInternal(MappingMongoConverter.java:816)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$1.doWithPersistentProperty(MappingMongoConverter.java:270)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$1.doWithPersistentProperty(MappingMongoConverter.java:263)
    at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:261)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:263)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:237)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:201)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:197)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:78)
    at org.springframework.data.mongodb.core.MongoTemplate$ReadDbObjectCallback.doWith(MongoTemplate.java:2016)
    at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1700)
    at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1523)
    at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1507)
    at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:532)
    at org.springframework.data.mongodb.core.MongoTemplate.findOne(MongoTemplate.java:497)
    at org.springframework.data.mongodb.core.MongoTemplate.findOne(MongoTemplate.java:489)

我在DAO中我试图通过标识符获取文档,但它仅对dataDetails和params的值失败。如果我注释掉ParamData param,我会收到DataConfig的错误消息。数据是使用命令行/节点脚本添加的,未使用此代码添加。但它可以通过node / mongoose以及命令行正确检索。

2 个答案:

答案 0 :(得分:5)

这似乎是双嵌套内部类和编译器创建的综合生成构造函数的问题。我可以在本地重现该问题,看看我们是否可以提供修复。在此期间,您有两种选择:

  1. 将内部类转换为静态类,因为这将删除合成构造函数,并且实例化将正常工作。
  2. 以与嵌套属性相同的方式嵌套类型声明。即将ParamData类移动到GroupDataConfigConfig,因为这将导致合成构造函数以与Spring Data当前依赖的实例化顺序匹配的方式创建。< / LI>

    我建议采用前一种方法,因为它没有人为地将类绑定到外部类的实例。

答案 1 :(得分:1)

Failed to instantiate ... using constructor public ... ReflectionEntityInstantiator

表示无法使用反射创建对象。

你们所有课程中的所有领域都有getter和setter吗?您上面的代码没有ParamDataConfigDataConfig的代码。

此外,如果您的任何类中碰巧有非默认构造函数,请确保您有一个空参数构造函数,否则反射将失败。