DATADOC-48 added cross-store support for Mongo->JPA relationships

This commit is contained in:
Thomas Risberg
2011-03-08 23:28:25 -05:00
parent 779d9d6a79
commit 0ad895d6d4
5 changed files with 132 additions and 16 deletions

View File

@@ -53,10 +53,10 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
// System.err.println("Mongo persisted property [" + propertyName + "] :: " + propertyKey + " = " + dbo.get(propertyKey)); // System.err.println("Mongo persisted property [" + propertyName + "] :: " + propertyKey + " = " + dbo.get(propertyKey));
if (propertyKey.startsWith("_")) { if (propertyKey.startsWith("_")) {
// Id or class // Id or class
changeSet.set(propertyName, dbo.get(propertyKey)); changeSet.set(propertyKey, dbo.get(propertyKey));
} else { } else {
//throw new IllegalStateException("Unknown property [" + propertyName + "] found in MongoDB store"); //throw new IllegalStateException("Unknown property [" + propertyName + "] found in MongoDB store");
changeSet.set(propertyName, dbo.get(propertyKey)); changeSet.set(propertyKey, dbo.get(propertyKey));
} }
} }
} catch (MongoException ex) { } catch (MongoException ex) {

View File

@@ -4,28 +4,51 @@ import java.lang.reflect.Field;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.data.document.mongodb.MongoTemplate;
import org.springframework.persistence.OrderedEntityOperations; import org.springframework.persistence.OrderedEntityOperations;
import org.springframework.persistence.RelatedEntity; import org.springframework.persistence.RelatedEntity;
import org.springframework.persistence.support.ChangeSet;
import org.springframework.persistence.support.ChangeSetBacked; import org.springframework.persistence.support.ChangeSetBacked;
import org.springframework.persistence.support.ChangeSetPersister.NotFoundException;
import org.springframework.persistence.support.EntityInstantiator;
import org.springframework.persistence.support.HashMapChangeSet;
import com.mongodb.DB; import com.mongodb.DB;
public class MongoEntityOperations extends OrderedEntityOperations<Object, ChangeSetBacked> { public class MongoEntityOperations extends OrderedEntityOperations<Object, ChangeSetBacked> {
@Autowired @Autowired
private DB mongoDb; private MongoTemplate mongoTemplate;
@Autowired private EntityInstantiator<ChangeSetBacked, ChangeSet> entityInstantiator;
private MongoChangeSetPersister changeSetPersister; private MongoChangeSetPersister changeSetPersister;
public void setEntityInstantiator(EntityInstantiator<ChangeSetBacked, ChangeSet> entityInstantiator) {
this.entityInstantiator = entityInstantiator;
}
@Autowired
public void setChangeSetPersister(MongoChangeSetPersister changeSetPersister) {
this.changeSetPersister = changeSetPersister;
}
@Override @Override
public boolean cacheInEntity() { public boolean cacheInEntity() {
return true; return true;
} }
@Override @Override
public ChangeSetBacked findEntity(Class<ChangeSetBacked> entityClass, Object pk) throws DataAccessException { public ChangeSetBacked findEntity(Class<ChangeSetBacked> entityClass, Object key) throws DataAccessException {
throw new UnsupportedOperationException(); try {
ChangeSet cs = new HashMapChangeSet();
changeSetPersister.getPersistentState(entityClass, key, cs);
return entityInstantiator.createEntityFromState(cs, entityClass);
}
catch (NotFoundException ex) {
return null;
}
} }
@Override @Override

View File

@@ -1,10 +1,14 @@
package org.springframework.data.document.persistence; package org.springframework.data.document.persistence;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.document.mongodb.MongoTemplate; import org.springframework.data.document.mongodb.MongoTemplate;
import org.springframework.persistence.document.test.Account;
import org.springframework.persistence.document.test.MongoPerson; import org.springframework.persistence.document.test.MongoPerson;
import org.springframework.test.annotation.Rollback; import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
@@ -13,6 +17,7 @@ import org.springframework.test.context.transaction.BeforeTransaction;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.mongodb.DBCollection; import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject; import com.mongodb.DBObject;
import com.mongodb.Mongo; import com.mongodb.Mongo;
import com.mongodb.MongoException; import com.mongodb.MongoException;
@@ -26,12 +31,21 @@ public class CrossStoreMongoTests {
@Autowired @Autowired
private MongoTemplate mongoTemplate; private MongoTemplate mongoTemplate;
private EntityManager entityManager;
private String colName = MongoPerson.class.getSimpleName().toLowerCase();
@BeforeTransaction
public void setUp() { @PersistenceContext
DBCollection col = this.mongoTemplate.getCollection(MongoPerson.class.getSimpleName().toLowerCase()); public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
private void clearData() {
DBCollection col = this.mongoTemplate.getCollection(colName);
if (col != null) { if (col != null) {
this.mongoTemplate.dropCollection(MongoPerson.class.getName()); this.mongoTemplate.dropCollection(colName);
} }
} }
@@ -39,6 +53,7 @@ public class CrossStoreMongoTests {
@Transactional @Transactional
@Rollback(false) @Rollback(false)
public void testUserConstructor() { public void testUserConstructor() {
clearData();
int age = 33; int age = 33;
MongoPerson p = new MongoPerson("Thomas", age); MongoPerson p = new MongoPerson("Thomas", age);
Assert.assertEquals(age, p.getAge()); Assert.assertEquals(age, p.getAge());
@@ -49,14 +64,48 @@ public class CrossStoreMongoTests {
@Test @Test
@Transactional @Transactional
public void testInstantiatedFinder() throws MongoException { public void testInstantiatedFinder() throws MongoException {
String key = MongoPerson.class.getSimpleName().toLowerCase(); DBCollection col = this.mongoTemplate.getCollection(colName);
DBCollection col = this.mongoTemplate.getCollection(key);
DBObject dbo = col.findOne(); DBObject dbo = col.findOne();
Object id1 = dbo.get("_id"); Object _id = dbo.get("_id");
MongoPerson found = MongoPerson.findPerson(id1); MongoPerson found = MongoPerson.findPerson(_id);
Assert.assertNotNull(found); Assert.assertNotNull(found);
Assert.assertEquals(id1, found.getId()); Assert.assertEquals(_id, found.getId());
System.out.println("Loaded MongoPerson data: " + found); System.out.println("Loaded MongoPerson data: " + found);
} }
@Test
@Transactional
@Rollback(false)
public void testCreateJpaEntity() {
clearData();
Account a = new Account();
a.setName("My Account");
a.setFriendlyName("My Test Acct.");
a.setBalance(123.45F);
a.setId(2L);
MongoPerson p = new MongoPerson("Jack", 22);
entityManager.persist(a);
p.setAccount(a);
}
@Test
@Transactional
public void testReadJpaEntity() {
DBCollection col = this.mongoTemplate.getCollection(colName);
DBCursor dbc = col.find();
Object _id = null;
for (DBObject dbo : dbc) {
System.out.println(dbo);
if ("Jack".equals(dbo.get("name"))) {
_id = dbo.get("_id");
break;
}
}
System.out.println(_id);
MongoPerson found = MongoPerson.findPerson(_id);
System.out.println(found);
if (found != null)
System.out.println(found.getAccount());
}
} }

View File

@@ -16,6 +16,14 @@ public class Account {
private String whatever; private String whatever;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() { public String getName() {
return name; return name;
} }
@@ -47,6 +55,11 @@ public class Account {
public void setWhatever(String whatever) { public void setWhatever(String whatever) {
this.whatever = whatever; this.whatever = whatever;
} }
@Override
public String toString() {
return "Account [id=" + id + ", name=" + name + ", balance=" + balance
+ ", friendlyName=" + friendlyName + "]";
}
} }

View File

@@ -16,6 +16,37 @@
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/> <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan> </context:component-scan>
<!-- Store spanning config -->
<bean class="org.springframework.persistence.StoreSpanning"
factory-method="aspectOf" >
<property name="mappingValidator">
<bean class="org.springframework.persistence.support.SimpleMappingValidator" />
</property>
</bean>
<bean id="entityOperationsLocator" class="org.springframework.persistence.ChainingEntityOperationsLocator" />
<bean class="org.springframework.persistence.ChainingForeignStoreKeyManagerLocator" />
<bean class="org.springframework.persistence.PresentKeyForeignStoreKeyManager" autowire="constructor" />
<bean class="org.springframework.persistence.GeneratedFieldForeignStoreKeyManager" />
<bean class="org.springframework.persistence.document.MongoEntityOperations" >
<property name="order" value="5" />
<property name="entityInstantiator">
<bean class="org.springframework.persistence.support.ChangeSetConstructorEntityInstantiator" />
</property>
<property name="changeSetPersister" ref="mongoChangeSetPersister" />
</bean>
<bean class="org.springframework.persistence.EntityManagerJpaEntityOperations" />
<bean class="org.springframework.persistence.support.ChangeSetForeignStoreKeyManager">
<property name="fieldDelimiter" value="#"/>
</bean>
<!-- Mongo config --> <!-- Mongo config -->
<bean id="mongo" class="org.springframework.data.document.mongodb.MongoFactoryBean"> <bean id="mongo" class="org.springframework.data.document.mongodb.MongoFactoryBean">
<property name="host" value="localhost" /> <property name="host" value="localhost" />