Merge branch 'master' of github.com:SpringSource/spring-data-document
Conflicts: spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MappingTests.java
This commit is contained in:
@@ -44,11 +44,8 @@ public aspect MongoDocumentBacking {
|
|||||||
// ITD to introduce N state to Annotated objects
|
// ITD to introduce N state to Annotated objects
|
||||||
declare parents : (@Entity *) implements DocumentBacked;
|
declare parents : (@Entity *) implements DocumentBacked;
|
||||||
|
|
||||||
// declare @type: DocumentBacked+: @Configurable;
|
// The annotated fields that will be persisted in MongoDB rather than with JPA
|
||||||
|
|
||||||
declare @field: @Document * (@Entity+ *).*:@Transient;
|
declare @field: @Document * (@Entity+ *).*:@Transient;
|
||||||
declare @field: ChangeSet (DocumentBacked+).*:@Transient;
|
|
||||||
declare @field: ChangeSetPersister (DocumentBacked+).*:@Transient;
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Advise user-defined constructors of ChangeSetBacked objects to create a new
|
// Advise user-defined constructors of ChangeSetBacked objects to create a new
|
||||||
@@ -86,27 +83,44 @@ public aspect MongoDocumentBacking {
|
|||||||
LOGGER
|
LOGGER
|
||||||
.debug("User-defined constructor called on DocumentBacked object of class "
|
.debug("User-defined constructor called on DocumentBacked object of class "
|
||||||
+ entity.getClass());
|
+ entity.getClass());
|
||||||
|
// Populate all ITD fields
|
||||||
|
entity.setChangeSet(new HashMapChangeSet());
|
||||||
entity.itdChangeSetPersister = changeSetPersister;
|
entity.itdChangeSetPersister = changeSetPersister;
|
||||||
// Populate all properties
|
entity.itdTransactionSynchronization =
|
||||||
ChangeSet changeSet = new HashMapChangeSet();
|
new DocumentBackedTransactionSynchronization(changeSetPersister, entity);
|
||||||
// changeSetManager.populateChangeSet(changeSet, entity);
|
registerTransactionSynchronization(entity);
|
||||||
entity.setChangeSet(changeSet);
|
}
|
||||||
if (!TransactionSynchronizationManager.isSynchronizationActive()) {
|
|
||||||
throw new InvalidDataAccessResourceUsageException(
|
private static void registerTransactionSynchronization(DocumentBacked entity) {
|
||||||
"No transaction synchronization is active");
|
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||||
|
if (!TransactionSynchronizationManager.getSynchronizations().contains(entity.itdTransactionSynchronization)) {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("Adding transaction synchronization for " + entity.getClass());
|
||||||
|
}
|
||||||
|
TransactionSynchronizationManager.registerSynchronization(entity.itdTransactionSynchronization);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("Transaction synchronization already active for " + entity.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("Transaction syncronization is not active for " + entity.getClass());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TransactionSynchronizationManager
|
|
||||||
.registerSynchronization(new DocumentBackedTransactionSynchronization(
|
|
||||||
changeSetPersister, entity));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// ChangeSet-related mixins
|
// ChangeSet-related mixins
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Introduced field
|
// Introduced field
|
||||||
private ChangeSet DocumentBacked.changeSet;
|
@Transient private ChangeSet DocumentBacked.changeSet;
|
||||||
|
|
||||||
private ChangeSetPersister<?> DocumentBacked.itdChangeSetPersister;
|
@Transient private ChangeSetPersister<?> DocumentBacked.itdChangeSetPersister;
|
||||||
|
|
||||||
|
@Transient private DocumentBackedTransactionSynchronization DocumentBacked.itdTransactionSynchronization;
|
||||||
|
|
||||||
public void DocumentBacked.setChangeSet(ChangeSet cs) {
|
public void DocumentBacked.setChangeSet(ChangeSet cs) {
|
||||||
this.changeSet = cs;
|
this.changeSet = cs;
|
||||||
@@ -126,6 +140,32 @@ public aspect MongoDocumentBacking {
|
|||||||
return itdChangeSetPersister.getPersistentId(this, this.changeSet);
|
return itdChangeSetPersister.getPersistentId(this, this.changeSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lifecycle methods
|
||||||
|
@javax.persistence.PrePersist public void DocumentBacked.prePersist() {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("JPA lifecycle called PrePersist: " + this.getClass().getName() + " :: " + this.get_persistent_id());
|
||||||
|
}
|
||||||
|
registerTransactionSynchronization(this);
|
||||||
|
}
|
||||||
|
@javax.persistence.PreUpdate public void DocumentBacked.preUpdate() {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("JPA lifecycle called PreUpdate: " + this.getClass().getName() + " :: " + this.get_persistent_id());
|
||||||
|
}
|
||||||
|
registerTransactionSynchronization(this);
|
||||||
|
}
|
||||||
|
@javax.persistence.PreRemove public void DocumentBacked.preRemove() {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("JPA lifecycle called PreRemove: " + this.getClass().getName() + " :: " + this.get_persistent_id());
|
||||||
|
}
|
||||||
|
registerTransactionSynchronization(this);
|
||||||
|
}
|
||||||
|
@javax.persistence.PostLoad public void DocumentBacked.postLoad() {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("JPA lifecycle called PostLoad: " + this.getClass().getName() + " :: " + this.get_persistent_id());
|
||||||
|
}
|
||||||
|
registerTransactionSynchronization(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* delegates field reads to the state accessors instance
|
* delegates field reads to the state accessors instance
|
||||||
*/
|
*/
|
||||||
@@ -160,18 +200,6 @@ public aspect MongoDocumentBacking {
|
|||||||
return proceed(entity, newVal);
|
return proceed(entity, newVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * delegates field writes to the state accessors instance
|
|
||||||
// */
|
|
||||||
// Object around(DocumentBacked entity, Object newVal) : entityIdSet(entity, newVal) {
|
|
||||||
// Field f = field(thisJoinPoint);
|
|
||||||
// String propName = f.getName();
|
|
||||||
// LOGGER.trace("SET @Id -> ChangeSet @Id property [" + propName
|
|
||||||
// + "] with value=[" + newVal + "]");
|
|
||||||
// entity.getChangeSet().set("_id", newVal);
|
|
||||||
// return proceed(entity, newVal);
|
|
||||||
// }
|
|
||||||
|
|
||||||
Field field(JoinPoint joinPoint) {
|
Field field(JoinPoint joinPoint) {
|
||||||
FieldSignature fieldSignature = (FieldSignature) joinPoint.getSignature();
|
FieldSignature fieldSignature = (FieldSignature) joinPoint.getSignature();
|
||||||
return fieldSignature.getField();
|
return fieldSignature.getField();
|
||||||
|
|||||||
@@ -13,7 +13,11 @@ import org.springframework.persistence.document.test.Resume;
|
|||||||
import org.springframework.test.annotation.Rollback;
|
import org.springframework.test.annotation.Rollback;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
import org.springframework.transaction.TransactionStatus;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.transaction.support.TransactionCallback;
|
||||||
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import com.mongodb.DBCollection;
|
import com.mongodb.DBCollection;
|
||||||
import com.mongodb.Mongo;
|
import com.mongodb.Mongo;
|
||||||
@@ -30,6 +34,9 @@ public class CrossStoreMongoTests {
|
|||||||
|
|
||||||
private EntityManager entityManager;
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PlatformTransactionManager transactionManager;
|
||||||
|
|
||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
public void setEntityManager(EntityManager entityManager) {
|
public void setEntityManager(EntityManager entityManager) {
|
||||||
this.entityManager = entityManager;
|
this.entityManager = entityManager;
|
||||||
@@ -71,6 +78,7 @@ public class CrossStoreMongoTests {
|
|||||||
Assert.assertEquals("DiMark, DBA, 1990-2000" + "; "
|
Assert.assertEquals("DiMark, DBA, 1990-2000" + "; "
|
||||||
+ "VMware, Developer, 2007-", found.getResume().getJobs());
|
+ "VMware, Developer, 2007-", found.getResume().getJobs());
|
||||||
found.getResume().addJob("SpringDeveloper.com, Consultant, 2005-2006");
|
found.getResume().addJob("SpringDeveloper.com, Consultant, 2005-2006");
|
||||||
|
found.setAge(44);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -87,4 +95,22 @@ public class CrossStoreMongoTests {
|
|||||||
+ "VMware, Developer, 2007-" + "; "
|
+ "VMware, Developer, 2007-" + "; "
|
||||||
+ "SpringDeveloper.com, Consultant, 2005-2006", found.getResume().getJobs());
|
+ "SpringDeveloper.com, Consultant, 2005-2006", found.getResume().getJobs());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMergeJpaEntityWithMongoDocument() {
|
||||||
|
TransactionTemplate txTemplate = new TransactionTemplate(transactionManager);
|
||||||
|
final Person found = entityManager.find(Person.class, 1L);
|
||||||
|
found.setAge(77);
|
||||||
|
found.getResume().addJob("TargetRx, Developer, 2000-2005");
|
||||||
|
txTemplate.execute(new TransactionCallback<Object>() {
|
||||||
|
public Object doInTransaction(TransactionStatus status) {
|
||||||
|
entityManager.merge(found);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
final Person updated = entityManager.find(Person.class, 1L);
|
||||||
|
// assert that the new values are in respective DBs
|
||||||
|
// TODO: during merge we lose the changeset since JPA creates a new persistent instance -
|
||||||
|
// we need to move the existing changeset over somehow
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<name>Spring Data MongoDB Support</name>
|
<name>Spring Data MongoDB Support</name>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<mongo.version>2.3</mongo.version>
|
<mongo.version>2.4</mongo.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|||||||
@@ -24,11 +24,14 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.After;
|
import com.mongodb.Mongo;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
|
import org.springframework.data.document.mongodb.MongoDbUtils;
|
||||||
import org.springframework.data.document.mongodb.MongoTemplate;
|
import org.springframework.data.document.mongodb.MongoTemplate;
|
||||||
import org.springframework.data.document.mongodb.query.Criteria;
|
import org.springframework.data.document.mongodb.query.Criteria;
|
||||||
import org.springframework.data.document.mongodb.query.Query;
|
import org.springframework.data.document.mongodb.query.Query;
|
||||||
@@ -38,28 +41,32 @@ import org.springframework.data.document.mongodb.query.Query;
|
|||||||
*/
|
*/
|
||||||
public class MappingTests {
|
public class MappingTests {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(MongoDbUtils.class);
|
||||||
|
|
||||||
ApplicationContext applicationContext;
|
ApplicationContext applicationContext;
|
||||||
MongoTemplate template;
|
MongoTemplate template;
|
||||||
|
MongoMappingContext mappingContext;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws InterruptedException {
|
public void setUp() throws Exception {
|
||||||
|
Mongo mongo = new Mongo();
|
||||||
|
mongo.getDB("database").getCollection("person").drop();
|
||||||
applicationContext = new ClassPathXmlApplicationContext("/mapping.xml");
|
applicationContext = new ClassPathXmlApplicationContext("/mapping.xml");
|
||||||
template = applicationContext.getBean(MongoTemplate.class);
|
template = applicationContext.getBean(MongoTemplate.class);
|
||||||
}
|
mappingContext = applicationContext.getBean(MongoMappingContext.class);
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() {
|
|
||||||
template.dropCollection("person");
|
|
||||||
template.dropCollection("account");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPersonPojo() {
|
public void testPersonPojo() throws Exception {
|
||||||
|
LOGGER.info("about to create new personpojo");
|
||||||
PersonPojo p = new PersonPojo(12345, "Person", "Pojo");
|
PersonPojo p = new PersonPojo(12345, "Person", "Pojo");
|
||||||
|
LOGGER.info("about to insert");
|
||||||
template.insert(p);
|
template.insert(p);
|
||||||
|
LOGGER.info("done inserting");
|
||||||
assertNotNull(p.getId());
|
assertNotNull(p.getId());
|
||||||
|
|
||||||
List<PersonPojo> result = template.find(new Query(Criteria.where("ssn").is(12345)), PersonPojo.class);
|
List<PersonPojo> result = template.find(
|
||||||
|
new Query(Criteria.where("ssn").is(12345)), PersonPojo.class);
|
||||||
assertThat(result.size(), is(1));
|
assertThat(result.size(), is(1));
|
||||||
assertThat(result.get(0).getSsn(), is(12345));
|
assertThat(result.get(0).getSsn(), is(12345));
|
||||||
}
|
}
|
||||||
@@ -69,7 +76,8 @@ public class MappingTests {
|
|||||||
PersonCustomIdName p = new PersonCustomIdName(123456, "Custom", "Id");
|
PersonCustomIdName p = new PersonCustomIdName(123456, "Custom", "Id");
|
||||||
template.insert(p);
|
template.insert(p);
|
||||||
|
|
||||||
List<PersonCustomIdName> result = template.find(new Query(Criteria.where("ssn").is(123456)), PersonCustomIdName.class);
|
List<PersonCustomIdName> result = template.find(
|
||||||
|
new Query(Criteria.where("ssn").is(123456)), PersonCustomIdName.class);
|
||||||
assertThat(result.size(), is(1));
|
assertThat(result.size(), is(1));
|
||||||
assertNotNull(result.get(0).getCustomId());
|
assertNotNull(result.get(0).getCustomId());
|
||||||
}
|
}
|
||||||
@@ -89,10 +97,12 @@ public class MappingTests {
|
|||||||
template.insert(p);
|
template.insert(p);
|
||||||
assertNotNull(p.getId());
|
assertNotNull(p.getId());
|
||||||
|
|
||||||
List<PersonMapProperty> result = template.find(new Query(Criteria.where("ssn").is(1234567)), PersonMapProperty.class);
|
List<PersonMapProperty> result = template.find(
|
||||||
|
new Query(Criteria.where("ssn").is(1234567)), PersonMapProperty.class);
|
||||||
assertThat(result.size(), is(1));
|
assertThat(result.size(), is(1));
|
||||||
assertThat(result.get(0).getAccounts().size(), is(2));
|
assertThat(result.get(0).getAccounts().size(), is(2));
|
||||||
assertThat(result.get(0).getAccounts().get("checking").getBalance(), is(1000.0f));
|
assertThat(result.get(0).getAccounts().get("checking").getBalance(),
|
||||||
|
is(1000.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -125,7 +135,8 @@ public class MappingTests {
|
|||||||
|
|
||||||
assertNotNull(p.getId());
|
assertNotNull(p.getId());
|
||||||
|
|
||||||
List<Person> result = template.find(new Query(Criteria.where("ssn").is(123456789)), Person.class);
|
List<Person> result = template.find(
|
||||||
|
new Query(Criteria.where("ssn").is(123456789)), Person.class);
|
||||||
assertThat(result.size(), is(1));
|
assertThat(result.size(), is(1));
|
||||||
assertThat(result.get(0).getAddress().getCountry(), is("USA"));
|
assertThat(result.get(0).getAddress().getCountry(), is("USA"));
|
||||||
assertThat(result.get(0).getAccounts(), notNullValue());
|
assertThat(result.get(0).getAccounts(), notNullValue());
|
||||||
@@ -146,13 +157,9 @@ public class MappingTests {
|
|||||||
template.insert("person", p1);
|
template.insert("person", p1);
|
||||||
template.insert("person", p2);
|
template.insert("person", p2);
|
||||||
|
|
||||||
List<Person> result = template.find(new Query(Criteria.where("ssn").is(1234567890)), Person.class);
|
List<Person> result = template.find(
|
||||||
|
new Query(Criteria.where("ssn").is(1234567890)), Person.class);
|
||||||
assertThat(result.size(), is(1));
|
assertThat(result.size(), is(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEvents() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,13 +29,6 @@ public class QueryTests {
|
|||||||
Assert.assertEquals(expected, q.getQueryObject().toString());
|
Assert.assertEquals(expected, q.getQueryObject().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSimpleQueryWithChainedCriteria() {
|
|
||||||
Query q = new Query(where("name").is("Thomas").and("age").lt(80));
|
|
||||||
String expected = "{ \"name\" : \"Thomas\" , \"age\" : { \"$lt\" : 80}}";
|
|
||||||
Assert.assertEquals(expected, q.getQueryObject().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQueryWithNot() {
|
public void testQueryWithNot() {
|
||||||
Query q = new Query(where("name").is("Thomas")).and(where("age").not().mod(10, 0));
|
Query q = new Query(where("name").is("Thomas")).and(where("age").not().mod(10, 0));
|
||||||
@@ -81,6 +74,22 @@ public class QueryTests {
|
|||||||
Assert.assertEquals(expected, q.getQueryObject().toString());
|
Assert.assertEquals(expected, q.getQueryObject().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleQueryWithChainedCriteria() {
|
||||||
|
Query q = new Query(where("name").is("Thomas").and("age").lt(80));
|
||||||
|
String expected = "{ \"name\" : \"Thomas\" , \"age\" : { \"$lt\" : 80}}";
|
||||||
|
Assert.assertEquals(expected, q.getQueryObject().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testComplexQueryWithMultipleChainedCriteria() {
|
||||||
|
Query q1 = new Query(where("name").regex("^T.*").and("age").gt(20).lt(80).and("city").in("Stockholm", "London", "New York"));
|
||||||
|
Query q2 = new Query(where("name").regex("^T.*").and("age").gt(20).lt(80)).and(where("city").in("Stockholm", "London", "New York"));
|
||||||
|
Assert.assertEquals(q1.getQueryObject().toString(), q2.getQueryObject().toString());
|
||||||
|
Query q3 = new Query(where("name").regex("^T.*")).and(where("age").gt(20).lt(80)).and(where("city").in("Stockholm", "London", "New York"));
|
||||||
|
Assert.assertEquals(q1.getQueryObject().toString(), q3.getQueryObject().toString());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQueryWithElemMatch() {
|
public void testQueryWithElemMatch() {
|
||||||
Query q = new Query(where("openingHours").elemMatch(where("dayOfWeek").is("Monday").and("open").lte("1800")));
|
Query q = new Query(where("openingHours").elemMatch(where("dayOfWeek").is("Monday").and("open").lte("1800")));
|
||||||
|
|||||||
Reference in New Issue
Block a user