Skip to content

Commit 1353a21

Browse files
authored
document collections and lists (spring-attic#2196)
* document collections and lists in Firestore; fixes spring-attic#2189
1 parent 8ecc8ba commit 1353a21

File tree

3 files changed

+109
-7
lines changed

3 files changed

+109
-7
lines changed

docs/src/main/asciidoc/firestore.adoc

+12-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ import org.springframework.data.annotation.Id;
102102
import org.springframework.cloud.gcp.data.firestore.Document;
103103
104104
include::{project-root}/spring-cloud-gcp-data-firestore/src/test/java/org/springframework/cloud/gcp/data/firestore/User.java[tag=class_definition]
105-
106105
----
107106

108107
`@Document(collectionName = "usersCollection")` annotation configures the collection name for the documents of this type.
@@ -112,6 +111,18 @@ This annotation is optional, by default the collection name is derived from the
112111

113112
NOTE: Internally we use Firestore client library object mapping. See https://developers.google.com/android/reference/com/google/firebase/firestore/package-summary[the documentation] for supported annotations.
114113

114+
==== Embedded entities and lists
115+
Spring Data Cloud Firestore supports embedded properties of custom types and lists.
116+
Given a custom POJO definition, you can have properties of this type or lists of this type in your entities.
117+
They are stored as embedded documents (or arrays, correspondingly) in the Cloud Firestore.
118+
119+
Example:
120+
121+
[source,java,indent=0]
122+
----
123+
include::{project-root}/spring-cloud-gcp-data-firestore/src/test/java/org/springframework/cloud/gcp/data/firestore/User.java[tag=embedded_class_collections]
124+
----
125+
115126
=== Reactive Repositories
116127

117128
https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/reactive/ReactiveCrudRepository.html[Spring Data Repositories] is an abstraction that can reduce boilerplate code.

spring-cloud-gcp-data-firestore/src/test/java/org/springframework/cloud/gcp/data/firestore/User.java

+89-5
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,26 @@
2525
* Sample entity for integration tests.
2626
*
2727
* @author Daniel Zou
28+
* @author Dmitry Solomakha
2829
*/
2930
//tag::class_definition[]
31+
//tag::embedded_class_collections[]
3032
@Document(collectionName = "usersCollection")
3133
public class User {
3234
@DocumentId
3335
private String name;
3436

3537
private Integer age;
36-
//end::class_definition[]
3738

39+
//end::class_definition[]
3840
private List<String> pets;
3941

42+
private List<Address> addresses;
43+
44+
private Address homeAddress;
45+
46+
//end::embedded_class_collections[]
47+
4048
public User(String name, Integer age) {
4149
this.name = name;
4250
this.age = age;
@@ -48,6 +56,15 @@ public User(String name, Integer age, List<String> pets) {
4856
this.pets = pets;
4957
}
5058

59+
public User(String name, Integer age, List<String> pets, List<Address> addresses, Address homeAddress) {
60+
this.name = name;
61+
this.age = age;
62+
this.pets = pets;
63+
this.addresses = addresses;
64+
this.homeAddress = homeAddress;
65+
}
66+
67+
//tag::class_definition[]
5168
public User() {
5269
}
5370

@@ -66,7 +83,9 @@ public Integer getAge() {
6683
public void setAge(Integer age) {
6784
this.age = age;
6885
}
86+
//end::class_definition[]
6987

88+
//tag::embedded_class_collections[]
7089
public List<String> getPets() {
7190
return this.pets;
7291
}
@@ -75,11 +94,30 @@ public void setPets(List<String> pets) {
7594
this.pets = pets;
7695
}
7796

97+
public List<Address> getAddresses() {
98+
return this.addresses;
99+
}
100+
101+
public void setAddresses(List<Address> addresses) {
102+
this.addresses = addresses;
103+
}
104+
105+
public Address getHomeAddress() {
106+
return this.homeAddress;
107+
}
108+
109+
public void setHomeAddress(Address homeAddress) {
110+
this.homeAddress = homeAddress;
111+
}
112+
//end::embedded_class_collections[]
78113
@Override
79114
public String toString() {
80115
return "User{" +
81-
"name='" + this.name + '\'' +
82-
", age=" + this.age +
116+
"name='" + name + '\'' +
117+
", age=" + age +
118+
", pets=" + pets +
119+
", addresses=" + addresses +
120+
", homeAddress=" + homeAddress +
83121
'}';
84122
}
85123

@@ -93,13 +131,59 @@ public boolean equals(Object o) {
93131
}
94132
User user = (User) o;
95133
return Objects.equals(getName(), user.getName()) &&
96-
Objects.equals(getAge(), user.getAge());
134+
Objects.equals(getAge(), user.getAge()) &&
135+
Objects.equals(getPets(), user.getPets()) &&
136+
Objects.equals(getAddresses(), user.getAddresses()) &&
137+
Objects.equals(getHomeAddress(), user.getHomeAddress());
97138
}
98139

99140
@Override
100141
public int hashCode() {
101-
return Objects.hash(getName(), getAge());
142+
return Objects.hash(getName(), getAge(), getPets(), getAddresses(), getHomeAddress());
143+
}
144+
145+
//tag::embedded_class_collections[]
146+
147+
public static class Address {
148+
String streetAddress;
149+
String country;
150+
151+
public Address() {
152+
}
153+
//end::embedded_class_collections[]
154+
public Address(String streetAddress, String country) {
155+
this.streetAddress = streetAddress;
156+
this.country = country;
157+
}
158+
159+
public String getStreetAddress() {
160+
return this.streetAddress;
161+
}
162+
163+
public String getCountry() {
164+
return this.country;
165+
}
166+
167+
@Override
168+
public boolean equals(Object o) {
169+
if (this == o) {
170+
return true;
171+
}
172+
if (o == null || getClass() != o.getClass()) {
173+
return false;
174+
}
175+
Address address = (Address) o;
176+
return Objects.equals(getStreetAddress(), address.getStreetAddress()) &&
177+
Objects.equals(getCountry(), address.getCountry());
178+
}
179+
180+
@Override
181+
public int hashCode() {
182+
return Objects.hash(getStreetAddress(), getCountry());
183+
}
184+
//tag::embedded_class_collections[]
102185
}
103186
//tag::class_definition[]
104187
}
188+
//end::embedded_class_collections[]
105189
//end::class_definition[]

spring-cloud-gcp-data-firestore/src/test/java/org/springframework/cloud/gcp/data/firestore/it/FirestoreRepositoryIntegrationTests.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,10 @@ public void countTest() {
9494
@Test
9595
//tag::repository_built_in[]
9696
public void writeReadDeleteTest() {
97-
User alice = new User("Alice", 29);
97+
List<User.Address> addresses = Arrays.asList(new User.Address("123 Alice st", "US"),
98+
new User.Address("1 Alice ave", "US"));
99+
User.Address homeAddress = new User.Address("10 Alice blvd", "UK");
100+
User alice = new User("Alice", 29, null, addresses, homeAddress);
98101
User bob = new User("Bob", 60);
99102

100103
this.userRepository.save(alice).block();
@@ -103,6 +106,10 @@ public void writeReadDeleteTest() {
103106
assertThat(this.userRepository.count().block()).isEqualTo(2);
104107
assertThat(this.userRepository.findAll().map(User::getName).collectList().block())
105108
.containsExactlyInAnyOrder("Alice", "Bob");
109+
110+
User aliceLoaded = this.userRepository.findById("Alice").block();
111+
assertThat(aliceLoaded.getAddresses()).isEqualTo(addresses);
112+
assertThat(aliceLoaded.getHomeAddress()).isEqualTo(homeAddress);
106113
}
107114
//end::repository_built_in[]
108115

0 commit comments

Comments
 (0)