[英]Referential integrity constraint violation when trying to delete
I'm trying to create an API for saving a Person and its Address, like in this model:我正在尝试创建一个 API 来保存一个人及其地址,例如 model:
fk_id_pessoa is supposed to be a foreing key to associate many addresses to one person fk_id_pessoa 应该是将多个地址关联到一个人的外键
fk_main_address is for assign a main address to a person. fk_main_address 用于给一个人分配一个主地址。
And i'm getting this error when trying to delete a Person that has a foreing key in the address table:当我试图删除一个在地址表中有 foreing 键的人时,我遇到了这个错误:
2023-01-24T19:58:27.952-03:00 WARN 15492 --- [nio-8080-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 23503, SQLState: 23503
2023-01-24T19:58:27.952-03:00 ERROR 15492 --- [nio-8080-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : Referential integrity constraint violation: "FK4Y8KCQU7650VDPKHN1C54N3TB: PUBLIC.ENDERECO FOREIGN KEY(ID) REFERENCES PUBLIC.PESSOA(ID) (1)"; SQL statement:
delete from pessoa where id=? [23503-214]
Models:楷模:
Person人
package com.apitest.api.model;
import java.util.Date;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
@Entity
@Table(name = "pessoa")
public class Pessoa {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "nome")
private String nome;
@Column(name = "dataNascimento")
private Date dataNascimento;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "id_endereco")
private Endereco endereco;
public Pessoa(Integer id, String nome, Date dataNascimento, Endereco endereco) {
this.id = id;
this.nome = nome;
this.dataNascimento = dataNascimento;
this.endereco = endereco;
}
public Pessoa(){
};
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public Date getDataNascimento() {
return dataNascimento;
}
public void setDataNascimento(Date dataNascimento) {
this.dataNascimento = dataNascimento;
}
public Endereco getEndereco() {
return endereco;
}
public void setEndereco(Endereco endereco) {
this.endereco = endereco;
}
}
Address地址
package com.apitest.api.model;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
@Entity
@Table(name = "endereco")
public class Endereco {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id_endereco;
@Column(name = "logradouro")
private String logradouro;
@Column(name = "cep")
private String cep;
@Column(name = "numero")
private String numero;
@Column(name = "cidade")
private String cidade;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "id")
private Pessoa pessoa;
public Endereco(Integer id_endereco, String logradouro, String cep, String numero, String cidade, Pessoa pessoa) {
this.id_endereco = id_endereco;
this.logradouro = logradouro;
this.cep = cep;
this.numero = numero;
this.cidade = cidade;
this.pessoa = pessoa;
}
public Endereco(){
};
public String getLogradouro() {
return logradouro;
}
public void setLogradouro(String logradouro) {
this.logradouro = logradouro;
}
public String getCep() {
return cep;
}
public void setCep(String cep) {
this.cep = cep;
}
public String getNumero() {
return numero;
}
public void setNumero(String numero) {
this.numero = numero;
}
public String getCidade() {
return cidade;
}
public void setCidade(String cidade) {
this.cidade = cidade;
}
public Pessoa getPessoa() {
return pessoa;
}
public void setPessoa(Pessoa pessoa) {
this.pessoa = pessoa;
}
public Integer getId_endereco() {
return id_endereco;
}
public void setId_endereco(Integer id_endereco) {
this.id_endereco = id_endereco;
}
}
Controllers:控制器:
Person人
package com.apitest.api.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.apitest.api.model.Pessoa;
import com.apitest.api.service.PessoaService;
@RestController
public class PessoaController {
@Autowired
private PessoaService pessoaService;
@GetMapping("/pessoas")
public ResponseEntity<List<Pessoa>> getAllPessoa(){
return ResponseEntity.ok().body(pessoaService.getAllPessoa());
}
@PostMapping("/pessoas")
public ResponseEntity<Pessoa> createPessoa(@RequestBody Pessoa pessoa){
return ResponseEntity.ok().body(this.pessoaService.createPessoa(pessoa));
}
@GetMapping("/pessoas/{id}")
public ResponseEntity<Pessoa> getPessoaById(@PathVariable Integer id){
return ResponseEntity.ok().body(pessoaService.getPessoaById(id));
}
@PutMapping("/pessoas/{id}")
public ResponseEntity<Pessoa> updatePessoa(@PathVariable Integer id, @RequestBody Pessoa pessoa){
pessoa.setId(id);
return ResponseEntity.ok().body(this.pessoaService.updatePessoa(pessoa));
}
@DeleteMapping("/pessoas/{id}")
public HttpStatus deletePessoa (@PathVariable Integer id){
this.pessoaService.deletePessoa(id);
return HttpStatus.OK;
}
@PostMapping("/pessoas/{id}/{fkIdEndereco}")
public ResponseEntity<Pessoa> setEnderecoPrincipal(@PathVariable Integer id, @PathVariable Integer fkIdEndereco){
return ResponseEntity.ok().body(this.pessoaService.setEnderecoPrinicpal(id, fkIdEndereco));
}
}
Address:地址:
package com.apitest.api.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.apitest.api.model.Endereco;
import com.apitest.api.service.EnderecoService;
@RestController
public class EnderecoController {
@Autowired
private EnderecoService enderecoService;
@PostMapping("/endereco")
public ResponseEntity<Endereco> createEndereco(@RequestBody Endereco endereco){
return ResponseEntity.ok().body(this.enderecoService.createEndereco(endereco));
}
}
Service:服务:
Person人
package com.apitest.api.service;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.apitest.api.model.Endereco;
import com.apitest.api.model.Pessoa;
import com.apitest.api.repository.EnderecoRepository;
import com.apitest.api.repository.PessoaRepository;
@Service
@Transactional
public class PessoaServiceImpl implements PessoaService {
@Autowired
private PessoaRepository pessoaRepository;
@Autowired
private EnderecoRepository enderecoRepository;
@Override
public Pessoa createPessoa(Pessoa pessoa) {
return pessoaRepository.save(pessoa);
}
@Override
public Pessoa updatePessoa(Pessoa pessoa) {
Optional<Pessoa> pessoaDb = this.pessoaRepository.findById(pessoa.getId());
Pessoa pessoaUpdate = pessoaDb.get();
pessoaUpdate.setId(pessoa.getId());
pessoaUpdate.setNome(pessoa.getNome());
pessoaUpdate.getNome();
if(pessoa.getEndereco() != null){
Optional<Endereco> enderecoDb = this.enderecoRepository.findById(pessoa.getEndereco().getId_endereco());
pessoaUpdate.setEndereco(pessoa.getEndereco());
}
return pessoaUpdate;
}
@Override
public Pessoa getPessoaById(Integer idPessoa) {
Optional<Pessoa> pessoaDb = this.pessoaRepository.findById(idPessoa);
if(pessoaDb.isPresent()){
return pessoaDb.get();
}
return null;
}
@Override
public List<Pessoa> getAllPessoa() {
return this.pessoaRepository.findAll();
}
@Override
public void deletePessoa(Integer idPessoa) {
Optional<Pessoa> pessoaDb = this.pessoaRepository.findById(idPessoa);
if(pessoaDb.isPresent()){
this.pessoaRepository.delete(pessoaDb.get());
}
}
@Override
public Pessoa setEnderecoPrinicpal(Integer idPessoa, Integer idEndereco) {
// TODO Auto-generated method stub
return null;
}
/*@Override
public Pessoa setEnderecoPrinicpal(Integer idPessoa, Integer idEndereco) {
Optional<Pessoa> pessoaDb = this.pessoaRepository.findById(idPessoa);
Optional<Endereco> enderecoDb = this.enderecoRepository.findById(idEndereco);
Pessoa pessoa = pessoaDb.get();
Endereco endereco = enderecoDb.get();
if(endereco.getPessoa() != null && (pessoa.getId() == endereco.getPessoa().getId())){
pessoa.setFkIdEnderecoPrincipal(endereco);
return pessoa;
}
else{
return null;
}
}*/
}
Address地址
package com.apitest.api.service;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.apitest.api.model.Endereco;
import com.apitest.api.model.Pessoa;
import com.apitest.api.repository.EnderecoRepository;
import com.apitest.api.repository.PessoaRepository;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class EnderecoServiceImpl implements EnderecoService {
@Autowired
private EnderecoRepository enderecoRepository;
@Autowired
private PessoaRepository pessoaRepository;
@Override
public Endereco createEndereco(Endereco endereco) {
if(endereco.getPessoa() != null){
Optional<Pessoa> pessoaDb = this.pessoaRepository.findById(endereco.getPessoa().getId());
Pessoa pessoaUpdate = pessoaDb.get();
endereco.setPessoa(pessoaUpdate);
}
return enderecoRepository.save(endereco);
}
}
I have put "cascade = CascadeType.ALL" in both fields but didnt helped.我在两个字段中都输入了“cascade = CascadeType.ALL”,但没有帮助。 I also think that "fk_main_address" is mapped wrong.
我还认为“fk_main_address”映射错误。 Any help would be appreciated.
任何帮助,将不胜感激。
It is the database that is complaining.是数据库在抱怨。 You need to update the Person table, setting the main address FK to Nil.
您需要更新 Person 表,将主地址 FK 设置为 Nil。 Then you will be able to delete the record.
然后你就可以删除记录了。
I identified that the @JoinColumn annotation of the pessoa
field in Endereco
is wrong, the @JoinColumn should be the foreign key referring to the field, so it would be fk_id_pessoa
and not id
, follow the example link我发现
pessoa
中 pessoa 字段的Endereco
注释是错误的,@JoinColumn 应该是引用该字段的外键,所以它是fk_id_pessoa
而不是id
,按照示例链接
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.