committed by
Mark Paluch
parent
3d0cad81a1
commit
19b3c92192
@@ -6,4 +6,5 @@ This project contains examples for:
|
||||
* `EntityCallback` API usage for before convert/save interaction.
|
||||
* Result projections for DTOs and interface types.
|
||||
* Query metadata.
|
||||
* Unwrapping entities into the parent document.
|
||||
|
||||
|
||||
@@ -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.unwrapping;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class ApplicationConfiguration {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.unwrapping;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class Email { // might as well be a record type in more recent java versions
|
||||
|
||||
private final String email;
|
||||
|
||||
public Email(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Email email1 = (Email) o;
|
||||
return Objects.equals(email, email1.email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(email);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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.unwrapping;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.data.mongodb.core.mapping.Unwrapped;
|
||||
import org.springframework.data.mongodb.core.mapping.Unwrapped.OnEmpty;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class User {
|
||||
|
||||
@Nullable
|
||||
private String id;
|
||||
|
||||
@Nullable
|
||||
@Unwrapped(onEmpty = OnEmpty.USE_NULL)
|
||||
private UserName userName;
|
||||
|
||||
/*
|
||||
* The prefix allows to unwrap multiple properties of the same type assigning them a unique prefix.
|
||||
* In this case the `Email.email` will be stored as `primary_email`.
|
||||
*/
|
||||
@Nullable
|
||||
@Unwrapped(onEmpty = OnEmpty.USE_NULL, prefix = "primary_")
|
||||
private Email email;
|
||||
|
||||
User() {
|
||||
}
|
||||
|
||||
public User(String id, UserName userName, Email email) {
|
||||
|
||||
this.id = id;
|
||||
this.userName = userName;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
User(String id, String userName, String email) {
|
||||
this(id, new UserName(userName), new Email(email));
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public UserName getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public Email getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setUserName(@Nullable UserName userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public void setEmail(@Nullable Email email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
User user = (User) o;
|
||||
return Objects.equals(id, user.id) &&
|
||||
Objects.equals(userName, user.userName) &&
|
||||
Objects.equals(email, user.email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, userName, email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "User{" +
|
||||
"id='" + id + '\'' +
|
||||
", userName=" + userName +
|
||||
", email=" + email +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.unwrapping;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class UserName { // might as well be a record type in more recent java versions
|
||||
|
||||
private final String username;
|
||||
|
||||
public UserName(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
UserName userName = (UserName) o;
|
||||
return Objects.equals(username, userName.username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(username);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.unwrapping;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public interface UserRepository extends CrudRepository<User, String> {
|
||||
|
||||
/**
|
||||
* Use the value type directly.
|
||||
* This will unwrap the values into the target query object.
|
||||
*/
|
||||
User findByUserName(UserName userName);
|
||||
|
||||
/**
|
||||
* Use one of the unwrapped properties.
|
||||
* This will drill into the unwrapped using the value for the target query.
|
||||
*/
|
||||
User findByEmailEmail(String email);
|
||||
}
|
||||
@@ -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.unwrapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.mongodb.client.model.Filters;
|
||||
import org.bson.Document;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@SpringBootTest
|
||||
@ExtendWith(SpringExtension.class)
|
||||
class UnwrappingIntegrationTests {
|
||||
|
||||
@Autowired UserRepository repository;
|
||||
@Autowired MongoOperations operations;
|
||||
|
||||
User jane = new User("jane-01", new UserName("jane-villanueva"), new Email("jane@home.com"));
|
||||
User rogelio = new User("rogelio-01", new UserName("rogelio-de-la-vega"), new Email("me@RogelioDeLaVega.com"));
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
|
||||
operations.dropCollection(User.class);
|
||||
repository.saveAll(Arrays.asList(jane, rogelio));
|
||||
}
|
||||
|
||||
@Test
|
||||
void documentStructure() {
|
||||
|
||||
org.bson.Document stored = operations.execute(User.class, collection -> {
|
||||
return collection.find(Filters.eq("_id", rogelio.getId())).first();
|
||||
});
|
||||
|
||||
assertThat(stored).containsAllEntriesOf(new Document("_id", rogelio.getId())
|
||||
.append("username", rogelio.getUserName().getUsername())
|
||||
.append("primary_email", rogelio.getEmail().getEmail())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Query using the value type.
|
||||
*/
|
||||
@Test
|
||||
void queryViaValueType() {
|
||||
assertThat(repository.findByUserName(jane.getUserName())).isEqualTo(jane);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query using a property of the embedded value type
|
||||
*/
|
||||
@Test
|
||||
void queryViaPropertyOfValueType() {
|
||||
assertThat(repository.findByEmailEmail(jane.getEmail().getEmail())).isEqualTo(jane);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user