DATADOC-48 added support for removing any related Mongo documents when entities are removed

This commit is contained in:
Thomas Risberg
2011-03-31 17:11:08 -04:00
parent a13579f487
commit f4f9eac03a
3 changed files with 62 additions and 28 deletions

View File

@@ -107,7 +107,9 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
return 0L;
}
log.debug("Flush: changeset: " + cs.getValues().keySet());
if (log.isDebugEnabled()) {
log.debug("Flush: changeset: " + cs.getValues());
}
String collName = getCollectionNameForEntity(entity.getClass());
DBCollection dbc = mongoTemplate.getCollection(collName);
@@ -121,7 +123,6 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
dbQuery.put(ENTITY_ID, getPersistentId(entity, cs));
dbQuery.put(ENTITY_CLASS, entity.getClass().getName());
dbQuery.put(ENTITY_FIELD_NAME, key);
dbQuery.put(ENTITY_FIELD_CLASS, value.getClass().getName());
DBObject dbId = mongoTemplate.execute(collName,
new CollectionCallback<DBObject>() {
@Override
@@ -130,20 +131,39 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
return collection.findOne(dbQuery);
}
});
final DBObject dbDoc = new BasicDBObject();
mongoTemplate.getConverter().write(value, dbDoc);
dbDoc.putAll(dbQuery);
if (dbId != null) {
dbDoc.put("_id", dbId.get("_id"));
}
mongoTemplate.execute(collName, new CollectionCallback<Object>() {
@Override
public Object doInCollection(DBCollection collection)
throws MongoException, DataAccessException {
collection.save(dbDoc);
return null;
if (value == null) {
if (log.isDebugEnabled()) {
log.debug("Flush: removing: " + dbQuery);
}
});
mongoTemplate.execute(collName, new CollectionCallback<Object>() {
@Override
public Object doInCollection(DBCollection collection)
throws MongoException, DataAccessException {
collection.remove(dbQuery);
return null;
}
});
}
else {
final DBObject dbDoc = new BasicDBObject();
dbDoc.putAll(dbQuery);
if (log.isDebugEnabled()) {
log.debug("Flush: saving: " + dbQuery);
}
mongoTemplate.getConverter().write(value, dbDoc);
dbDoc.put(ENTITY_FIELD_CLASS, value.getClass().getName());
if (dbId != null) {
dbDoc.put("_id", dbId.get("_id"));
}
mongoTemplate.execute(collName, new CollectionCallback<Object>() {
@Override
public Object doInCollection(DBCollection collection)
throws MongoException, DataAccessException {
collection.save(dbDoc);
return null;
}
});
}
}
}
return 0L;

View File

@@ -12,11 +12,13 @@ import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.FieldSignature;
import org.springframework.dao.DataAccessException;
import org.springframework.data.document.mongodb.mapping.Document;
import org.springframework.data.persistence.document.DocumentBacked;
import org.springframework.data.persistence.document.DocumentBackedTransactionSynchronization;
import org.springframework.data.persistence.ChangeSet;
import org.springframework.data.persistence.ChangeSetBacked;
import org.springframework.data.persistence.ChangeSetPersister;
import org.springframework.data.persistence.ChangeSetPersister.NotFoundException;
import org.springframework.data.persistence.HashMapChangeSet;
@@ -97,10 +99,22 @@ public aspect MongoDocumentBacking {
// clear changeSet from removed entity
Object around(EntityManager em, Object entity) : entityManagerRemove(em, entity) {
if (entity instanceof DocumentBacked) {
Map<String,Object> cs = ((DocumentBacked)entity).getChangeSet().getValues();
for (String key : cs.keySet()) {
cs.put(key, null);
ChangeSet nulledCs = new HashMapChangeSet();
DocumentBacked documentEntity = (DocumentBacked) entity;
@SuppressWarnings("unchecked")
ChangeSetPersister<Object> changeSetPersister = (ChangeSetPersister<Object>)documentEntity.itdChangeSetPersister;
try {
changeSetPersister.getPersistentState(
documentEntity.getClass(),
documentEntity.get_persistent_id(),
documentEntity.getChangeSet());
}
catch (DataAccessException e) {}
catch (NotFoundException e) {}
for (String key : ((DocumentBacked)entity).getChangeSet().getValues().keySet()) {
nulledCs.set(key, null);
}
((DocumentBacked)entity).setChangeSet(nulledCs);
}
return proceed(em, entity);
}

View File

@@ -20,15 +20,12 @@ import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import com.mongodb.DBCollection;
import com.mongodb.Mongo;
import com.mongodb.DBObject;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/META-INF/spring/applicationContext.xml")
public class CrossStoreMongoTests {
@Autowired
private Mongo mongo;
@Autowired
private MongoTemplate mongoTemplate;
@@ -137,15 +134,18 @@ public class CrossStoreMongoTests {
txTemplate.execute(new TransactionCallback<Person>() {
public Person doInTransaction(TransactionStatus status) {
final Person found2 = entityManager.find(Person.class, 2L);
final Person found3 = entityManager.find(Person.class, 3L);
entityManager.remove(found2);
return null;
}
});
final Person found2 = entityManager.find(Person.class, 2L);
final Person found3 = entityManager.find(Person.class, 3L);
// TODO: assert that any documents for Person 2 are gone
// System.out.println(found2);
// System.out.println(found3);
boolean weFound3 = false;
for (DBObject dbo : this.mongoTemplate.getCollection(Person.class.getName()).find()) {
Assert.assertTrue(!dbo.get("_entity_id").equals(2L));
if (dbo.get("_entity_id").equals(3L)) {
weFound3 = true;
}
}
Assert.assertTrue(weFound3);
}
}