takotsubo
takotsubo

Reputation: 746

Need help troubleshooting with Jackson

I have a HashMap which I initialize once in static block from a json file. Then I work with my local HashMap to save users requests.

static {
  TypeFactory typeFactory = mapper.getTypeFactory();
  MapType mapType = typeFactory.constructMapType(ConcurrentHashMap.class, String.class, GooglePlayGame.class);
  try {
       games = mapper.readValue(new File("games.json"), mapType);
        } catch (IOException e) {
          log.error(e.getMessage());
        }
    }

When I decide to stop app and launch it again, I can add new pair of "key-value" to this map, but when I'm trying to append changes into my json file, everything that was already in json file is duplicated + new value. This code:

try(JsonGenerator g = mapper.getFactory().createGenerator(
                  new PrintWriter(new BufferedWriter(new FileWriter(new File("games.json"), true))))) {
    mapper.writeValue(g, games);
    } catch (IOException e) {
      log.error(e.getMessage());
    }

I understood why it's happening (because of static initialization every new launch, and then I write to file all hashmap again and again), but I don't know how to fix this. I want to append new pairs to existing json file.

For example: Adding first request, all fine:

{"Machinarium":
   {"Title":"Machinarium",
    "Updated":"28 February, 2019",
    "Version":"2.5.6","Requirements":"4.1,
     "Contacts":"[email protected]"
}

Then I restart app and got another request, my json file now looks like:

{"Machinarium":
   {"Title":"Machinarium",
    "Updated":"28 February, 2019",
    "Version":"2.5.6","Requirements":"4.1,
     "Contacts":"[email protected]",
....
},
{"Machinarium":
   {"Title":"Machinarium",
    "Updated":"28 February, 2019",
    "Version":"2.5.6","Requirements":"4.1,
     "Contacts":"[email protected]",
....
},
"Samorost 3":
   {"Title":"Samorost 3",
    "Updated":"November 14, 2019",
     "Version":"1.0",
     "Requirements":"4.3,
...}

As you can see, duplicate here.

So the goal is: create HashMap -> get user request -> write this request(pair "key-value") to local hashmap -> write hashmap (or every pair separately? hmm) to json file. Then when app starts again: initialize hashmap from this json file with saved requests -> get new user request -> add new requests to json file.

I need to write each pair one by one to file (not all map), but how?

Upvotes: 2

Views: 97

Answers (1)

Christopher Schneider
Christopher Schneider

Reputation: 3915

Ultimately, your issue is here: new FileWriter(new File("games.json"), true)).

The FileWriter constructor is FileWriter(File file, boolean append) so you are appending data to that file every time you write.

What you want instead is just FileWriter(File file) which overwrites the file by default. This assumes that your games map is always up to date and has all the data in memory.

This is a bit less efficient since you'd be overwriting the entire file every time a change is made, but this doesn't seem likely to be a lot of data, so I don't think it should be a concern. If this turns out to be a very large amount of data that is updated frequently, you may want to look into using a database instead of a JSON file.

Upvotes: 1

Related Questions