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.