Hej, dzisiaj podczas implementowania HATEOS'a trochę mnie olśniło.
Kiedyś w robocie gdy używałem jeszcze SONAR'a pamiętam że pluło warningami w stylu "You should/must return a copy of given {...} Object" nie za bardzo rozumiałem dlaczego. Poszedłem troche na skróty, postanowiłem trzymać dane w pamięci:
private final Set<Moderator> FAKE_DATA = Set.of(
new Moderator(1L, "Bolec", "Adam", "Kowalski", "[email protected]", LocalDate.of(1992, 3, 3)),
new Moderator(2L, "Koles", "Adrian", "Kownacki", "[email protected]", LocalDate.of(1994, 10, 17)),
new Moderator(3L, "Dolec", "Antek", "Koterski", "[email protected]", LocalDate.of(1991, 11, 21))
);
W kontrolerze do ResponseEntity jak to bywa w HATEOAS dopisywałem linki. Zauważyłem że każdorazowo gdy wołałem findAll() inkrementopałem link dostępu
response.forEach(x -> x.add(linkTo(AdminController.class).slash(x.getId()).withSelfRel()));
I następstwo :
"_embedded": {
"moderatorList": [
{
"id": 3,
"nickname": "Dolec",
"firstName": "Antek",
"lastName": "Koterski",
"email": "[email protected]",
"registrationDate": "1991-11-21",
"_links": {
"self": [
{
"href": "http://localhost:8080/admin/3"
},
{
"href": "http://localhost:8080/admin/3"
}
]
}
},
I tutaj mi zabłysło i wrzuciłem deepCopy(...) co rozwiązało problem.
public Set<Moderator> findAll() {
return FAKE_DATA.stream()
.map(this::deepCopy)
.map(x -> (Moderator) x)
.collect(Collectors.toSet());
}
Całość kodu tutaj:
https://github.com/Korges/spring-hateoas
No i czas na pytanko, jak to jest z tym zwracaniem kopii obiektów? Domyślam się że chodzi o to aby w publicznych akcesorach nie udostępniać mutowalnych danych. W jakich przypadkach należy je stosować i jaki sposób polecacie? Czy taka implementacja jaka jest u mnie wystarczy ? (deepCopy() w klasie ModeratorRepositoryDao)