简体   繁体   中英

MongoDB Java not saving sub document

I have a local MongoDB database with a collection that contain players data, the class responsible for this collection is PlayersDataDB. I also have a custom class MyDocument, that extend org.bson.Document, it contain some custom methods like getColoredString(String key) and also a custom getEmbedded(String path, boolean create) that look for an embedded from a String like "subDoc1.subDoc2" and create if it's missing and if create==true

What i want to do: i want to save to the database every time when i'm editing the MyDocument, so every time when i use put() , append() , remove() . For example if a have the base document named 'root' i get the embedded "doc1.doc2" and i put in a String "test: yes", i want it to go up to the root Document ( named parent in the code ) and save it to the collection and key, passed in the constructor.

My problem: But for now, when i'm testing it show "saving" in the terminal but when i look in the database nothing change.

This example create the docs and they appear in the DB: new PlayersDataDB(uuid).getDocument().getEmbedded("doc1.doc2", true ).put("t1","yes" ); But when i reuse it: new PlayersDataDB(uuid).getDocument().getEmbedded("doc1.doc2", true ).put("test","yes" ); the "doc1" and "doc2" sub documents already exist, it show in the terminal "putting test -> yes" and "saving" but nothing appear in the DB

Note: this code is for a plugin for Minecraft where each player have 1 unique UUID, so the DB have 1 unique Document for each player

The class PlayersDataDB, responsable for this collection:

public static final MongoCollection<Document> players = MongoDB.getDB()
            .getCollection( "playersData" );

public final Document uuidDocument;
private MyDocument document;


public PlayersDataDB( UUID uuid ) {
    uuidDocument = new Document( "uuid", "player's uuid" );
    Document foundDoc = players.find( uuidDocument ).first();
    if( foundDoc == null ) {
        this.document = new MyDocument( players, uuidDocument )
                  .append( "uuid", player.getUniqueId().toString() )
                  .append( "nickname", "MyName" )
                  .append( "group", "default" )
                  .append( "lastTimeSeen", "Is online" );
    } else { // as i can't cast Document to MyDocument, i use putall() to copy all data
        this.document = new MyDocument( players, uuidDocument );
        this.document.putAll( foundDoc );
    }
}
public MyDocument getDocument() {
    return document;
}

And here is the MyDocument class: The problem is in my custom getEmbedded(String, boolean) and maybe also in the save()


import com.mongodb.client.MongoCollection;
import org.bson.Document;

import java.util.Map;

public class MyDocument extends Document {

    private MongoCollection<Document> collectionOfCurrentDoc;
    private Document keyWhereSave;
    private MyDocument parent;

    // either the document is the root, it's the one i need to save
    public MyDocument( MongoCollection<Document> col, Document keyWhereSave ) {
        super();
        collectionOfCurrentDoc = col;
        this.keyWhereSave = keyWhereSave;
    }

    // or it's a sub document, so it have a parent
    public MyDocument( MyDocument parent ) {
        super( key, value );
        this.parent = parent;
    }

    public String getColoredString( String key ) {
        String res = super.getString( key );
        if( res != null )
            res = "colored " + res; 
            //using other classes here so i put this for example
        return res;
    }

    public String getColoredString( String path, String key ) {
        MyDocument embedded = getEmbedded( path, false );
        if( embedded != null )
            return embedded.getColoredString( key );
        return null;
    }

    public MyDocument getEmbedded( String path, boolean createIfMissing ) {
        MyDocument value = this;
        for( String key : path.split( "\\." ) ) {
            Document foundDoc = value.get( key, Document.class );
            MyDocument nextEmbedded = new MyDocument( value );
            if( foundDoc == null ) {
                System.out.println( "%s embedded don't exist".formatted( key ) );
                if( createIfMissing ) {
                    System.out.println( "creating embedded %s".formatted( key ) );
                    value.put( key, nextEmbedded );
                } else
                    return null;
            } else {
                System.out.println( "embedded already exist" );
                nextEmbedded.putAll( foundDoc );
            }
            System.out.println( "-".repeat( 20 ) );
            value = nextEmbedded;
        }
        return value;
    }

    public void save() {
        MyDocument docToSave = this;
        while( docToSave.parent != null ) {
            System.out.println( "found parent" );
            docToSave = docToSave.parent;
        }
        System.out.println( "saving " );
        docToSave.collectionOfCurrentDoc.replaceOne( docToSave.keyWhereSave, docToSave );
    }

    @Override
    public Object put( String key, Object value ) {
        System.out.println( "putting %s -> %s".formatted( key, value ) );
        Object res = super.put( key, value );
        save();
        return res;
    }

    @Override
    public Object remove( Object key ) {
        Object res = super.remove( key ); ;
        save();
        return res;
    }

    public MyDocument append( String key, Object value ) {
        super.append( key, value );
        save();
        return this;
    }
}

I found how to fix this, i had to add the key to the current MyDocument and make the current document save himself to his parent like this: docToSave.parent.put( docToSave.keyToThis, docToSave ); in the save() while loop

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM