Solved MongoDB with Morphia - Cannot save different instance

Discussion in 'Spigot Plugin Development' started by Maxx_Qc, Feb 12, 2020.

  1. Hey guys, so I'm trying to use morphia but it's kinda complicated for someone who's kinda new to database manipulations. Basically, once a user logs into the server I store all his data into the mongodb using morphia. The thing is, if someone else joins, the first user's data is overwritten into the database with the new user's data. I don't know why it's doing that and I've been going crazy trying to fix that >.<

    Here's my code for my UserManager:
    Code (Java):

    import org.bukkit.OfflinePlayer;
    import org.bukkit.entity.Player;

    import java.util.ArrayList;
    import java.util.LinkedHashSet;

    public class UserManager
    {
        private JavaPlugin plugin;
        private LinkedHashSet<User> users;

        public UserManager(final JavaPlugin plugin)
        {
            this.plugin = plugin;
            this.users = new LinkedHashSet<>();
        }

        public LinkedHashSet<User> getUsers() { return users; }

        private boolean cachedDataContains(final Player player)
        {
            final User user = getUsers().stream().filter(find -> find.getUuid().equalsIgnoreCase(player.getUniqueId().toString())).findFirst().orElse(null);
            return user != null;
        }

        private boolean cachedDataContains(final OfflinePlayer player)
        {
            final User user = getUsers().stream().filter(find -> find.getUuid().equalsIgnoreCase(player.getUniqueId().toString())).findFirst().orElse(null);
            return user != null;
        }

        public User getUser(final OfflinePlayer player)
        {
            if (cachedDataContains(player))
                return getUsers().stream().filter(find -> find.getUuid().equalsIgnoreCase(player.getUniqueId().toString())).findFirst().orElse(null);

            return plugin.getUserDAO().findOne("uuid", player.getUniqueId().toString());
        }

        public User getUser(final Player player)
        {
            if (cachedDataContains(player))
                return getUsers().stream().filter(find -> find.getUuid().equalsIgnoreCase(player.getUniqueId().toString())).findFirst().orElse(null);

            User user = plugin.getUserDAO().findOne("uuid", player.getUniqueId().toString());
            if (user == null)
                user = createUser(player);
            else
            {
                user.setPlayer(player);
                user.setRankName(user.getRankName());
                if (user.getOwnedChunks() == null)
                    user.setOwnedChunks(new ArrayList<>());
            }
            getUsers().add(user);
            return user;
        }

        public User loadUser(final Player player)
        {
            return getUser(player);
        }

        public void saveUser(final User user) { plugin.getUserDAO().save(user); }

        public void saveUser(final Player player) { plugin.getUserDAO().save(getUser(player)); }

        private User createUser(final Player player)
        {
            User user = new User();
            user.setPlayer(player);
            user.setup();
            user.setCoins(plugin.getConfig().getInt("options.starting-coins"));
            user.setIpHistory(new ArrayList<>());
            user.setNameHistory(new ArrayList<>());
            user.setOwnedChunks(new ArrayList<>());
            user.setRankName("DEFAULT");
            saveUser(user);
            return user;
        }

        public void unregisterUser(final Player player)
        {
            System.out.println("boop");
            User user = getUser(player);
            if (user == null) //will never happen anyway?
                return;
            user.setup();
            saveUser(user);
            getUsers().remove(user);
        }
    }
     
    Just wanna mention that I also use morphia to store claimed chunks into my mondb and it does the same thing. The database can only contain one claimed chunk at the time and gets overwritten everytime.
     
  2. Your ID is never set, as you are using mongo you should use the player's UUID as the actual document ID
     
  3. How can I do that? I've been trying to use
    Code (Java):
    @Id
    protected String id;
    and using this.id = playerUUID; but it doesn't work. I always get a duplicated key error message.
     
  4. Set your variable as final and initialize it in the constructor? The object may be saving in mongo while the variable is still not initialized ?
     
  5. Basically what I did:
    Code (Java):
    @Id
    protected final String id;

    public User(String id) { this.id = id; }
    Error:
    Code (Text):
    Caused by: com.mongodb.DuplicateKeyException: Write failed with error code 11000 and error message 'E11000 duplicate key error collection: survival.users index: uuid_1 dup key: { uuid: null }'
            at com.mongodb.operation.BaseWriteOperation.convertBulkWriteException(BaseWriteOperation.java:243) ~[?:?]
            at com.mongodb.operation.BaseWriteOperation.access$300(BaseWriteOperation.java:60) ~[?:?]
            at com.mongodb.operation.BaseWriteOperation$1.call(BaseWriteOperation.java:144) ~[?:?]
            at com.mongodb.operation.BaseWriteOperation$1.call(BaseWriteOperation.java:133) ~[?:?]
            at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:424) ~[?:?]
            at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:415) ~[?:?]
            at com.mongodb.operation.BaseWriteOperation.execute(BaseWriteOperation.java:133) ~[?:?]
            at com.mongodb.operation.BaseWriteOperation.execute(BaseWriteOperation.java:60) ~[?:?]
            at com.mongodb.Mongo.execute(Mongo.java:819) ~[?:?]
            at com.mongodb.Mongo$2.execute(Mongo.java:802) ~[?:?]
            at com.mongodb.DBCollection.executeWriteOperation(DBCollection.java:340) ~[?:?]
            at com.mongodb.DBCollection.update(DBCollection.java:565) ~[?:?]
            at org.mongodb.morphia.DatastoreImpl.saveDocument(DatastoreImpl.java:1299) ~[?:?]
            at org.mongodb.morphia.DatastoreImpl.save(DatastoreImpl.java:1289) ~[?:?]
            at org.mongodb.morphia.DatastoreImpl.save(DatastoreImpl.java:775) ~[?:?]
            at org.mongodb.morphia.DatastoreImpl.save(DatastoreImpl.java:758) ~[?:?]
            at org.mongodb.morphia.dao.BasicDAO.save(BasicDAO.java:230) ~[?:?]
            at com.maxx.themcsurvival.data.UserManager.saveUser(UserManager.java:67) ~[?:?]
            at com.maxx.themcsurvival.data.UserManager.createUser(UserManager.java:81) ~[?:?]
            at com.maxx.themcsurvival.data.UserManager.getUser(UserManager.java:50) ~[?:?]
            at com.maxx.themcsurvival.data.UserManager.loadUser(UserManager.java:64) ~[?:?]
            at com.maxx.themcsurvival.listener.JoinLeaveListener.onJoin(JoinLeaveListener.java:26) ~[?:?]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_201]
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_201]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_201]
            at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_201]
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:316) ~[spigot.jar:git-Spigot-800b93f-a81f6ed]
            ... 13 more
     
  6. Why do you use morphia? , It is not necessary

    Also as you say, you are new , is something more complicated I do not recommend it
     
  7. Morphia is making my life easier for storing both of my classes into mongodb without having to do all the work myself.
    I might be new, but it doesn't mean that I cannot learn and in fact, become not new to this.
     
  8. You are wrong, you learn from the easiest to the hard, you are going astray ,
    I also explained to you in the other thread what you have to do and you just ignored it, that's why I think helping you again won't be worth it.
     
  9. I didn’t ignore it. I followed what you said in order to get it working lol whatever