Witam,
piszę obecnie aplikację z wykorzystaniem Jacksona, Jersey oraz Hibernate. Encje JPA są od razu serializowane i zwracane bez zastosowania jakichś dodatkowych obiektów opakowujących.
Problem zaczyna się w momencie, gdy chcę te encje edytować. Mogę oczywiście odbierać automatycznie deserializowane encje
@POST
@Path("/{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response update(@PathParam("id") int id, User user) {...}
ale chciałbym umożliwić użytkownikowi przesyłanie tylko tych pól które chce modyfikować. W takim rozwiązaniu pozostałe pola dostaną wartość NULL i zapis obiektu do bazy nadpisze wartości (albo rzuci wyjątkiem, jeżeli kolumna jest niemodyfikowalna).
Drugim rozwiązaniem jest przesyłanie mapy parametrów
@POST
@Path("/{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response update(@PathParam("id") int id, Map<String, Object> properties) {...}
a następnie ręczne ich kopiowanie do obiektu User odobno pobranego z bazy. W tym rozwiązaniu problemem jest oczywiście konieczność ręcznej deserializacji obiektów do właściwego typu, oraz samo ustawienie pola na podstawie nazwy. Można to pewnie zrobić przy pomocy refleksji, ale ja wykorzystałem bibliotekę Commons BeanUtils i metodę BeanUtils.copyProperty(Object bean, String name, Object value)
. Takie rozwiązanie też ma swoje wady, bo wymaga znów pisania deserializatorów które już mam napisane dla Jacksona (fakt, to przeważnie parę linijek kodu tylko).
Pytanie, w jaki sposób najczęściej rozwiązujecie tego typu problemy w swoich aplikacjach? Jest może jakiś mechanizm 'scalenia' takich encji w JPA, osobiście nie bardzo sobie to wyobrażam, bo przecież NULLa mogę sam umieścić w polu?