morphia: Mapper error updating Key array field with $set
Morphia 1.1.1 MongoDB Java Driver version: 2.14.0 MongoDB version: 3.0.12
Error:
161122 15:26:53,310 ERROR [Mapper] Error converting value([]) to reference.
java.lang.NullPointerException
at org.mongodb.morphia.mapping.Mapper.getDBRefs(Mapper.java:725)
at org.mongodb.morphia.mapping.Mapper.toMongoObject(Mapper.java:559)
at org.mongodb.morphia.query.UpdateOpsImpl.add(UpdateOpsImpl.java:216)
at org.mongodb.morphia.query.UpdateOpsImpl.set(UpdateOpsImpl.java:155)
at com.farmerswife.cloudwife.server.services.dao.AbstractDAO.set(AbstractDAO.java:146)
at com.farmerswife.cloudwife.server.services.dao.TaskDAO.updateAssignees(TaskDAO.java:661)
at com.farmerswife.cloudwife.server.services.utils.UserConsumerUtils.consumeTaskAssignments(UserConsumerUtils.java:358)
xxxDAO
methods on stack trace:
public void updateAssignees(EntityId<CWTask> taskId, List<Key<? extends Assignable>> assignees) {
set(taskId, ASSIGNEES_FIELD, assignees);
}
protected boolean set(EntityId<T> entityId, String fieldExpr, Object value) {
Query<T> q = q().field(Mapper.ID_KEY).equal(entityId);
UpdateOperations<T> uops = ds.createUpdateOperations(entityClazz);
uops.set(fieldExpr, value);
ds.update(q, uops);
return true;
}
Entities:
@Entity(value = "cw_task")
@Converters(EntityIdConverter.class)
public class CWTask extends SyncableEntity implements Serializable {
@Id
private EntityId<CWTask> id;
private String name;
private String description;
private Date dueDate;
@Indexed
private EntityId<CWProject> projectId;
private List<Key<? extends Assignable>> assignees = new ArrayList<>();
}
Note:
EntityId
basically extends ObjectId
and provides type-safety (I know this breaks after Morphia 1.2 as ObjectId
has been made final
but at this point it’s not relevant).
Assignable
is just a marker interface to restrict the type of entities that a CWTask can be assigned to, ie. CWUser, CWGroup, etc
The error is caused by line 558 of org.mongodb.morphia.mapping.Mapper.toMongoObject(MappedField, MappedClass, Object)
:
if (mapped != null && (Key.class.isAssignableFrom(mapped.getClazz()) || mapped.getEntityAnnotation() != null))
where if we pass in an empty list as field value, being the CWTask.assignees
field of type List<Key>
with no annotation (Key.class.isAssignableFrom(mapped.getClazz())
evals as true
and mapped.getEntityAnnotation() != null
evaluates as false
so getDBRefs()
is then invoked resulting in NPE at line 725
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 21 (9 by maintainers)
Commits related to this issue
- add check for @Reference before checking idOnly fixes #1078 updated logging config so the NPE shows properly pre-fix — committed to MorphiaOrg/morphia by deleted user 8 years ago
- add check for @Reference before checking idOnly fixes #1078 fixes #1087 (cherry picked from commit c006ea5) — committed to MorphiaOrg/morphia by deleted user 8 years ago
- add check for @Reference before checking idOnly Backports #1078 fixes #1108 — committed to MorphiaOrg/morphia by deleted user 8 years ago
I’ve opened https://github.com/mongodb/morphia/issues/1108 to backport this.
That did it. I see the NPE now. I’ll dig in to it. Thanks.