简体   繁体   中英

Working with POJO classes as schema for mongo db, specifically handling schema changes

I'm using simple Java classes which are the schema for my mongo db table. There are several frameworks for serialization/ deserialization to/ from JSON and CRUD operations for mongo (I've looked into Jackson serializer and Morphia). But none of them seems to provide a solution for handling changes:

Let's say I have this class as my schema:

Class Person
{
  String name;
  int age;
  String occupation;
}

In my code, I will probably use a setter in some place for age:

Person newDbEntry = new Person();
newDbEntry.setAge(45);
newDbEntry.setOccupation("Carpenter");

Now let's say that at some point of the development process, it was decided that age field name needs to be changed to "theAge", and it was also decided to remove "occupation" field from this collection completely- to a new table.

The problem that I'm faced with is that all my queries look like this:

JsonObject query = new JsonObject().put("age",new JsonObject().put("$gte", 22);

In other words, all field names are written in queries as Strings (and also in all other mongo APIs- update, findAndModify, etc).

I'm looking for a way to "bind" all mentions of the field "age" in my code with the POJO class- so that when something in the POJO schema changes (like renaming this field), I'll have (ideally) compiler errors in all queries that mention this field.

As it currently stands, changes to schema cause no compiler errors and - more critically - usually no runtime errors. The old string query just quietly returns no results, or something similar. This makes changes to the schema very hard to implement.

How should this be done correctly?

Here's the solution that I ended up using: Project lombok now supports FieldNames generation: https://projectlombok.org/features/experimental/FieldNameConstants

So instead of using the name hardcoded as string:

serviceRepository.setField(id, “service.serviceName”, “newName”);

I use:

serviceRepository.setField(id, ConnectivityServiceDetails.Fields.service + "." + ConnectivityService.Fields.serviceName, “newName”);

This way, when we search in Intellij for usages of this field (or try to refactor it), it will find those places also automatically.

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