DATADOC-48 improving the entity id handling for partial entity document persistence

This commit is contained in:
Thomas Risberg
2011-03-28 13:58:15 -04:00
parent 6d8ecf2cbb
commit 615f3f1323
5 changed files with 49 additions and 49 deletions

View File

@@ -26,7 +26,7 @@ public class DocumentBackedTransactionSynchronization implements TransactionSync
@Override @Override
public void afterCommit() { public void afterCommit() {
log.debug("After Commit called for " + entity); log.debug("After Commit called for " + entity);
changeSetPersister.persistState(entity.getClass(), entity.getChangeSet()); changeSetPersister.persistState(entity, entity.getChangeSet());
changeSetTxStatus = 0; changeSetTxStatus = 0;
} }

View File

@@ -1,5 +1,7 @@
package org.springframework.data.persistence.document.mongo; package org.springframework.data.persistence.document.mongo;
import javax.persistence.EntityManagerFactory;
import com.mongodb.BasicDBObject; import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection; import com.mongodb.DBCollection;
import com.mongodb.DBObject; import com.mongodb.DBObject;
@@ -7,6 +9,7 @@ import com.mongodb.MongoException;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.document.mongodb.CollectionCallback; import org.springframework.data.document.mongodb.CollectionCallback;
import org.springframework.data.document.mongodb.MongoTemplate; import org.springframework.data.document.mongodb.MongoTemplate;
@@ -29,14 +32,27 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
private MongoTemplate mongoTemplate; private MongoTemplate mongoTemplate;
private EntityManagerFactory entityManagerFactory;
public void setMongoTemplate(MongoTemplate mongoTemplate) { public void setMongoTemplate(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate; this.mongoTemplate = mongoTemplate;
} }
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
@Override @Override
public void getPersistentState(Class<? extends ChangeSetBacked> entityClass, public void getPersistentState(Class<? extends ChangeSetBacked> entityClass,
Object id, final ChangeSet changeSet) throws DataAccessException, Object id, final ChangeSet changeSet)
NotFoundException { throws DataAccessException, NotFoundException {
if (id == null) {
log.debug("Unable to load MongoDB data for null id");
return;
}
String collName = getCollectionNameForEntity(entityClass); String collName = getCollectionNameForEntity(entityClass);
final DBObject dbk = new BasicDBObject(); final DBObject dbk = new BasicDBObject();
@@ -75,26 +91,20 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
} }
@Override @Override
public Object getPersistentId(Class<? extends ChangeSetBacked> entityClass, public Object getPersistentId(ChangeSetBacked entity, ChangeSet cs) throws DataAccessException {
ChangeSet cs) throws DataAccessException { log.debug("getPersistentId called on " + entity);
log.debug("getPersistentId called on " + entityClass); if (entityManagerFactory == null) {
if (cs == null) { throw new DataAccessResourceFailureException("EntityManagerFactory cannot be null");
return null;
} }
if (cs.getValues().get(ChangeSetPersister.ID_KEY) == null) { Object o = entityManagerFactory.getPersistenceUnitUtil().getIdentifier(entity);
// Not yet persistent
return null;
}
Object o = cs.getValues().get(ChangeSetPersister.ID_KEY);
return o; return o;
} }
@Override @Override
public Object persistState(Class<? extends ChangeSetBacked> entityClass, public Object persistState(ChangeSetBacked entity, ChangeSet cs) throws DataAccessException {
ChangeSet cs) throws DataAccessException {
log.debug("Flush: changeset: " + cs.getValues().keySet()); log.debug("Flush: changeset: " + cs.getValues().keySet());
String collName = getCollectionNameForEntity(entityClass); String collName = getCollectionNameForEntity(entity.getClass());
DBCollection dbc = mongoTemplate.getCollection(collName); DBCollection dbc = mongoTemplate.getCollection(collName);
if (dbc == null) { if (dbc == null) {
dbc = mongoTemplate.createCollection(collName); dbc = mongoTemplate.createCollection(collName);
@@ -103,8 +113,8 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
if (key != null && !key.startsWith("_") && !key.equals(ChangeSetPersister.ID_KEY)) { if (key != null && !key.startsWith("_") && !key.equals(ChangeSetPersister.ID_KEY)) {
Object value = cs.getValues().get(key); Object value = cs.getValues().get(key);
final DBObject dbQuery = new BasicDBObject(); final DBObject dbQuery = new BasicDBObject();
dbQuery.put(ENTITY_ID, cs.getValues().get(ChangeSetPersister.ID_KEY)); dbQuery.put(ENTITY_ID, getPersistentId(entity, cs));
dbQuery.put(ENTITY_CLASS, entityClass.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()); dbQuery.put(ENTITY_FIELD_CLASS, value.getClass().getName());
DBObject dbId = mongoTemplate.execute(collName, DBObject dbId = mongoTemplate.execute(collName,
@@ -134,8 +144,7 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
return 0L; return 0L;
} }
private String getCollectionNameForEntity( private String getCollectionNameForEntity(Class<? extends ChangeSetBacked> entityClass) {
Class<? extends ChangeSetBacked> entityClass) {
return ClassUtils.getQualifiedName(entityClass); return ClassUtils.getQualifiedName(entityClass);
} }

View File

@@ -76,11 +76,11 @@ public aspect MongoDocumentBacking {
args(newVal) && args(newVal) &&
!set(* DocumentBacked.*); !set(* DocumentBacked.*);
protected pointcut entityIdSet(DocumentBacked entity, Object newVal) : // protected pointcut entityIdSet(DocumentBacked entity, Object newVal) :
set(@Id * DocumentBacked+.*) && // set(@Id * DocumentBacked+.*) &&
this(entity) && // this(entity) &&
args(newVal) && // args(newVal) &&
!set(* DocumentBacked.*); // !set(* DocumentBacked.*);
before(DocumentBacked entity) : arbitraryUserConstructorOfChangeSetBackedObject(entity) { before(DocumentBacked entity) : arbitraryUserConstructorOfChangeSetBackedObject(entity) {
LOGGER LOGGER
@@ -118,12 +118,12 @@ public aspect MongoDocumentBacking {
// Flush the entity state to the persistent store // Flush the entity state to the persistent store
public void DocumentBacked.flush() { public void DocumentBacked.flush() {
itdChangeSetPersister.persistState(this.getClass(), this.changeSet); Object id = itdChangeSetPersister.getPersistentId(this, this.changeSet);
itdChangeSetPersister.persistState(this, this.changeSet);
} }
public Object DocumentBacked.get_persistent_id() { public Object DocumentBacked.get_persistent_id() {
return itdChangeSetPersister.getPersistentId(this.getClass(), return itdChangeSetPersister.getPersistentId(this, this.changeSet);
this.changeSet);
} }
/** /**
@@ -160,17 +160,17 @@ public aspect MongoDocumentBacking {
return proceed(entity, newVal); return proceed(entity, newVal);
} }
/** // /**
* delegates field writes to the state accessors instance // * delegates field writes to the state accessors instance
*/ // */
Object around(DocumentBacked entity, Object newVal) : entityIdSet(entity, newVal) { // Object around(DocumentBacked entity, Object newVal) : entityIdSet(entity, newVal) {
Field f = field(thisJoinPoint); // Field f = field(thisJoinPoint);
String propName = f.getName(); // String propName = f.getName();
LOGGER.trace("SET @Id -> ChangeSet @Id property [" + propName // LOGGER.trace("SET @Id -> ChangeSet @Id property [" + propName
+ "] with value=[" + newVal + "]"); // + "] with value=[" + newVal + "]");
entity.getChangeSet().set("_id", newVal); // entity.getChangeSet().set("_id", newVal);
return proceed(entity, newVal); // return proceed(entity, newVal);
} // }
Field field(JoinPoint joinPoint) { Field field(JoinPoint joinPoint) {
FieldSignature fieldSignature = (FieldSignature) joinPoint.getSignature(); FieldSignature fieldSignature = (FieldSignature) joinPoint.getSignature();

View File

@@ -64,11 +64,6 @@ public class CrossStoreMongoTests {
public void testReadJpaToMongoEntityRelationship() { public void testReadJpaToMongoEntityRelationship() {
Person found = entityManager.find(Person.class, 1L); Person found = entityManager.find(Person.class, 1L);
Assert.assertNotNull(found); Assert.assertNotNull(found);
// TODO: This part isn't quite working yet - need to intercept the id
// population from JPA EM
found.setId(found.getId());
Assert.assertEquals(Long.valueOf(1), found.getId()); Assert.assertEquals(Long.valueOf(1), found.getId());
Assert.assertNotNull(found); Assert.assertNotNull(found);
Assert.assertEquals(Long.valueOf(1), found.getId()); Assert.assertEquals(Long.valueOf(1), found.getId());
@@ -84,11 +79,6 @@ public class CrossStoreMongoTests {
public void testUpdatedJpaToMongoEntityRelationship() { public void testUpdatedJpaToMongoEntityRelationship() {
Person found = entityManager.find(Person.class, 1L); Person found = entityManager.find(Person.class, 1L);
Assert.assertNotNull(found); Assert.assertNotNull(found);
// TODO: This part isn't quite working yet - need to intercept the id
// population from JPA EM
found.setId(found.getId());
Assert.assertEquals(Long.valueOf(1), found.getId()); Assert.assertEquals(Long.valueOf(1), found.getId());
Assert.assertNotNull(found); Assert.assertNotNull(found);
Assert.assertEquals(Long.valueOf(1), found.getId()); Assert.assertEquals(Long.valueOf(1), found.getId());

View File

@@ -36,6 +36,7 @@
<bean id="mongoChangeSetPersister" <bean id="mongoChangeSetPersister"
class="org.springframework.data.persistence.document.mongo.MongoChangeSetPersister"> class="org.springframework.data.persistence.document.mongo.MongoChangeSetPersister">
<property name="mongoTemplate" ref="mongoTemplate"/> <property name="mongoTemplate" ref="mongoTemplate"/>
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean> </bean>
<jdbc:embedded-database id="dataSource" type="HSQL"> <jdbc:embedded-database id="dataSource" type="HSQL">