我尝试使用spring boot将初始json文档加载到mongodb数据库中。首先,这些是mongodb文档架构。
@Document(collection="Posts")
public class Post {
@Id
private String _id;
@Indexed(unique = true)
private Long id; // This field is used for compatibility with Jpa Service interface
private String title;
private String body;
private Date createdDate;
@DBRef
private User user;
@DBRef
private Collection<Tag> tags;
}
以下代码是最初的json文件内容。
[ {
"Post" : {
"id" : 1,
"title" : "Title 1",
"created_date" : "2018-12-01 11:10:13.247",
"body" : " 국회는 헌법 또는 ....",
"user" : {
"username" : "joseph",
"password" : "password"
},
"tags" : {
"tag" : [
{
"id" : 1,
"created_Date" : "2018-12-02 11:10:13.247",
"body" : "첫 글의 댓글입니다.",
"user" : {
"username" : "jina",
"password" : "password"
}
},{
"id" : 2,
"created_Date" : "2018-12-03 11:10:13.247",
"body" : "첫 글의 두번째 댓글입니다.",
"user" : {
"username" : "julian",
"password" : "password"
} } ] } }
}
,
{
"post" : {
"id" : 2,
"title" : "Title 2",
"created_date" : "2018-12-03 11:10:13.247",
"body" : "제안된 헌법개정안은 대통령이 ....",
"user" : {
"username" : "joseph",
"password" : "password"
},
"tags" : {
"tag" : [
{
"id" : 1,
"created_Date" : "2018-12-02 11:10:13.247",
"body" : "댓글 입니다.",
"user" : {
"username" : "julian",
"password" : "password"
} } ] } }
}]
最后的部分是将上面的初始json文件加载到mongodb中的函数。
@Override
public void loadInitDocuments(String file) {
// TODO Auto-generated method stub
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "EUC-KR"))) {
String line;
StringBuffer strBuffer = new StringBuffer();
while ((line = br.readLine()) != null) {
strBuffer.append(line+ "\n");
}
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
TypeReference<List<Post>> typeReference = new TypeReference<List<Post>>(){};
Collection<Post> posts = objectMapper.readValue(strBuffer.toString(), typeReference);
System.out.println(posts.stream().collect(Collectors.toList()));
if(postMongoRepository.count() == 0) {
for(Post post : posts) {
postMongoRepository.save(post); // this line throws exception
}
}
br.close();
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
但MongoRepository.save行抛出异常。
Caused by: com.mongodb.MongoWriteException: E11000 duplicate key error collection: Blog.Posts index: id dup key: { : null }
at com.mongodb.client.internal.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:967)
at com.mongodb.client.internal.MongoCollectionImpl.executeInsertOne(MongoCollectionImpl.java:494)
at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:478)
at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:472)
at org.springframework.data.mongodb.core.MongoTemplate$6.doInCollection(MongoTemplate.java:1436)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:538)
我用谷歌搜索找到了原因。原因是“如果文档没有唯一索引中索引字段的值,索引将为此文档存储空值。由于唯一约束,MongoDB只允许一个缺少索引字段的文档。 “但我不知道json文件的哪一部分有错误的值。
这次我遇到了@Dbref注释部分的问题。以下是用户文档代码,
@Document //
public class User {
@Id //(2)
private String _id;
@Indexed(unique = true)
private Long id;
@Indexed(unique=true)
private String username;
private String password;
}
以下是修改后的初始json文件内容。
[
{
"id" : 0,
"title" : "Title 1",
"created_date" : "2018-12-01 11:10:13.247",
"body" : " 국회는 헌법 또는 법률에 ",
"user" : {
"id" : 0,
"username" : "joseph",
"password" : "password"
},
"tag" : [
{
"id" : 0,
"created_Date" : "2018-12-02 11:10:13.247",
"body" : "첫 글의 댓글입니다.",
"user" : {
"id" : 1,
"username" : "jina",
"password" : "password"
}
},{
"id" : 1,
"created_Date" : "2018-12-03 11:10:13.247",
"body" : "첫 글의 두번째 댓글입니다.",
"user" : {
"id" : 2,
"username" : "julian",
"password" : "password"
}
} ] }
,
{
"id" : 1,
"title" : "Title 2",
"created_date" : "2018-12-03 11:10:13.247",
"body" : "제안된 헌법개정안은 대통령이 20",
"user" : {
"id" : 0,
"username" : "joseph",
"password" : "password"
},
"tag" : [
{
"id" : 0,
"created_Date" : "2018-12-02 11:10:13.247",
"body" : "댓글 입니다.",
"user" : {
"id" : 2,
"username" : "julian",
"password" : "password"
} } ] }
]
但user
文档不与json文件绑定。例外是......
Cannot create a reference to an object with a NULL id.
org.springframework.data.mapping.MappingException: Cannot create a reference to an object with a NULL id.
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.createDBRef(MappingMongoConverter.java:975)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:597)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeAssociation(MappingMongoConverter.java:560)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeProperties(MappingMongoConverter.java:537)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:524)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:497)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:441)
User
文档不与Post
文档绑定,因此它返回null值。执行此行时,返回false
for(Post post : posts) {
if(post.getUser().getId() == null)
System.out.println("YES!! It is null");
postMongoRepository.save(post);
}
在您的初始json文件中,您有一个包含两个根文件的2个文档的数组:第一个为“Post”,第二个为“post”。因此保存第一个文档将导致id = null(因为定义了Post.id,但不是id)。与第二个相同会抛出错误...尝试替换,它必须工作......
[ {
"id" : 1,
"title" : "Title 1",
"created_date" : "2018-12-01 11:10:13.247",
"body" : " 국회는 헌법 또는 ....",
"user" : {
"username" : "joseph",
"password" : "password"
},
"tags" : {
"tag" : [
{
"id" : 1,
"created_Date" : "2018-12-02 11:10:13.247",
"body" : "첫 글의 댓글입니다.",
"user" : {
"username" : "jina",
"password" : "password"
}
},{
"id" : 2,
"created_Date" : "2018-12-03 11:10:13.247",
"body" : "첫 글의 두번째 댓글입니다.",
"user" : {
"username" : "julian",
"password" : "password"
} } ] }
}
,
{
"id" : 2,
"title" : "Title 2",
"created_date" : "2018-12-03 11:10:13.247",
"body" : "제안된 헌법개정안은 대통령이 ....",
"user" : {
"username" : "joseph",
"password" : "password"
},
"tags" : {
"tag" : [
{
"id" : 1,
"created_Date" : "2018-12-02 11:10:13.247",
"body" : "댓글 입니다.",
"user" : {
"username" : "julian",
"password" : "password"
} } ] }
}]