Как добавить окончательное поле в существующую коллекцию документов spring-data-mongodb?

2

У меня есть существующая коллекция документов, использующая spring-data-mongodb version 1.0.2.RELEASE.

@Document
public class Snapshot {
    @Id
    private final long id;
    private final String description;
    private final boolean active;

    @PersistenceConstructor
    public Snapshot(long id, String description, boolean active) {
        this.id = id;
        this.description = description;
        this.active = active;
    }
}

Я пытаюсь добавить новое свойство private final boolean billable;. Поскольку свойства final, они должны быть установлены в конструкторе. Если я добавлю новое свойство в конструктор, то приложение больше не сможет читать существующие документы.

org.springframework.data.mapping.model.MappingInstantiationException: Could not instantiate bean class [com.some.package.Snapshot]: Illegal arguments for constructor;

Насколько я могу судить, вы не можете иметь несколько конструкторов, объявленных как @PersistenceContstructor, поэтому, если я вручную не обновляю существующие документы, чтобы содержать поле billable, у меня нет способа добавить свойство final к этому существующему коллекция.

Кто-нибудь нашел решение этого раньше?

Теги:
spring-data-mongodb

1 ответ

3
Лучший ответ

Я обнаружил, что невозможно добавить новое поле private final в существующую коллекцию, используя только аннотацию @PersistenceContstructor. Вместо этого мне нужно было добавить реализацию org.springframework.core.convert.converter.Converter для обработки логики для меня.

Здесь мой конвертер выглядит следующим образом:

@ReadingConverter
public class SnapshotReadingConverter implements Converter<DBObject, Snapshot> {

    @Override
    public Snapshot convert(DBObject source) {
        long id = (Long) source.get("_id");
        String description = (String) source.get("description");
        boolean active = (Boolean) source.get("active");
        boolean billable = false;
        if (source.get("billable") != null) {
            billable = (Boolean) source.get("billable");
        }
        return new Snapshot(id, description, active, billable);
    }
}

Я надеюсь, что это может помочь кому-то еще в будущем.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню