W poprzednim wpisie pokazałam, jak dodawać dokumenty i kolekcje do nierelacyjnej bazy MongoDB oraz jak połączyć się z tą bazą z kodu javowego.
W tym odcinku pokażę, jak łatwo utrwalić w MongoDB obiekty przetwarzane w aplikacji webowej.
Spis treści
Wpis w pom.xml
Kolejny raz korzystam ze “startera” Spring Boot, który grupuje w sobie kilka podstawowych bibliotek realizujących spójny cel – w tym wypadku mapowanie, zapis i odczyt danych z MongoDB:
1 2 3 4 |
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency |
Adnotacje w obiekcie, który ma zostać utrwalony w bazie danych
Do obiektu reprezentującego użytkownika bazy danych dodałam następujące adnotacje:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
... import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.DBRef; import org.springframework.data.mongodb.core.mapping.Document; @Document public class User { @Id private BigInteger id; private String displayedName; private String description; private Calendar birthday; private URI profilePic; ... @DBRef private List<Size> sizes; ... } |
@Document
oznacza, że mamy do czynienia z obiektem zapisywanym w bazie danych. Jest to odpowiednik @Entity w wersji Spring Data dla relacyjnych baz danych.@Id
to automatycznie generowany, obowiązkowy identyfikator dokumentu w ramach kolekcji w MongoDB.- Pola nieopisane zostaną bezpośrednio odwzorowane w dokumencie w bazie danych.
@DBRef
oznacza odwołanie do innej kolekcji w bazie. Uwaga! Nie wolno tworzyć odwołań obustronnych, MongoDB brzydko się przez nie zapętli. Zamiast tego należy po jednej stronie jawnie zapisać identyfikator dokumentu.
Interfejs do obsługi repozytorium
Muszę tylko zasygnalizować, że będę chciała pobierać z bazy obiekty danego typu:
1 2 3 4 5 6 7 8 9 |
package pl.namiekko.controllers; import java.math.BigInteger; import org.springframework.data.repository.CrudRepository; import pl.namiekko.entities.User; public interface UserRepository extends CrudRepository<User, BigInteger>{ } |
Użycie w kodzie: kontroler i widok
Kontroler
W celu przetestowania konfiguracji dodałam odwołanie do kolekcji użytkowników do mojego powitalnego kontrolera GreetingController:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@Controller public class GreetingController { @Autowired private UserRepository userRepository; @RequestMapping("/") public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) { model.addAttribute("name", name); for(User user: userRepository.findAll()){ model.addAttribute("retrievedName", user.getUserName()); break; } return "index"; } } |
Nazwa pierwszego napotkanego użytkownika zostanie dodana do modelu.
Widok
W powitalnym szablonie Thymeleaf dopisałam kod, który wyświetli nazwę odnalezionego w bazie danych użytkownika, o ile taki użytkownik istnieje:
1 2 3 |
... <p th:if="${retrievedName != null}" th:text="'Our database user is, ' + ${retrievedName} + '!'" /> ... |
Efekt

Zapis informacji w bazie
Mogę skorzystać ze sposobu pokazanego w poprzednim wpisie. Mogę też przygotować kod, który będzie wywoływany przy każdym uruchomieniu aplikacji:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@Service public class DatabaseLoader { ... @PostConstruct private void initDatabase() { userRepository.deleteAll(); User user = new User(); user.setEmail("user@example.com"); user.setDisplayedName("First User <3"); user.setUserName("first1"); userRepository.save(user); } } |
Konfiguracja połączenia z bazą danych
Tym razem oparłam się na wartościach domyślnych. Nie wpisałam w application.properties żadnych danych na temat połączenia z bazą danych. Oczywiście musiałam uruchomić mój serwer MongoDB.
Wszystko zadziałało.
Mogę podejrzeć zastosowane wartości właściwości związanych z MongoDB dzięki dołączonej w pom.xml bibliotece Spring Boot Actuator. Pod adresem http://localhost:8080/configprops widzę m.in. takie dane:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
"spring.data.mongodb.CONFIGURATION_PROPERTIES":{ "prefix":"spring.data.mongodb", "properties":{ "database":null, "password":null, "fieldNamingStrategy":null, "gridFsDatabase":null, "port":null, "host":null, "uri":"mongodb://localhost/test", "authenticationDatabase":null, "username":null } } |
Test
to baza danych, którą utworzyłam na potrzeby poprzedniego wpisu.
Troubleshooting: co zrobiłam nie tak przy pierwszym podejściu?
- Zapomniałam o wpisaniu
@Autowired
w kontrolerze w punkcie 4 (komunikatCrudRepository ... is no accessor method!
) - Nie włączyłam MongoDB (
Timed out after 10000 ms while waiting for a server that matches AnyServerSelector{} ... caused by {java.net.ConnectException: Connection refused: connect}}
)