Spring Boot 尝试删除时违反引用完整性约束

efzxgjgh  于 2023-01-25  发布在  Spring
关注(0)|答案(2)|浏览(195)

我正在尝试创建一个API来保存Person和它的Address,就像这个模型:

fk_id_pessoa应该是将多个地址与一个人关联的外键
fk_main_address用于将主地址分配给人。
我得到这个错误时,试图删除一个人,在地址表中有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]

型号:

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;
    }



    

    
}

地址

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;
    }

    
}

控制器:

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));
    }

    
}

地址:

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));

    }

    
}

服务:

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;
        }

    }*/
    
}

地址

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);

    }
    
}

我已经在两个字段中输入了"cascade = CascadeType. ALL",但是没有任何帮助。我还认为"fk_main_address"Map错误。任何帮助都将不胜感激。

h5qlskok

h5qlskok1#

是数据库在抱怨。你需要更新Person表,将主地址FK设置为Nil。然后你就可以删除记录了。

t30tvxxf

t30tvxxf2#

我发现Enderecopessoa字段的@JoinColumn注解是错误的,@JoinColumn应该是引用该字段的外键,因此它应该是fk_id_pessoa而不是id,请遵循link示例

相关问题