2

I try to load initial json documents into mongodb database with spring boot. First, These are mongodb documents schema.

@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;
}

And below codes are the initial json file contents.

[ {
    "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"
                    } } ] } }   
}]

And the last parts are the function which load the above initial json file into 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());
        }

But MongoRepository.save line throws exception.

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)

I found the reason with googling. The reason is "If a document does not have a value for the indexed field in a unique index, the index will store a null value for this document. Because of the unique constraint, MongoDB will only permit one document that lacks the indexed field." But I have no idea which part of json file has wrong value.

Edited Part

This time I face the problem with the @Dbref annotation part. Below is the User document codes,

@Document //
public class User {

    @Id //(2)
    private String _id;

    @Indexed(unique = true)
    private Long id;

    @Indexed(unique=true)
    private String username;

    private String password;
}

And below are the modified initial json file contents.

[
    {
        "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"
                } } ] } 
]

But the user document is not bound with json file. The exception is...

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 document is not bound with Post document, so it return null value. When this line is executed it return false

for(Post post : posts) {
  if(post.getUser().getId() == null)
    System.out.println("YES!! It is null");

  postMongoRepository.save(post);
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Joseph Hwang
  • 1,337
  • 3
  • 38
  • 67
  • As per prior edits that have been notified to you, please bear in mind that we prefer a technical style of writing here. We gently discourage greetings, hope-you-can-helps, thanks, advance thanks, notes of appreciation, regards, kind regards, signatures, please-can-you-helps, chatty material and abbreviated txtspk, pleading, how long you've been stuck, voting advice, meta commentary, etc. Just explain your problem, and show what you've tried, what you expected, and what actually happened. – halfer Mar 10 '19 at 17:14

1 Answers1

2

In your initial json file, you have an array of 2 documents, which have only one root field : "Post" for first one, "post" for second one. So saving first document will result in id=null (as Post.id is defined, but not id). And the same with the second will throw error... Try replacing by, and it must work...

[ {
        "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"
                    } } ] }    
}]
matthPen
  • 4,253
  • 1
  • 16
  • 16