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

Most upvoted comments

That did it. I see the NPE now. I’ll dig in to it. Thanks.