Имеется вебприложение на следующем стеке: backend: java 8, spring-boot, spring-mvc, hibernate, postgresql. frontend: reactjs, material-ui.
Возникла необходимость отображать яндекс-карту с метками. Я решил сохранять информацию, которую получаю от яндексовского сервиса в jsonb.
Сущность в которой необходимо сохранять инфу:
@NoArgsConstructor
@Getter @Setter
@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
@Entity
public class Location extends Identifiable implements Serializable {
@Type(type = "jsonb")
@Column(columnDefinition = "jsonb")
private Geolocation geolocation;
}
Классы, являющиеся отражением структуры json:
@NoArgsConstructor
@Getter @Setter
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@TypeDefs({
@TypeDef(name = "json", typeClass = JsonStringType.class),
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
})
@MappedSuperclass
public class Geolocation {
private Double latitude;
private Double longitude;
private Address address;
}
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@TypeDefs({
@TypeDef(name = "json", typeClass = JsonStringType.class),
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
})
@MappedSuperclass
public class Address {
private String countryCode;
private String formatted;
private String postalCode;
private Map<String,String> components = new HashMap<>();
}
Метод контроллера, вызывающийся для сохранения геолокации:
@Log4j2
@Controller
@RequestMapping(value = "/api/locations")
public class LocationController {
@Autowired
private ModelMapper modelMapper;
@Autowired
private LocationRepository locationRepository;
@PreAuthorize("hasRole('ADMIN')")
@Transactional
@RequestMapping(value = "/{id}/geolocation", method = RequestMethod.POST)
@ResponseBody
public com.helan.videoafisha.dto.general.Location saveGeolocation(
@PathVariable("id") Long id,
@RequestBody com.helan.videoafisha.dto.backend.frontend.reactjs.locations.with_geolocation.Geolocation modelGeolocation) {
Location location = locationRepository.getOne(id);
Geolocation geolocation = modelMapper.map(modelGeolocation, Geolocation.class);
location.setGeolocation(geolocation);
locationRepository.save(location);
return modelMapper.map(location, com.helan.videoafisha.dto.general.Location.class);
}
}
Суть проблемы заключается в том, что когда geolocation равен null, тогда даный метод отрабатывает корректно: https://imgur.com/PE5lvKQ.png
Hibernate:
update
backend.location
set
geolocation=?,
max_device_count=?,
site_id=?,
time_zone_id=?,
title=?
where
id=?
2020-04-01 16:42:31.339 DEBUG - c.h.v.b.m.l.LogRequestFilter : 200 POST /api/locations/1/geolocation [member #1/admin@mail.ru] 127.0.0.1:41090 {"isRequesting":false,"latitude":55.69962195079022,"longitude":37.62218505859374,"address":{"countryCode":"RU","formatted":"Россия, Москва, Варшавское шоссе, 13с4","postalCode":"117105","components":{"country":"Россия","province":"Центральный федеральный округ","locality":"Москва","street":"Варшавское шоссе","house":"13с4"}}}
После этого, когда geolocation не null повторные вызовы с другими данными не приводят ни к каким изменениям. Даже update не вызывается. Отладка метода не выявила никаких иных условий выполнения.
2020-04-01 16:49:14.836 DEBUG - c.h.v.b.m.l.LogRequestFilter : 200 POST /api/locations/1/geolocation [member #1/admin@mail.ru] 127.0.0.1:41202 {"isRequesting":false,"latitude":55.70117301801526,"longitude":37.58991271972656,"address":{"countryCode":"RU","formatted":"Россия, Москва, улица Вавилова, 9Ас17","postalCode":"117312","components":{"country":"Россия","province":"Центральный федеральный округ","locality":"Москва","street":"улица Вавилова","house":"9Ас17"}}}
Чем может быть вызвано подобное поведение? Если вручную установить колонку geolocation в null, то метод отработает как надо.