Henders
Dezembro 3, 2020, 7:52pm
#1
Olá, estou com este erro:
identifier of an instance of br.com.empresa.entrevista.data.entity.Pais was altered from 1 to 2
OU seja, não consigo mudar um País de um Estado.
Tenho que fazer mudanças na entidade Pais não é isso? Mas Veja minha entidade:
Pais.java
@Getter
@Setter
@Entity
@Table(name = "Pais")
@SQLDelete(sql = "UPDATE pais SET ativo = 0 WHERE id = ?")
@Where(clause = "ativo = 1")
public class Pais extends BaseEntity {
private String nome;
private String sigla;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pais")
private Set<Estado> estados;
}
Meu PaisResource.java:
@RestController
@RequestMapping("/api/pais")
public class PaisResource {
@Autowired
private PaisRepository repository;
@Autowired
private PaisResourceMapper mapper;
@Autowired
private PaisService service;
@GetMapping(produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<PageDto<PaisDTO>> getPageWithQuery(@QuerydslPredicate(root = Pais.class ) Predicate predicate, Pageable pageble) {
return ResponseEntity.ok(convertToPageDto(predicate, pageble));
}
@PostMapping
public ResponseEntity<PaisDTO> add(@Valid @RequestBody PaisDTO dto) throws Exception {
Pais entity = this.mapper.fromDto(dto);
service.validateAdd(dto, entity);
entity = repository.save(entity);
ResponseEntity<PaisDTO> re = ResponseEntity.ok(this.convertToDto(entity));
return re;
}
@GetMapping(value = "/{id}")
public ResponseEntity<PaisDTO> get(@PathVariable Integer id) {
return ResponseEntity.ok(convertToDto(repository.findById(id).get()));
}
@PutMapping(value = "/{id}")
public ResponseEntity<PaisDTO> update(@Valid @RequestBody PaisDTO dto, @PathVariable Integer id) throws Exception {
Optional<Pais> entity = repository.findById(id);
if (entity.isPresent()) {
this.mapper.merge(entity.get(), dto);
service.validateUpdate(dto, entity.get());
Pais mergedEntity = repository.save(entity.get());
ResponseEntity<PaisDTO> re = ResponseEntity.ok(this.convertToDto(mergedEntity));
return re;
} else {
throw new RuntimeException();
}
}
@DeleteMapping(value = "/{id}")
public void delete(@PathVariable Integer id) throws Exception {
service.validateDelete(id);
repository.deleteById(id);
}
private PageDto<PaisDTO> convertToPageDto(Predicate predicate, Pageable pageble) {
Page<Pais> pageEntity = repository.findAll(predicate, pageble);
return new PageDto<PaisDTO>(StreamSupport.stream(pageEntity.spliterator(), false).map(this::convertToDto)
.collect(Collectors.toList()), pageEntity.getTotalElements());
}
private PaisDTO convertToDto(Pais entity) {
return mapper.toDto(entity);
}
}
Veja o front:
Henders
Dezembro 3, 2020, 7:55pm
#2
@Jonathan_Medeiros você teria alguma ideia? Desculpe te incomodar cara, mas se puder me ajudar agradeço. Até o @pmlm é um cara também gente boa que vez ou outra me dá uma ideia…
O problema em si está em estado e não no país, certo?
Você está tentando atualizar dados de um estado e não pais, pelo menos é o que me parece!
Compartilha suas classes de estado, controller e entidade!
Henders
Dezembro 3, 2020, 9:00pm
#4
Isso, me equivoquei, é Estado mesmo. Veja aí @Jonathan_Medeiros por favor:
Estado.java:
@Getter
@Setter
@Entity
@SQLDelete(sql = "UPDATE estado SET ativo = 0 WHERE id = ?")
@Where(clause = "ativo = 1")
public class Estado extends BaseEntity {
private String nome;
private String sigla;
private Double populacao;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(nullable = false)
private Pais pais;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "estado")
private Set<Cidade> cidades;
}
EstadoRepository.java
@Repository
@JaversSpringDataAuditable
public interface EstadoRepository extends DefaultRepository<Integer, Estado, QEstado> {
}
EstadoResource.java
@RestController
@RequestMapping("/api/estado")
public class EstadoResource {
@Autowired
private EstadoRepository repository;
@Autowired
private EstadoResourceMapper mapper;
@Autowired
private EstadoService service;
@GetMapping(produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<PageDto<EstadoDTO>> getPageWithQuery(@QuerydslPredicate(root = Estado.class ) Predicate predicate, Pageable pageble) {
return ResponseEntity.ok(convertToPageDto(predicate, pageble));
}
@GetMapping(value = "/{id}")
public ResponseEntity<EstadoDTO> get(@PathVariable Integer id) {
return ResponseEntity.ok(convertToDto(repository.findById(id).get()));
}
@PostMapping
public ResponseEntity<EstadoDTO> add(@Valid @RequestBody EstadoDTO dto) throws Exception {
Estado entity = this.mapper.fromDto(dto);
service.validateAdd(dto, entity);
entity = repository.save(entity);
ResponseEntity<EstadoDTO> re = ResponseEntity.ok(this.convertToDto(entity));
return re;
}
@PutMapping(value = "/{id}")
public ResponseEntity<EstadoDTO> update(@Valid @RequestBody EstadoDTO dto, @PathVariable Integer id) throws Exception {
Optional<Estado> entity = repository.findById(id);
if (entity.isPresent()) {
this.mapper.merge(entity.get(), dto);
service.validateUpdate(dto, entity.get());
Estado mergedEntity = repository.save(entity.get());
ResponseEntity<EstadoDTO> re = ResponseEntity.ok(this.convertToDto(mergedEntity));
return re;
} else {
throw new RuntimeException();
}
}
@DeleteMapping(value = "/{id}")
public void delete(@PathVariable Integer id) throws Exception {
service.validateDelete(id);
repository.deleteById(id);
}
private PageDto<EstadoDTO> convertToPageDto(Predicate predicate, Pageable pageble) {
Page<Estado> pageEntity = repository.findAll(predicate, pageble);
return new PageDto<EstadoDTO>(StreamSupport.stream(pageEntity.spliterator(), false).map(this::convertToDto)
.collect(Collectors.toList()), pageEntity.getTotalElements());
}
private EstadoDTO convertToDto(Estado entity) {
return mapper.toDto(entity);
}
}
EstadoService.java:
public interface EstadoService {
void validateDelete(Integer id) throws AppException;
void validateUpdate(@Valid EstadoDTO dto, Estado entity) throws AppException;
void validateAdd(@Valid EstadoDTO dto, Estado entity) throws AppException;
}
Perfeito!
Pelo que me parece você não busca país no DB, certo?
Para atualizar o país contido no estado primeiro você precisa colocá-lo em um estado gerenciável pelo JPA, ou seja, dar ao JPA conhecimento do objeto que está sendo modificado, no caso do update isso é feito através de uma simples busca de país no banco de dados e setá-lo na entidade.
Perceba, não digo que o registro não exista em sua base de dados, até porquê ele está sendo carregado em tela, mas sim que você não faz a busca dele antes de atualizar o estado, compreende?
No método de atualizar o estado teria que ter algo mais ou menos assim:
Pais pais = paisRepository.findById(dto.getPais().getId());
estadoEntity.setPais(pais);
Henders
Dezembro 4, 2020, 5:04pm
#8
Olá @Jonathan_Medeiros eu não consegui cara… Este não seria o meu método update de estado?
@PutMapping(value = "/{id}")
public ResponseEntity<EstadoDTO> update(@Valid @RequestBody EstadoDTO dto, @PathVariable Integer id) throws Exception {
Optional<Estado> entity = repository.findById(id);
if (entity.isPresent()) {
this.mapper.merge(entity.get(), dto);
service.validateUpdate(dto, entity.get());
Estado mergedEntity = repository.save(entity.get());
ResponseEntity<EstadoDTO> re = ResponseEntity.ok(this.convertToDto(mergedEntity));
return re;
} else {
throw new RuntimeException();
}
}
Então, quando insiro
@PutMapping(value = "/{id}")
public ResponseEntity<EstadoDTO> update(@Valid @RequestBody EstadoDTO dto, @PathVariable Integer id) throws Exception {
Pais pais = paisRepository.findById(dto.getPais().getId());
estadoEntity.setPais(pais);
Optional<Estado> entity = repository.findById(id);
if (entity.isPresent()) {
this.mapper.merge(entity.get(), dto);
service.validateUpdate(dto, entity.get());
Estado mergedEntity = repository.save(entity.get());
ResponseEntity<EstadoDTO> re = ResponseEntity.ok(this.convertToDto(mergedEntity));
return re;
} else {
throw new RuntimeException();
}
}
Ele diz que tenho que criar variáveis relacionadas. Daí eu crio e vira um loop de erros. Você poderia me esclarecer no que estou errando?
Está dando errado porquê você só copiou e colou, eu escrevi para te servir como referência para você implementar no seu código!
E no caso essa parte da implementação ficaria após o if que verifica se o estado existe!
1 curtida