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

У меня есть существующая коллекция документов, использующая spring-data-mongodb версию 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 в эту существующую коллекцию.

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


person mpage    schedule 21.11.2013    source источник


Ответы (1)


Я обнаружил, что невозможно добавить новое поле 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);
    }
}

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

person mpage    schedule 22.11.2013