代码之家  ›  专栏  ›  技术社区  ›  Eveprogram11

在Spring Boot和JPA中保存具有非null外键的实体时出现NullPointerException

  •  0
  • Eveprogram11  · 技术社区  · 2 年前

    我在我的Spring Boot应用程序中遇到了一个问题,在尝试使用JPA保存具有非null外键的实体时,我得到了一个NullPointerException。我有一个历史临床实体,它与Paciente实体有多对一的关系。外键列paciente_id在数据库中不可为null。

    但是,当我尝试用有效的pacientId保存新的HistoriaClinica实体时,我会收到一个NullPointerException,并显示错误消息:“给定的id不能为null”。我已经检查并确认pacientId不为null并且存在于数据库中。

    我已经查看了我的代码,并验证了Paciente和HistoriaClinica之间关系的映射和注释设置正确。我还检查了数据库配置,并确保存在必要的表和列。

    我使用SpringBoot3.0.5和JPA作为持久层。我在下面包含了相关的代码片段:

    @Entity
    @Table(name = "historias_clinicas")
    @Getter
    @Setter
    public class HistoriaClinica {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @Column(name = "fecha_creacion", nullable = false)
        @JsonFormat(pattern = "dd-MM-yyyy")
        private Date fechaCreacion;
    
        private String enfermedad;
    
        private String descripcion;
    
        private String medicacion;
        
        private String droga;
        
        private String dósis;
        
        private Double peso;
        
        private Double altura;
    
        @Column(nullable = false)
        private String indicaciones;
    
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "paciente_id", nullable = false)
        private Paciente paciente;
    
        @OneToMany(mappedBy = "historiaClinica", cascade = CascadeType.ALL)
        private List<ArchivoHistoriaClinica> archivosHistoriaClinica;
    
        @OneToMany(mappedBy = "historiaClinica", cascade = CascadeType.ALL, orphanRemoval = true)
        private List<Actualizacion> actualizaciones = new ArrayList<>();
    
        @OneToMany(mappedBy = "historiaClinica", cascade = CascadeType.ALL, orphanRemoval = true)
        private List<ArchivoHistoriaClinica> archivos = new ArrayList<>();
    //respective constructors
    
    @Getter @Setter
    public class Paciente {
        
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        
        private Long id;
        
        @Column(nullable = false)
        @NotNull
        private String nombre;
        
        @Column(nullable = false)
        @NotNull
        private String apellido;
        
        @Column(nullable = false, unique = true)
        @NotNull
        private String dni;
        
        @Column(name = "fecha_nacimiento")
        @NotNull
        private LocalDate fechaNacimiento;
        
        private String direccion;
        
        private String telefono;
        
        private String email;
        
        @Column(nullable = false)
        private String role = "ROLE_PACIENTE"; // anotación de rol
    
        
        @OneToMany(mappedBy = "paciente", cascade = CascadeType.ALL)
        private List<HistoriaClinica> historiasClinicas;
    
        public Paciente() {
        }
    

    我正在调用的HistoriaClinicalService方法:

     public HistoriaClinica save(HistoriaClinicaDTO hcDTO, Long idPaciente) {
            Paciente paciente = pacienteRepository.findById(idPaciente)
                    .orElseThrow(() -> new EntityNotFoundException("Paciente no encontrado con id " + idPaciente));
    
            HistoriaClinica hc = historiaClinicaMapper.toEntity(hcDTO);
            hc.setPaciente(paciente);
    
            List<Actualizacion> actualizaciones = hcDTO.getActualizaciones().stream()
                    .map(actualizacionMapper::toEntity)
                    .collect(Collectors.toList());
            hc.setActualizaciones(actualizaciones);
    
            List<ArchivoHistoriaClinica> archivos = hcDTO.getArchivos().stream()
                    .map(archivoHistoriaClinicaMapper::toEntity)
                    .collect(Collectors.toList());
            hc.setArchivos(archivos);
            actualizaciones.forEach(actualizacion -> actualizacion.setHistoriaClinica(hc));
            archivos.forEach(archivo -> archivo.setHistoriaClinica(hc));
    
            entityManager.persist(hc);
            return hc;
        }
    

    以及终点:

    @PostMapping("/nuevas/{idPaciente}")
    public ResponseEntity<HistoriaClinicaDTO> createHistoriaClinica(@RequestBody HistoriaClinicaDTO historiaClinicaDTO, @PathVariable("idPaciente") Long pacienteId) {
        // Verificar si el paciente existe
        Optional<Paciente> pacienteOptional = pacienteService.buscarPorId(pacienteId);
        if (!pacienteOptional.isPresent()) {
            throw new RuntimeException("No se encontró un paciente con el ID proporcionado.");
        }
    
        HistoriaClinica nuevaHistoriaClinica = historiaClinicaService.save(historiaClinicaDTO, pacienteId);
    
        HistoriaClinicaDTO newHistoriaClinicaDTO = historiaClinicaMapper.toDto(nuevaHistoriaClinica);
    
        return ResponseEntity.ok(newHistoriaClinicaDTO);
    }
    

    我试着调试代码并在每一步检查值,但我无法确定NullPointerException的根本原因。如果您能就如何排除和解决此问题提供任何见解或建议,我将不胜感激。

    提前感谢您的帮助!

    以下是我迄今为止检查的内容:

    • “Paciente”实体有一个生成的“id”字段,在保存新实例时会自动分配该字段。
    • “HistoriaClinica”实体与“Paciente”具有多对一关系,并且该关联使用“pacient_id”外键进行了正确定义。
    • 从存储库检索“Paciente”时,会成功找到并返回它。
    • 在“历史临床”实体中设置“Paciente”对象之前,我已验证该对象是否具有有效ID。
    • 我已经检查了数据库,并且关联的“Paciente”记录具有有效的ID。
    • 尽管进行了这些检查,但在尝试持久化“HistoriaClinia”实体时,我仍然会遇到“NullPointerException”,消息中指出“pacientId不得为null”。
    0 回复  |  直到 2 年前