Issue 406 in morphia: UpdateOperations with isolated() do not honor DatastoreImpl update with createIfMissing behavior

16 views
Skip to first unread message

mor...@googlecode.com

unread,
Apr 30, 2012, 3:00:46 PM4/30/12
to morphia...@googlegroups.com
Status: New
Owner: ----
Labels: Type-Defect Priority-Low

New issue 406 by jaronsampson: UpdateOperations with isolated() do not
honor DatastoreImpl update with createIfMissing behavior
http://code.google.com/p/morphia/issues/detail?id=406

morphia 0.99 / morphia logging 0.99 / morphia validation 0.99
mongo-java-driver-2.7.3 / mongodb-osx-x86_64-2.0.4

The expected upsert behavior using update(query, ops, createIfMissing=true)
fails to work when isolated() is used in the UpdateOperations. Instead the
query always updates existing record after creating an initial record.
Removing isolated() allows this method to be used with the expected upsert
behavior. Also, using findAndModify(query, ops, false, true) upserts
correctly with isolated() left in the ops.

The main difference I can see involves a block in DatastoreImpl, where it
is calling disableValidation on the query used in the update. The
combination of isolated and update seems to result in the query matching
all existing documents in the collection and updating that result set. I
believe I verified this by adding a second document to the collection via
the CLI, and running the morphia update method again: all documents in the
collection ended up with the update calls set operations from my morphia
code.

@SuppressWarnings("rawtypes")
private <T> UpdateResults<T> update(Query<T> query,
UpdateOperations ops, boolean createIfMissing, boolean multi, WriteConcern
wc) {
DBObject u = ((UpdateOpsImpl) ops).getOps();
if (((UpdateOpsImpl) ops).isIsolated()) {
Query<T> q = query.clone();
q.disableValidation().filter("$atomic", true);
return update(q, u, createIfMissing, multi, wc);
}
return update(query, u, createIfMissing, multi, wc);
}

compared to this block:

public <T> T findAndModify(Query<T> query, UpdateOperations<T> ops,
boolean oldVersion, boolean createIfMissing) {
QueryImpl<T> qi = (QueryImpl<T>) query;

DBCollection dbColl = qi.getCollection();
//TODO remove this after testing.
if(dbColl == null)
dbColl = getCollection(qi.getEntityClass());

if (log.isTraceEnabled())
log.info("Executing findAndModify(" +
dbColl.getName() + ") with update ");

DBObject res = dbColl.findAndModify(qi.getQueryObject(),

qi.getFieldsObject(),

qi.getSortObject(),

false,

((UpdateOpsImpl<T>)
ops).getOps(), !oldVersion,

createIfMissing);

if (res == null)
return null;
else
return (T) mapr.fromDBObject(qi.getEntityClass(),
res, createCache());
}

...which sends the UpdateOperations from UpdateOpsImpl settings up to the
driver without changing the QueryImpl fields through disableValidation().

Note: I have not stress tested this to see if either method actually
isolates the update operation or not.

Thanks,
Jaron Sampson


Attachments:
morphia.issuereport.createIfMissing.isolated.txt 4.7 KB

mor...@googlecode.com

unread,
Apr 30, 2012, 3:03:28 PM4/30/12
to morphia...@googlegroups.com

Comment #1 on issue 406 by jaronsampson: UpdateOperations with isolated()
do not honor DatastoreImpl update with createIfMissing behavior
http://code.google.com/p/morphia/issues/detail?id=406

Clarification: <snip>"Instead the query always updates existing record
after creating an initial record. " </snip>

If the collection was empty the first time the update method is executed,
it inserts one record. All subsequent calls update that record with the
update operations specified).

mor...@googlecode.com

unread,
Feb 23, 2015, 8:23:29 PM2/23/15
to morphia...@googlegroups.com

Comment #2 on issue 406 by justin....@10gen.com: UpdateOperations with
isolated() do not honor DatastoreImpl update with createIfMissing behavior
https://code.google.com/p/morphia/issues/detail?id=406

Can you post a test case on https://github.com/mongodb/morphia/issues/406.
I'd love to isolate and fix this but i'm not sure what exactly the problem
is. But given that no one else has said anything like this, I'm leaning
toward closing this issue for now.

--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
Reply all
Reply to author
Forward
0 new messages