Невозможно вызвать «String.hashCode()», поскольку «<local4>» имеет значение null

Я получаю сообщение об ошибке при выполнении теста

package com.***.cmp.cgw.webclient.restcontroller.anagrafica;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;


import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@Disabled("Test per prove manuali, da raffinare")
@SpringBootTest
@AutoConfigureMockMvc
class RicercaAnagraficaBancaRestControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    void getPersonaFisica() throws Exception {
        mvc.perform(MockMvcRequestBuilders
                        .get("/ricerca/anagrafica")
                        .param("abi", String.valueOf(55))
                        .param("ndg", "00259055")
                        .accept(MediaType.APPLICATION_JSON))
                .andDo(print())
                .andExpect(status().isOk());
    }
}

Результат:

MockHttpServletResponse: Статус = 500 Сообщение об ошибке = ноль Заголовки = [Vary: «Происхождение», «Метод-запрос-контроля-доступа», «Заголовки-запроса-контроля-доступа», Content-Type: «application/json», X-Content-Type-Options: «nosniff», X-XSS-Protection: «0», Cache-Control: «без кэша, без хранения, максимальный возраст = 0, необходимо выполнить повторную проверку», Прагма: «без кэша», Срок действия: «0», Параметры X-Frame: «DENY»] Тип контента = приложение/json Body = {"errorMessage":"Невозможно вызвать "String.hashCode()", поскольку "<local4>" имеет значение null","Exception":null} URL-адрес перенаправления = null URL-адрес перенаправления = null Файлы cookie = []

Вызываемый контроллер

package com.****.cmp.cgw.webclient.restcontroller.anagrafica;

import com.****.cmp.cgw.webclient.dto.DatiAzienda;
import com.****.cmp.cgw.webclient.dto.DatiDittaIndividuale;
import com.****.cmp.cgw.webclient.dto.DatiPersonaFisica;
import com.****.cmp.cgw.webclient.dto.ricercabanca.ClienteDTO;
import com.****.cmp.cgw.webclient.dto.ricercabanca.Dati;
import com.****.cmp.cgw.webclient.dto.ricercabanca.Residenza;
import com.****.cmp.cgw.webclient.enumeration.TipoCliente;
import org.jetbrains.annotations.NotNull;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.****.cgw.webclient.model.integration.Ana02Repr;
import com.****.cgw.webclient.model.integration.Ana02Req;
import com.****.cmp.cgw.webclient.client.****IntegrationApiClient;

import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;

import java.util.*;

import static com.****.cmp.cgw.webclient.enumeration.TipoCliente.*;

@RestController
@RequestMapping("/ricerca")
public class RicercaAnagraficaBancaRestController {

    @Autowired
    private ****IntegrationApiClient client;

    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "Cliente recuperato",
                    content = { @Content(mediaType = "application/json") }),})
    @GetMapping(path = "/anagrafica", produces = MediaType.APPLICATION_JSON_VALUE)
    public com.****.cmp.cgw.webclient.dto.ApiResponse<ClienteDTO>
    getClientByAnagrafica(@RequestParam int abi,
                          @RequestParam String ndg) {

        ResponseEntity<Ana02Repr> ana02ReprResponseEntity = client.ana02(createRequest(abi, ndg));

        //todo: cambiare setting una volta capito parametro

        return toApiResponse(ana02ReprResponseEntity);
    }

    private @NotNull Ana02Req createRequest(int abi, String ndg) {
        Ana02Req ana02Req = new Ana02Req();
        ana02Req.setCag(ndg);
        //todo: ndg da paddare a 8 con 0 iniziali
        ana02Req.setCodAbiUser(abi);
        ana02Req.codUser("fk0232"); //todo: utente di Ilario, da cambiare
        ana02Req.setCodFiliale("CE");
        return ana02Req;
    }

    private @NotNull com.****.cmp.cgw.webclient.dto.ApiResponse<ClienteDTO> toApiResponse(ResponseEntity<Ana02Repr> ana02ReprResponseEntity) {
        ClienteDTO clienteDTO = RicercaAnagraficaBancaMapper.INSTANCE.mapToClienteDTO(Objects.requireNonNull(ana02ReprResponseEntity.getBody()));

        com.****.cmp.cgw.webclient.dto.ApiResponse<ClienteDTO> apiResponse =
                new com.****.cmp.cgw.webclient.dto.ApiResponse<>();

        apiResponse.getContent().setValue(clienteDTO);

        apiResponse.setStatusCode(200);
        apiResponse.setMessage("Dettagli ndg recuperati correttamente");

        com.****.cmp.cgw.webclient.dto.ApiResponse.ApiAction apiAction =
                new com.****.cmp.cgw.webclient.dto.ApiResponse.ApiAction();

        apiAction.setMethod("GET");
        apiAction.setUrl("v1/searchReports");

        Map<String, com.****.cmp.cgw.webclient.dto.ApiResponse.ApiAction> action = new HashMap<>();

        action.put("search", apiAction);

        apiResponse.getContent().setActions(action);
        return apiResponse;
    }

    @Mapper
    @Component
    public interface RicercaAnagraficaBancaMapper {
        RicercaAnagraficaBancaMapper INSTANCE = Mappers.getMapper(RicercaAnagraficaBancaMapper.class);

        //todo: refactoring con funzioni mapstruct


        default ClienteDTO mapToClienteDTO(Ana02Repr ana02Repr){
            String segmentoCommerciale = ana02Repr.getSegmCommerciale();

            //todo: mapping da confermare
            TipoCliente tipoCliente = switch (segmentoCommerciale) {
                case "PF", "DF" -> PERSONA_FISICA;
                case "DI" -> DITTA_INDIVIDUALE;
                case "CM", "CG", "CF", "SG", "NG", "PG" -> SOCIETA;
                default -> throw new IllegalStateException("Valore non previsto in ana02 " +
                        "per segmento commerciale: " + segmentoCommerciale);
            };

            Residenza residenza = switch (tipoCliente) {
                case PERSONA_FISICA -> toResidenzaPersonaFisica(ana02Repr);
                case DITTA_INDIVIDUALE, SOCIETA -> toResidenzaPersonaGiuridica(ana02Repr);
            };

            Dati dati = switch (tipoCliente) {
                case PERSONA_FISICA -> toDatiPersonaFisica(ana02Repr);
                case DITTA_INDIVIDUALE -> toDatiDittaIndividuale(ana02Repr);
                case SOCIETA -> toDatiSocieta(ana02Repr);
            };

            ClienteDTO clienteDTO = new ClienteDTO();

            clienteDTO.setTipologia(tipoCliente.toString());
            clienteDTO.setResidenza(residenza);
            clienteDTO.setDati(dati);

            return clienteDTO;
        }

        @Mapping(source = "resIndirizzo", target = "indirizzo")
        @Mapping(source = "resComune", target = "localita")
        @Mapping(source = "resCap", target = "cap")
        @Mapping(source = "resProvincia", target = "provincia")
        @Mapping(source = "resNazDes", target = "nazione")
        Residenza toResidenzaPersonaFisica(Ana02Repr source);

        @Mapping(source = "legIndirizzo", target = "indirizzo")
        @Mapping(source = "legComune", target = "localita")
        @Mapping(source = "legCap", target = "cap")
        @Mapping(source = "legProvincia", target = "provincia")
        @Mapping(source = "legNazDes", target = "nazione")
        Residenza toResidenzaPersonaGiuridica(Ana02Repr source);

        //todo: la data come va formattata?
        @Mapping(source = "codFiscale", target = "codiceFiscale")
        @Mapping(source = "sesso", target = "sesso")
        @Mapping(source = "nome", target = "nome")
        @Mapping(source = "cognome", target = "cognome")
        @Mapping(source = "nascData", target = "dataNascita")
        @Mapping(source = "nascLuogo", target = "luogoNascita")
        @Mapping(source = "nascProvincia", target = "provinciaNascita")
        @Mapping(source = "nascNazDes", target = "nazioneNascita")
        DatiPersonaFisica toDatiPersonaFisica(Ana02Repr source);

        @Mapping(source = "intestaz", target = "denominazione")
        @Mapping(source = "codFiscale", target = "codiceFiscale")
        @Mapping(source = "sesso", target = "sesso")
        @Mapping(source = "nome", target = "nome")
        @Mapping(source = "cognome", target = "cognome")
        @Mapping(source = "nascData", target = "dataNascita")
        @Mapping(source = "nascLuogo", target = "luogoNascita")
        @Mapping(source = "nascProvincia", target = "provinciaNascita")
        @Mapping(source = "nascNazDes", target = "nazioneNascita")
        @Mapping(source = "raeCod", target = "numeroRea")
        @Mapping(source = "cciaaProvincia", target = "provinciaCCIA")
        @Mapping(source = "partitaIva", target = "partitaIVA")
        DatiDittaIndividuale toDatiDittaIndividuale(Ana02Repr source);

        @Mapping(source = "intestaz", target = "denominazione")
        @Mapping(source = "desTipoControparte", target = "specieGiuridica")
        @Mapping(source = "raeCod", target = "numeroRea")
        @Mapping(source = "cciaaProvincia", target = "provinciaCCIA")
        @Mapping(source = "partitaIva", target = "partitaIVA")
        @Mapping(source = "codFiscale", target = "codiceFiscale")
        DatiAzienda toDatiSocieta(Ana02Repr source);

    }

}

Проблема в том, что я не могу найти, с чем связана эта ошибка. Даже в сети есть только один пример, но, похоже, это не мой случай.

Обновлено: вопрос не в нулевом указателе, а в

{"errorMessage":"Cannot invoke "String.hashCode()" because "<local4>" is null","exception":null}

поэтому, очевидно, это не дубликат общего вопроса об исключении нулевого указателя!

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
672
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема заключалась в анализе неправильного поля. ana02Repr.getSegmCommerciale() всегда возвращается ноль. Я до сих пор не знаю, почему он не вернул более описательную ошибку.

Другие вопросы по теме