Java, when I put my User in a Map, it's not working

OpperDev :

I'm developing two api for a minecraft server, a proxy, and a spigot, when a player connects, the proxy API fetches the player on the database, then sends it on redis, then the api spigot will look for the player on redis, and save it in a Map, and that's where the problem is, I have a "User#get" method like this:

public static User get(UUID uuid) {
    return users.getOrDefault(uuid, fetchUser(uuid));
}

And a "User#fetchUser" like this:

private static User fetchUser(UUID uuid) {
    return Main.instance.getRedisAPI().get(uuid.toString(), User.class);
}

The key redis is the uuid of the player, and the value, is the user class serialized in JSON, with the api Gson I recently knew that Gson, to deserialize, created his own empty constructor, and filled the fields by reflection, which I do not want, because it is in my constructor that I put the User in the map. So I created my own TypeAdapter that implements JsonDeserializer, in order to run the constructor. it works, the constructor is well executed, but the user is not put in the map! So every time I make a User#get, it runs the fetchUser, and it ends up crashing because it's too many requests. I'm putting my classes in a pastebin for you to watch. (sorry if that's not the way to do it, it's the first time I'm posting on stackoverflow, and sorry for my english, I'm french and I use google translation)

User.java > https://pastebin.com/4ta4XDqX
RedisAPI.java > https://pastebin.com/GjWPUf4m
Serializer.java > https://pastebin.com/k6g1KYYF
UserDeserializer.java > https://pastebin.com/0LF7trSR

Thank you in advance.

Jorn Vernee :

Map::getOrDefault does:

Returns the value to which the specified key is mapped, or defaultValue if this map contains no mapping for the key.

So, it does not add any value to the map at all. You're also always eagerly executing the User::fetchUser method, whether the UUID exists in the map or not.

It sounds like you need Map::computeIfAbsent instead, which:

If the specified key is not already associated with a value (or is mapped to null), attempts to compute its value using the given mapping function and enters it into this map unless null.

i.e.

public static User get(UUID uuid) {
    return users.computeIfAbsent(uuid, User::fetchUser);
}

Where User::fetchUser is only executed if the UUID was not found in the map already.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=129936&siteId=1