Add MongoDB example for linking documents.

Closes #631
This commit is contained in:
Christoph Strobl
2021-10-04 13:45:37 +02:00
committed by Greg L. Turnquist
parent a171e33444
commit af124509c8
21 changed files with 1029 additions and 0 deletions

View File

@@ -72,6 +72,7 @@ Local Elasticsearch instance must be running to run the tests.
* `gridfs` - Example project showing usage of gridFS with MongoDB.
* `jmolecules` - Example of Spring Data MongoDB working with a jMolecules based domain model.
* `kotlin` - Example for using [Kotlin](https://kotlinlang.org/) with MongoDB.
* `linking` - Example demonstrating possibilities for linking documents.
* `query-by-example` - Example project showing usage of Query by Example with MongoDB.
* `querydsl` - Example project showing imperative and reactive [Querydsl](https://github.com/querydsl/querydsl) support for MongoDB.
* `reactive` - Example project to show reactive template and repository support.

62
mongodb/linking/README.md Normal file
View File

@@ -0,0 +1,62 @@
# Spring Data MongoDB - Linking Example
This project contains examples for linking Documents using:
* `@DBRef`
* `@DocumentReference`
## DBRef
Use MongoDB native `dbref` for storing associations.
```java
class Manager {
@DBRef
private List<Employee> employees;
// ...
}
```
## DocumentReference
Link documents via their id.
```java
class Manager {
@DocumentReference
private List<Employee> employees;
// ...
}
```
Link documents via a (non _id_) property.
```java
class Manager {
@DocumentReference(lookup = "{ 'name' : ?#{#target} }")
private List<Employee> employees;
// ...
}
```
Link documents JPA style.
```java
class Manager {
@ReadOnlyProperty
@DocumentReference(lookup="{'managerId':?#{#self._id} }")
private List<Employee> employees;
// ...
}
```
----
For more information please refer to the [Reference Documentation](https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mapping-usage-references).

15
mongodb/linking/pom.xml Normal file
View File

@@ -0,0 +1,15 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-data-mongodb-linking-example</artifactId>
<name>Spring Data MongoDB - Linking Example</name>
<parent>
<groupId>org.springframework.data.examples</groupId>
<artifactId>spring-data-mongodb-examples</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</parent>
</project>

View File

@@ -0,0 +1,24 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.dbref;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Christoph Strobl
*/
@SpringBootApplication
class ApplicationConfiguration {}

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.dbref;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DBRef;
/**
* @author Christoph Strobl
*/
class Employee {
@Id
private String id;
private String name;
@DBRef(lazy = true) // lazy to avoid stackoverflow on load
private Manager manager;
public Employee() {
}
public Employee(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Manager getManager() {
return manager;
}
public void setManager(Manager manager) {
this.manager = manager;
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.dbref;
import java.util.List;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DBRef;
/**
* @author Christoph Strobl
*/
class Manager {
@Id //
private String id;
private String name;
@DBRef //
private List<Employee> employees;
public Manager() {
}
public Manager(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.docref.jpastyle;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Christoph Strobl
*/
@SpringBootApplication
class ApplicationConfiguration {
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.docref.jpastyle;
import org.springframework.data.annotation.Id;
/**
* @author Christoph Strobl
*/
class Employee {
@Id
private String id;
private String name;
/**
* Only hold the id of the manager to link to it.
*/
private String managerId;
public Employee() {
}
public Employee(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getManagerId() {
return managerId;
}
public void setManagerId(String managerId) {
this.managerId = managerId;
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.docref.jpastyle;
import java.util.List;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.ReadOnlyProperty;
import org.springframework.data.mongodb.core.mapping.DocumentReference;
/**
* @author Christoph Strobl
*/
class Manager {
@Id //
private String id;
private String name;
/**
* Uses the {@literal this.id} to look up documents in the {@literal employee} collection
* that have a matching {@literal managerId} field value.
*/
@ReadOnlyProperty
@DocumentReference(lookup="{'managerId':?#{#self._id} }")
private List<Employee> employees;
public Manager() {
}
public Manager(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.docref.query;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Christoph Strobl
*/
@SpringBootApplication
class ApplicationConfiguration {}

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.docref.query;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DocumentReference;
/**
* @author Christoph Strobl
*/
class Employee {
@Id
private String id;
private String name;
@DocumentReference(lazy = true) // lazy to avoid stackoverflow on load
private Manager manager;
public Employee() {
}
public Employee(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Manager getManager() {
return manager;
}
public void setManager(Manager manager) {
this.manager = manager;
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.docref.query;
import java.util.List;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DocumentReference;
/**
* @author Christoph Strobl
*/
class Manager {
@Id //
private String id;
private String name;
/**
* Uses the value stored in the {@literal employees} field of the {@literal manager} document to look up
* documents in the {@literal employee} collection that have a matching {@literal name} field value.
*/
@DocumentReference(lookup = "{ 'name' : ?#{#target} }") //
private List<Employee> employees;
public Manager() {
}
public Manager(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.docref.simple;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Christoph Strobl
*/
@SpringBootApplication
class ApplicationConfiguration {}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.docref.simple;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.DocumentReference;
/**
* @author Christoph Strobl
*/
class Employee {
@Id
private String id;
private String name;
@DocumentReference(lazy = true) // lazy to avoid stackoverflow on load
private Manager manager;
public Employee() {
}
public Employee(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Manager getManager() {
return manager;
}
public void setManager(Manager manager) {
this.manager = manager;
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.docref.simple;
import java.util.List;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DocumentReference;
/**
* @author Christoph Strobl
*/
class Manager {
@Id //
private String id;
private String name;
/**
* Uses the value stored in the {@literal employees} field of the {@literal manager} document to look up
* documents in the {@literal employee} collection that have a matching {@literal _id} field value.
*/
@DocumentReference //
private List<Employee> employees;
public Manager() {
}
public Manager(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.dbref;
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import java.util.List;
import com.mongodb.DBRef;
import org.bson.Document;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Update;
/**
* @author Christoph Strobl
*/
@DataMongoTest
public class DBRefTests {
@Autowired MongoOperations operations;
@Test
void saveAndLoadDbRef() {
Manager manager = new Manager("jabba-the-hutt", "jabba");
operations.save(manager);
Employee employee1 = new Employee("greedo-tetsu-jr", "greedo");
employee1.setManager(manager);
operations.save(employee1);
operations.update(Manager.class) //
.matching(where("id").is(manager.getId())) //
.apply(new Update().push("employees").value(employee1)) //
.first();
Employee employee2 = new Employee("boba-fett", "boba");
employee2.setManager(manager);
operations.save(employee2);
operations.update(Manager.class) //
.matching(where("id").is(manager.getId())) //
.apply(new Update().push("employees").value(employee2)) //
.first();
operations.execute(Manager.class, collection -> {
Document rawManager = collection.find(new Document("_id", manager.getId())).first();
assertThat(rawManager.get("employees", List.class)) //
.containsExactly( //
new DBRef("employee", "greedo-tetsu-jr"), //
new DBRef("employee", "boba-fett") //
);
return "OK";
});
Manager loaded = operations.query(Manager.class)
.matching(where("id").is(manager.getId()))
.firstValue();
assertThat(loaded.getEmployees()) //
.allMatch(it -> it instanceof Employee) //
.extracting("name").containsExactly("greedo", "boba");
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.docref.jpastyle;
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import org.bson.Document;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.data.mongodb.core.MongoOperations;
/**
* @author Christoph Strobl
*/
@DataMongoTest
public class JpaStyleDocRefTests {
@Autowired MongoOperations operations;
/**
* Load linked documents where where the actual reference is stored in the obverse side of the association.
*/
@Test
void saveAndLoadJpaStyleRelation() {
Manager manager = new Manager("jabba-the-hutt", "jabba");
operations.save(manager);
Employee employee1 = new Employee("greedo-tetsu-jr", "greedo");
employee1.setManagerId(manager.getId()); // establish the link to the manager document
operations.save(employee1);
// no need to update he manager document after save of employee
Employee employee2 = new Employee("boba-fett", "boba");
employee2.setManagerId(manager.getId()); // establish the link to the manager document
operations.save(employee2);
// no need to update he manager document after save of employee
operations.execute(Manager.class, collection -> {
Document rawManager = collection.find(new Document("_id", manager.getId())).first();
assertThat(rawManager).doesNotContainKey("employees");
return "OK";
});
Manager loaded = operations.query(Manager.class)
.matching(where("id").is(manager.getId()))
.firstValue();
assertThat(loaded.getEmployees()) //
.allMatch(it -> it instanceof Employee) //
.extracting("name").containsExactly("greedo", "boba");
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.docref.query;
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import java.util.List;
import org.bson.Document;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Update;
/**
* @author Christoph Strobl
*/
@DataMongoTest
public class QueryDocRefTests {
@Autowired MongoOperations operations;
/**
* Load linked documents where where the reference is stored on the inverse and evaluated against a non id property on
* the obverse side of the association.
*/
@Test
void saveAndLoadDocRefViaQuery() {
Manager manager = new Manager("jabba-the-hutt", "jabba");
operations.save(manager);
Employee employee1 = new Employee("greedo-tetsu-jr", "greedo");
employee1.setManager(manager); // back-link to the manager document
operations.save(employee1);
operations.update(Manager.class) // establish the link to the employee document via employee.name
.matching(where("id").is(manager.getId())) //
.apply(new Update().push("employees").value(employee1.getName())) //
.first();
Employee employee2 = new Employee("boba-fett", "boba");
employee2.setManager(manager); // back-link to the manager document
operations.save(employee2);
operations.update(Manager.class) // establish the link to the employee document via employee.name
.matching(where("id").is(manager.getId())) //
.apply(new Update().push("employees").value(employee2.getName())) //
.first();
operations.execute(Manager.class, collection -> {
Document rawManager = collection.find(new Document("_id", manager.getId())).first();
assertThat(rawManager.get("employees", List.class)) //
.containsExactly("greedo", "boba");
return "OK";
});
Manager loaded = operations.query(Manager.class)
.matching(where("id").is(manager.getId()))
.firstValue();
assertThat(loaded.getEmployees()) //
.allMatch(it -> it instanceof Employee) //
.extracting("name").containsExactly("greedo", "boba");
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.springdata.mongodb.linking.docref.simple;
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import java.util.List;
import org.bson.Document;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Update;
/**
* @author Christoph Strobl
*/
@DataMongoTest
public class SimpleDocRefTests {
@Autowired MongoOperations operations;
/**
* Load linked documents where where the reference is stored on the inverse and evaluated against the id property on
* the obverse side of the association.
*/
@Test
void saveAndLoadDocRef() {
Manager manager = new Manager("jabba-the-hutt", "jabba");
operations.save(manager);
Employee employee1 = new Employee("greedo-tetsu-jr", "greedo");
employee1.setManager(manager); // back-link to the manager document
operations.save(employee1);
operations.update(Manager.class) // establish the link to the employee document via employee.id
.matching(where("id").is(manager.getId())) //
.apply(new Update().push("employees").value(employee1)) //
.first();
Employee employee2 = new Employee("boba-fett", "boba");
employee2.setManager(manager); // back-link to the manager document
operations.save(employee2);
operations.update(Manager.class) // establish the link to the employee document via employee.id
.matching(where("id").is(manager.getId())) //
.apply(new Update().push("employees").value(employee2)) //
.first();
operations.execute(Manager.class, collection -> {
Document rawManager = collection.find(new Document("_id", manager.getId())).first();
assertThat(rawManager.get("employees", List.class)) //
.containsExactly("greedo-tetsu-jr", "boba-fett");
return "OK";
});
Manager loaded = operations.query(Manager.class)
.matching(where("id").is(manager.getId()))
.firstValue();
assertThat(loaded.getEmployees()) //
.allMatch(it -> it instanceof Employee) //
.extracting("name").containsExactly("greedo", "boba");
}
}

View File

@@ -0,0 +1,3 @@
# Random port for embedded MongoDB
spring.data.mongodb.port=0
spring.mongodb.embedded.version=3.6.0

View File

@@ -33,6 +33,7 @@
<module>transactions</module>
<module>schema-validation</module>
<module>querydsl</module>
<module>linking</module>
<module>util</module>
</modules>