[英]Spring doesn't save object to MongoDB correctly
Following question has been separated from this one: ArrayIndexOutOfBoundsException while Spring save data to MongoDB 以下问题已与以下问题分开: ArrayIndexOutOfBoundsException,而Spring将数据保存到MongoDB
I have problem with saving Object to MongoDB. 我将Object保存到MongoDB时遇到问题。 I've noticed that problem might be caused by too complex object.
我注意到这个问题可能是由太复杂的对象引起的。 I have following class hierarchy:
我有以下类层次结构:
ClassA
is superclass for ClassB
and ClassC
. ClassA
是ClassB
和ClassC
超类。 ClassD
contains map of maps. ClassD
包含地图的地图。 ClassC
contains ClassB
. ClassC
包含ClassB
。
Code which I invoke is following: 我调用的代码如下:
ClassC c = new ClassC()
c.setName("NAME");
mongoOperation.save(c, "Mongo"); // MongoOperations object
The problem is that Mongo doesn't save object's data. 问题是Mongo不保存对象的数据。 It saves only
_id
and _class
. 它只保存
_id
和_class
。
Actual data 实际数据
{
"_id" : ObjectId("53e86cd9c506f66eafaa03cb"),
"_class" : "com.sample.ClassC"
}
Expected data 预期数据
{
"_id" : ObjectId("53e86cd9c506f66eafaa03cb"),
"_class" : "com.sample.ClassC",
"name" : "NAME"
}
Funny thing is that when I comment out map field in ClassD
everything works fine. 有趣的是,当我在
ClassD
注释掉地图字段时,一切正常。
Is it possible to be caused by too complex object which I try to serialize? 是否有可能是由于我试图序列化的太复杂的对象造成的?
EDIT 编辑
When I remove bObject
from ClassC
it also works fine. 当我从
ClassC
删除bObject
,它也可以正常工作。
EDIT 2 编辑2
All classes are simple beans with setters and getters. 所有类都是带有setter和getter的简单bean。
eg 例如
public class ClassD{
private TreeMap<String, TreeMap<String,String>> map;
public TreeMap<String, TreeMap<String, String>> getMap() {
return map;
}
public void setMap(TreeMap<String, TreeMap<String, String>> map) {
this.map = map;
}
}
EDIT 3 编辑3
Full example below, it has same class hierarchy as picture above. 下面的完整示例,它具有与上图相同的类层次结构。
public class Application implements CommandLineRunner {
@Autowired
private MongoTemplate mongoTemplate;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) throws Exception {
ClassC cObject = new ClassC();
cObject.setName("Jon");
try {
mongoTemplate.save(cObject);
}catch(Exception e){
e.printStackTrace();
}
mongoTemplate.save(cObject);
}
}
class ClassA{
private String name;
private ClassD dObject;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ClassD getdObject() {
return dObject;
}
public void setdObject(ClassD dObject) {
this.dObject = dObject;
}
}
class ClassB extends ClassA {
}
class ClassC extends ClassA {
private ClassB b;
public ClassB getB() {
return b;
}
public void setB(ClassB b) {
this.b = b;
}
}
class ClassD {
private TreeMap<String, TreeMap<String, String>> map = new TreeMap<>();
public TreeMap<String, TreeMap<String, String>> getMap() {
return map;
}
public void setMap(TreeMap<String, TreeMap<String, String>> map) {
this.map = map;
}
}
The following code seems to work: 以下代码似乎有效:
@EnableAutoConfiguration
public class Application implements CommandLineRunner {
@Autowired
private MongoTemplate mongoTemplate;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) throws Exception {
Customer customer = new Customer("myself");
ClassB classB = new ClassB();
TreeMap<String, TreeMap<String, String>> map = new TreeMap<String, TreeMap<String, String>>();
TreeMap<String, String> innermap = new TreeMap<String, String>();
innermap.put("iam", "cool");
map.put("innermap", innermap);
TreeMap<String, String> innermap2 = new TreeMap<String, String>();
innermap2.put("youare", "yellow");
map.put("innermap2", innermap2);
classB.setMap(map);
customer.setClassB(classB);
try {
mongoTemplate.save(customer);
} catch (Exception e) {
e.printStackTrace();
}
mongoTemplate.save(customer);
System.out.println(mongoTemplate.findAll(Customer.class));;
}
}
public class ClassB {
private TreeMap<String, TreeMap<String, String>> map = new TreeMap<String, TreeMap<String, String>>();
public TreeMap<String, TreeMap<String, String>> getMap() {
return map;
}
public void setMap(TreeMap<String, TreeMap<String, String>> map) {
this.map = map;
}
}
@Document(collection ="customer")
public class Customer {
@Id
private String id;
private String name;
private ClassB classB;
public Customer() {
}
public Customer(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ClassB getClassB() {
return classB;
}
public void setClassB(ClassB classB) {
this.classB = classB;
}
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", classB=" + classB
+ "]";
}
}
But the ArrayIndexOutOfBoundsException-issue is still present. 但ArrayIndexOutOfBoundsException问题仍然存在。
I guess the MongoConverter
in specific version of your spring-data-mongodb.jar works incorrectly. 我猜
MongoConverter
在弹簧数据mongodb.jar的特定版本的作品不正确。 Spring must convert your ClassC
instance into DBObject
format, then call DBCollection.save
to save data into database. Spring必须将
ClassC
实例转换为DBObject
格式,然后调用DBCollection.save
将数据保存到数据库中。 You can check the content of DBObject
parameter in method "com.mongodb.DBCollection.save"
whether it contains correct data as you expect. 您可以在方法
"com.mongodb.DBCollection.save"
检查DBObject
参数的内容, DBObject
它是否包含您期望的正确数据。
I copy your ClassC
with complete structure and test, it's fine and cannot reproduce what you described above. 我复制你的
ClassC
完整的结构和测试,它很好,不能重现你上面描述的。 I use spring-data-mongdb-1.2.3-RELEASE.jar. 我使用spring-data-mongdb-1.2.3-RELEASE.jar。 What's the version you adopt?
你采用的是什么版本?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.