So I'm having this issue where I'm using a single collection to store different classes that inherit from the same abstract class wrapped in another class. I can insert these records without issue, but when I need to update a common property it fails. What can I do in this case?
Error:
"Failed to instantiate com.models.Task using constructor public com.models.Task() with arguments "
Classes:
//wrapper
@Data
@Document(collection="tasks")
public class WrapperTask {
@Id
private ObjectId id;
@BsonProperty(useDiscriminator = true)
private Task task;
public WrapperTask() {
}
public String getId() {
return Utils.ObjectId(this.id);
}
}
//abstract
@Data
@JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@Type(value = UploadTask.class, name = "uploadTask"),
//more classes
})
@BsonDiscriminator
public abstract class Task {
private TaskStatus status;
public int totalCount;
public int completedCount;
public Task() {
this.status = TaskStatus.NEW;
}
}
//child
@Data
@EqualsAndHashCode(callSuper = true)
@Document(collection = "tasks")
@TypeAlias("uploadTask")
@BsonDiscriminator
public class UploadTask extends Task {
private LinkedList<Document> documents = new LinkedList<>();
public UploadTask(int totalCount) {
super();
this.totalCount = totalCount;
}
public UploadTask() {
super();
}
}
Logic:
Query query = new Query(Criteria.where("_id").is(taskId));
Update update = new Update();
update = update.set("task.status", "some status");
if (taskType == UploadTask.class) {
Criteria criteria = Criteria.where("document.index").is(index);
update = update.set("task.documents.$[document].status", "some status");
update = update.set("task.documents.$[document].statusMessage", "some message").filterArray(criteria);
}
mongoOperations.findAndModify(query, update, options().upsert(false), WrapperTask.class);
So, how do I make this update work?
Thanks
As suggested in this post, the answer is to override the getMappingBasePackages()
in the mongo config file:
@Override
protected Collection<String> getMappingBasePackages()
{
return Arrays.asList("com.myapp.models");
}