How to add a final field to an existing spring-dat

2019-05-28 22:51发布

I have an existing document collection using 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;
    }
}

I'm trying to add a new property private final boolean billable;. Since the properties are final they need to be set in the constructor. If I add the new property to the constructor, then the application can no longer read the existing docs.

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

As far as I can tell, you cannot have multiple constructors declared as @PersistenceContstructorso unless I manually update the existing documents to contain the billable field, I have no way to add a final property to this existing collection.

Has anyone found a solution to this before?

1条回答
我想做一个坏孩纸
2楼-- · 2019-05-28 23:52

I found that it is not possible to add a new private final field to an existing collection using only the @PersistenceContstructor annotation. Instead I needed to add an org.springframework.core.convert.converter.Converter implementation to handle the logic for me.

Here's what my converter ended up looking like:

@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);
    }
}

I hope this can help someone else in the future.

查看更多
登录 后发表回答