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; return 0L;
} }
log.debug("Flush: changeset: " + cs.getValues().keySet()); if (log.isDebugEnabled()) {
log.debug("Flush: changeset: " + cs.getValues());
}
String collName = getCollectionNameForEntity(entity.getClass()); String collName = getCollectionNameForEntity(entity.getClass());
DBCollection dbc = mongoTemplate.getCollection(collName); 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_ID, getPersistentId(entity, cs));
dbQuery.put(ENTITY_CLASS, entity.getClass().getName()); dbQuery.put(ENTITY_CLASS, entity.getClass().getName());
dbQuery.put(ENTITY_FIELD_NAME, key); dbQuery.put(ENTITY_FIELD_NAME, key);
dbQuery.put(ENTITY_FIELD_CLASS, value.getClass().getName());
DBObject dbId = mongoTemplate.execute(collName, DBObject dbId = mongoTemplate.execute(collName,
new CollectionCallback<DBObject>() { new CollectionCallback<DBObject>() {
@Override @Override
@@ -130,9 +131,27 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
return collection.findOne(dbQuery); return collection.findOne(dbQuery);
} }
}); });
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(); final DBObject dbDoc = new BasicDBObject();
mongoTemplate.getConverter().write(value, dbDoc);
dbDoc.putAll(dbQuery); 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) { if (dbId != null) {
dbDoc.put("_id", dbId.get("_id")); dbDoc.put("_id", dbId.get("_id"));
} }
@@ -146,6 +165,7 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
}); });
} }
} }
}
return 0L; return 0L;
} }

View File

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

View File

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