我尝试使用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
文档绑定,因此返回空值。执行此行后,它返回false
for(Post post : posts) {
if(post.getUser().getId() == null)
System.out.println("YES!! It is null");
postMongoRepository.save(post);
}
答案 0 :(得分:2)
在您的初始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"
} } ] }
}]