use of org.mongodb.morphia.mapping.MappedField in project morphia by mongodb.
the class DatastoreImpl method tryVersionedUpdate.
private <T> WriteResult tryVersionedUpdate(final DBCollection dbColl, final T entity, final DBObject dbObj, final Object idValue, final InsertOptions options, final MappedClass mc) {
WriteResult wr;
if (mc.getFieldsAnnotatedWith(Version.class).isEmpty()) {
return null;
}
final MappedField mfVersion = mc.getMappedVersionField();
final String versionKeyName = mfVersion.getNameToStore();
Long oldVersion = (Long) mfVersion.getFieldValue(entity);
long newVersion = nextValue(oldVersion);
dbObj.put(versionKeyName, newVersion);
if (idValue != null && newVersion != 1) {
final Query<?> query = find(dbColl.getName(), entity.getClass()).disableValidation().filter(Mapper.ID_KEY, idValue).enableValidation().filter(versionKeyName, oldVersion);
final UpdateResults res = update(query, dbObj, new UpdateOptions().bypassDocumentValidation(options.getBypassDocumentValidation()).writeConcern(options.getWriteConcern()));
wr = res.getWriteResult();
if (res.getUpdatedCount() != 1) {
throw new ConcurrentModificationException(format("Entity of class %s (id='%s',version='%d') was concurrently updated.", entity.getClass().getName(), idValue, oldVersion));
}
} else {
wr = saveDocument(dbColl, dbObj, options);
}
return wr;
}
use of org.mongodb.morphia.mapping.MappedField in project morphia by mongodb.
the class DatastoreImpl method update.
@Override
public <T> UpdateResults update(final Query<T> query, final UpdateOperations<T> operations, final UpdateOptions options) {
DBCollection dbColl = query.getCollection();
// TODO remove this after testing.
if (dbColl == null) {
dbColl = getCollection(query.getEntityClass());
}
final MappedClass mc = getMapper().getMappedClass(query.getEntityClass());
final List<MappedField> fields = mc.getFieldsAnnotatedWith(Version.class);
DBObject queryObject = query.getQueryObject();
if (operations.isIsolated()) {
queryObject.put("$isolated", true);
}
if (!fields.isEmpty()) {
operations.inc(fields.get(0).getNameToStore(), 1);
}
final BasicDBObject update = (BasicDBObject) ((UpdateOpsImpl) operations).getOps();
if (LOG.isTraceEnabled()) {
LOG.trace(format("Executing update(%s) for query: %s, ops: %s, multi: %s, upsert: %s", dbColl.getName(), queryObject, update, options.isMulti(), options.isUpsert()));
}
return new UpdateResults(dbColl.update(queryObject, update, enforceWriteConcern(options, query.getEntityClass()).getOptions()));
}
use of org.mongodb.morphia.mapping.MappedField in project morphia by mongodb.
the class DatastoreImpl method update.
@Override
@SuppressWarnings("unchecked")
public <T> UpdateResults update(final T entity, final UpdateOperations<T> operations) {
if (entity instanceof Query) {
return update((Query<T>) entity, operations);
}
final MappedClass mc = mapper.getMappedClass(entity);
Query<?> query = createQuery(mapper.getMappedClass(entity).getClazz()).disableValidation().filter(Mapper.ID_KEY, mapper.getId(entity));
if (!mc.getFieldsAnnotatedWith(Version.class).isEmpty()) {
final MappedField field = mc.getFieldsAnnotatedWith(Version.class).get(0);
query.field(field.getNameToStore()).equal(field.getFieldValue(entity));
}
return update((Query<T>) query, operations);
}
use of org.mongodb.morphia.mapping.MappedField in project morphia by mongodb.
the class DatastoreImpl method update.
@SuppressWarnings("unchecked")
private <T> UpdateResults update(final Query<T> query, final DBObject update, final UpdateOptions options) {
DBCollection dbColl = query.getCollection();
// TODO remove this after testing.
if (dbColl == null) {
dbColl = getCollection(query.getEntityClass());
}
if (query.getSortObject() != null && query.getSortObject().keySet() != null && !query.getSortObject().keySet().isEmpty()) {
throw new QueryException("sorting is not allowed for updates.");
}
if (query.getOffset() > 0) {
throw new QueryException("a query offset is not allowed for updates.");
}
if (query.getLimit() > 0) {
throw new QueryException("a query limit is not allowed for updates.");
}
DBObject queryObject = query.getQueryObject();
final MappedClass mc = getMapper().getMappedClass(query.getEntityClass());
final List<MappedField> fields = mc.getFieldsAnnotatedWith(Version.class);
if (!fields.isEmpty()) {
final MappedField versionMF = fields.get(0);
if (update.get(versionMF.getNameToStore()) == null) {
if (!update.containsField("$inc")) {
update.put("$inc", new BasicDBObject(versionMF.getNameToStore(), 1));
} else {
((Map<String, Object>) (update.get("$inc"))).put(versionMF.getNameToStore(), 1);
}
}
}
if (LOG.isTraceEnabled()) {
LOG.trace(format("Executing update(%s) for query: %s, ops: %s, multi: %s, upsert: %s", dbColl.getName(), queryObject, update, options.isMulti(), options.isUpsert()));
}
return new UpdateResults(dbColl.update(queryObject, update, enforceWriteConcern(options, query.getEntityClass()).getOptions()));
}
use of org.mongodb.morphia.mapping.MappedField in project morphia by mongodb.
the class IndexHelper method findField.
String findField(final MappedClass mc, final IndexOptions options, final List<String> path) {
String segment = path.get(0);
if (segment.equals("$**")) {
return segment;
}
MappedField mf = mc.getMappedField(segment);
if (mf == null) {
mf = mc.getMappedFieldByJavaField(segment);
}
if (mf == null && mc.isInterface()) {
for (final MappedClass mappedClass : mapper.getSubTypes(mc)) {
try {
return findField(mappedClass, options, new ArrayList<String>(path));
} catch (MappingException e) {
// try the next one
}
}
}
String namePath;
if (mf != null) {
namePath = mf.getNameToStore();
} else {
if (!options.disableValidation()) {
throw pathFail(mc, path);
} else {
return join(path, '.');
}
}
if (path.size() > 1) {
try {
Class concreteType = !mf.isSingleValue() ? mf.getSubClass() : mf.getConcreteType();
namePath += "." + findField(mapper.getMappedClass(concreteType), options, path.subList(1, path.size()));
} catch (MappingException e) {
if (!options.disableValidation()) {
throw pathFail(mc, path);
} else {
return join(path, '.');
}
}
}
return namePath;
}
Aggregations