DATADOC-48 simplified cross-store persistence of @Document annotated fields in a JPA entity

This commit is contained in:
Thomas Risberg
2011-03-23 07:44:52 -04:00
parent 74df4349ed
commit f21f25fb52
17 changed files with 548 additions and 575 deletions

View File

@@ -3,14 +3,11 @@ package org.springframework.data.document.persistence;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import com.mongodb.*;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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.Person;
import org.springframework.persistence.document.test.Resume;
import org.springframework.test.annotation.Rollback;
@@ -18,6 +15,9 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import com.mongodb.DBCollection;
import com.mongodb.Mongo;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/META-INF/spring/applicationContext.xml")
public class CrossStoreMongoTests {
@@ -30,8 +30,6 @@ public class CrossStoreMongoTests {
private EntityManager entityManager;
private String colName = MongoPerson.class.getSimpleName().toLowerCase();
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
@@ -45,65 +43,6 @@ public class CrossStoreMongoTests {
}
}
@Test
@Transactional
@Rollback(false)
public void testUserConstructor() {
clearData(colName);
int age = 33;
MongoPerson p = new MongoPerson("Thomas", age);
Assert.assertEquals(age, p.getAge());
p.birthday();
Assert.assertEquals(1 + age, p.getAge());
}
@Test
@Transactional
public void testInstantiatedFinder() throws MongoException {
DBCollection col = this.mongoTemplate.getCollection(colName);
DBObject dbo = col.findOne();
Object _id = dbo.get("_id");
MongoPerson found = MongoPerson.findPerson(_id);
Assert.assertNotNull(found);
Assert.assertEquals(_id, found.getId());
System.out.println("Loaded MongoPerson data: " + found);
}
@Test
@Transactional
@Rollback(false)
public void testCreateMongoToJpaEntityRelationship() {
clearData(colName);
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 testReadMongoToJpaEntityRelationship() {
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());
}
@Test
@Transactional
@Rollback(false)
@@ -122,12 +61,20 @@ public class CrossStoreMongoTests {
@Test
@Transactional
@Rollback(false)
public void testReadJpaToMongoEntityRelationship() {
Person found = entityManager.find(Person.class, 1L);
System.out.println(found);
// TODO: This part isn't working yet - there is no reference to the Momgo _id stored in the db
// if (found != null)
// System.out.println(found.getResume());
}
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.assertNotNull(found);
Assert.assertEquals(Long.valueOf(1), found.getId());
Assert.assertNotNull(found.getResume());
Assert.assertEquals("DiMark, DBA, 1990-2000" + "; " + "VMware, Developer, 2007-",
found.getResume().getJobs());
found.getResume().addJob("Developer, SpringDeveloper.com, 2005-2006");
}
}

View File

@@ -1,63 +0,0 @@
package org.springframework.persistence.document.test;
import org.springframework.persistence.RelatedEntity;
import org.springframework.persistence.document.DocumentEntity;
@DocumentEntity
public class MongoPerson {
// TODO only public because of AspectJ bug
public String name;
public int age;
public java.util.Date birthDate;
// TODO only public to check weaving bug--
// seems to work whereas private didn't
@RelatedEntity
public Account account;
public MongoPerson(String name, int age) {
this.name = name;
this.age = age;
this.birthDate = new java.util.Date();
}
public void birthday() {
++age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public java.util.Date getBirthDate() {
return birthDate;
}
public void setBirthDate(java.util.Date birthDate) {
this.birthDate = birthDate;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
}

View File

@@ -1,54 +0,0 @@
package org.springframework.persistence.document.test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.persistence.support.*;
import org.springframework.persistence.support.ChangeSetPersister.NotFoundException;
/**
* EXAMPLE OF CODE THAT SHOULD BE GENERATED BY ROO BESIDES EACH MONGOENTITY CLASS
*
* Note: Combines X_Roo_Entity with X_Roo_Finder, as
* we need only a single aspect for entities.
*
* @author Thomas Risberg
*
*/
privileged aspect MongoPerson_Roo_Mongo_Entity {
private static ChangeSetPersister<Object> changeSetPersister() {
return new MongoConfigurationHolder().changeSetConfig.getChangeSetPersister();
}
private static ChangeSetSynchronizer<ChangeSetBacked> changeSetManager() {
return new MongoConfigurationHolder().changeSetConfig.getChangeSetManager();
}
@Configurable
public static class MongoConfigurationHolder {
@Autowired
@Qualifier("mongoChangeSetConfiguration")
public ChangeSetConfiguration<Object> changeSetConfig;
}
/**
* Add constructor that takes ChangeSet.
* @param ChangeSet
*/
public MongoPerson.new(ChangeSet cs) {
super();
setChangeSet(cs);
}
public static MongoPerson MongoPerson.findPerson(Object id) {
ChangeSet rv = new HashMapChangeSet();
try {
changeSetPersister().getPersistentState(MongoPerson.class, id, rv);
return new MongoPerson(rv);
} catch (NotFoundException ex) {
return null;
}
}
}

View File

@@ -3,7 +3,7 @@ package org.springframework.persistence.document.test;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.springframework.persistence.RelatedEntity;
import org.springframework.data.document.mongodb.mapping.Document;
@Entity
public class Person {
@@ -17,8 +17,7 @@ public class Person {
private java.util.Date birthDate;
// @Document // need to decide what the annotation here should be
@RelatedEntity
@Document
public Resume resume;
public Person() {

View File

@@ -1,8 +1,6 @@
package org.springframework.persistence.document.test;
import org.springframework.persistence.document.DocumentEntity;
@DocumentEntity
//@DocumentEntity
public class Resume {
private String education = "";

View File

@@ -12,41 +12,9 @@
<context:spring-configured/>
<context:component-scan base-package="org.springframework.persistence.test">
<context:exclude-filter expression=".*_Roo_.*" type="regex"/>
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</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 -->
<bean id="mongo" class="org.springframework.data.document.mongodb.MongoFactoryBean">
<property name="host" value="localhost"/>
@@ -61,19 +29,14 @@
<bean class="org.springframework.data.document.mongodb.MongoExceptionTranslator"/>
<!-- Mongo aspect config -->
<bean class="org.springframework.persistence.document.MongoDocumentBacking"
<bean class="org.springframework.data.persistence.document.mongo.MongoDocumentBacking"
factory-method="aspectOf">
<property name="changeSetConfiguration" ref="mongoChangeSetConfiguration"/>
</bean>
<bean id="mongoChangeSetPersister" class="org.springframework.persistence.document.MongoChangeSetPersister"/>
<bean id="mongoChangeSetSynchronizer"
class="org.springframework.persistence.support.SimpleReflectiveChangeSetSynchronizer"/>
<bean id="mongoChangeSetConfiguration" class="org.springframework.persistence.support.ChangeSetConfiguration">
<property name="changeSetPersister" ref="mongoChangeSetPersister"/>
<property name="changeSetManager" ref="mongoChangeSetSynchronizer"/>
</bean>
<!-- Needed for ChangeSet persistence -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"/>
<bean id="mongoChangeSetPersister"
class="org.springframework.data.persistence.document.mongo.MongoChangeSetPersister">
<property name="mongoTemplate" ref="mongoTemplate"/>
</bean>
<jdbc:embedded-database id="dataSource" type="HSQL">
</jdbc:embedded-database>

View File

@@ -5,8 +5,7 @@ log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.category.org.springframework=INFO
log4j.category.org.springframework.data=DEBUG
log4j.category.org.springframework.persistence=DEBUG
log4j.category.org.springframework.data=TRACE
log4j.category.org.hibernate.SQL=DEBUG
# for debugging datasource initialization