【问题标题】:Why is Spring Data MongoDB unable to instantiate this nested type structure?为什么 Spring Data MongoDB 无法实例化这种嵌套类型结构?
【发布时间】:2014-12-09 06:37:03
【问题描述】:

我的文档结构是这样的:

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

我的 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 参数,我会收到DataConfig 的错误。数据是使用命令行/节点脚本添加的,而不是使用此代码添加的。但它可以通过节点/猫鼬以及命令行正确检索。

【问题讨论】:

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


    【解决方案1】:
    Failed to instantiate ... using constructor public ... ReflectionEntityInstantiator
    

    说它不能使用反射创建对象。

    你的所有类中的所有字段都有 getter 和 setter 吗?您上面的代码没有ParamDataConfigDataConfig

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

    【讨论】:

    • 抱歉,我好像没有添加 cmets,但是是的,所有类都有 getter 和 setter,没有一个类有非默认构造函数。
    • 我不确定是为了节省空间,您是否将所有类都保存在 Entity 类本身中,或者它们是否在它们自己的类文件中。您需要将每个类放在一个单独的文件中,并用@Document 进行注释。例如,请参见此处:stackoverflow.com/questions/11255100/…
    • @arun - 这不是必需的。如果操作正确,内部类就可以工作。
    【解决方案2】:

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

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

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

    【讨论】:

    • 感谢您将ParamData 移动到GroupDataConfig 中的Config 类中,它现在正在工作。但是偶然发现了另一个问题,它不允许我声明List&lt;Group&gt;,它需要ArrayList&lt;Group&gt;Group[],但对List&lt;String&gt; 工作正常!但就目前而言,它至少可以工作。
    猜你喜欢
    • 2017-04-19
    • 2015-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多