Boa tarde a todos! Estou implementando um pequeno projeto para estudar JPA e aprimorar. Estou implementando 2 tabelas, com relação 1:N. Ao tentar salvar novo objeto do tipo cidade, no qual está associado a país, não estou tendo sucesso. Estou usando esse json no endpoint via Postman:
{
"city": "Cidade teste 1",
"countryId": {
"country": "Pais teste 1"
}
}
Objetivo: criar um registro de cidade e automaticamente de país passando os nomes, tendo os id´s de cada entidade gerados automaticamente.
Gostaria de saber:
- Como salvar um objeto no endpoint de save para criar uma cidade e automaticamente um país?
- Quais são as melhores práticas pra criar registros (objetos) em endpoints cujas entidades (tabelas) estão relacionadas entre sí?
Código da classe City:
@Entity
@Table(name = "city")
public class City implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(columnDefinition = "SMALLINT UNSIGNED NOT NULL")
private BigInteger cityId;
@NotBlank
private String city;
@Past
private Date lastUpdate;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "countryId", columnDefinition = "SMALLINT UNSIGNED NOT NULL")
private Country countryId;
public City() {
}
public City(BigInteger cityId, @NotBlank String city, @NotBlank @Past Date lastUpdate, Country countryId) {
this.cityId = cityId;
this.city = city;
this.lastUpdate = lastUpdate;
this.countryId = countryId;
}
public BigInteger getCityId() {
return cityId;
}
public void setCityId(BigInteger cityId) {
this.cityId = cityId;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Date getLastUpdate() {
return lastUpdate;
}
public void setLastUpdate(Date lastUpdate) {
this.lastUpdate = lastUpdate;
}
public Country getCountryId() {
return countryId;
}
public void setCountryId(Country countryId) {
this.countryId = countryId;
}
}
Código da classe CityService:
@Service
public class CityService {
private CityRepository cityRepository;
private CountryRepository countryRepository;
public CityService(CityRepository cityRepository, CountryRepository countryRepository) {
this.cityRepository = cityRepository;
this.countryRepository = countryRepository;
}
@Transactional
public City save(City obj) {
try {
City city = new City();
city.setCityId(null);
city.setCity(obj.getCity());
city.setLastUpdate(new Date());
return cityRepository.save(city);
} catch (RuntimeException e) {
throw new ResourceNotFoundException(obj);
}
}
}
Código da classe CityController:
@RestController
@RequestMapping("/api/v1")
@Tag(name = "City")
public class CityController {
private CityService cityService;
public CityController(CityService cityService) {
this.cityService = cityService;
}
@PostMapping(value = "/cities", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Cria uma cidade")
public ResponseEntity<City> save(@RequestBody City city) {
city = cityService.save(city);
URI uri = ServletUriComponentsBuilder.fromCurrentRequest().path("/api/v1/cities/{cityId}")
.buildAndExpand(city.getCityId()).toUri();
return ResponseEntity.created(uri).body(city);
}
}
Código da classe Country:
@Entity
@Table(name = "country")
public class Country implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(columnDefinition = "SMALLINT UNSIGNED NOT NULL")
private BigInteger countryId;
@NotBlank(message = "O country é obrigatório")
private String country;
@Past(message = "Informe uma data passada")
private Date lastUpdate;
@OneToMany(mappedBy = "countryId", cascade = CascadeType.ALL)
@JsonIgnore
private Set<City> cityList = new HashSet<>();
public Country() {
}
public Country(BigInteger countryId, String country, Date lastUpdate) {
this.countryId = countryId;
this.country = country;
this.lastUpdate = lastUpdate;
}
public BigInteger getCountryId() {
return countryId;
}
public void setCountryId(BigInteger countryId) {
this.countryId = countryId;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Date getLastUpdate() {
return lastUpdate;
}
public void setLastUpdate(Date lastUpdate) {
this.lastUpdate = lastUpdate;
}
public Set<City> getCityList() {
return cityList;
}
}