DATADOC-48 improving the entity id handling for partial entity document persistence
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
Reference in New Issue
Block a user