Проблема Spring getOne (id) — значение существующего идентификатора равно нулю

#java #spring #hibernate #spring-boot

#java #spring #переход в спящий режим #spring-boot

Вопрос:

Я использую в своем проекте более новую версию Spring-boot, поэтому вместо findById (длинный идентификатор) я использую getOne (длинный идентификатор) (необязательный findById у меня не работал). Мой метод «сохранить новую форму» работает нормально, и база данных SQL создает идентификатор для отправленной формы (он же брокер). Но при редактировании формы я не могу получить доступ к существующему идентификатору и получаю ошибку null. Не мог бы кто-нибудь, пожалуйста, указать мне правильное направление здесь. Это потому, что я использую метод getOne, который возвращает значение null, или что-то еще вызывает эту проблему?

Вот стек трассировки, показывающий ошибку 500 из-за наличия нулевого идентификатора.

 2019-03-08 14:58:32.416 DEBUG 988 --- [p-nio-64-exec-1] o.s.web.servlet.DispatcherServlet        : "ERROR" dispatch for POST "/error", parameters={masked}
2019-03-08 14:58:32.417 DEBUG 988 --- [p-nio-64-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2019-03-08 14:58:32.418 DEBUG 988 --- [p-nio-64-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Using 'application/json', given [*/*] and supported [application/json, application/* json, application/json, application/* json]
2019-03-08 14:58:32.418 DEBUG 988 --- [p-nio-64-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Writing [{timestamp=Fri Mar 08 14:58:32 PST 2019, status=500, error=Internal Server Error, message=The given id must not be null!; nested exception is java.lang.IllegalArgumentException: The given id must not be null!, path=/saveBroker}]
2019-03-08 14:58:32.419 DEBUG 988 --- [p-nio-64-exec-1] o.s.web.servlet.DispatcherServlet        : Exiting from "ERROR" dispatch, status 500
  

Вот мои функции контроллера:

  @RequestMapping(value="/newBroker")
    public String newBroker(Model model){
        model.addAttribute("broker",new Broker());
        return "brokerProfile";
    }

    @RequestMapping(value="/addBroker")
    public String addBroker(Model model, @ModelAttribute(value="broker") Broker broker)
    {
        Long id=null;
        try{
            Broker newBroker = brokerRepository.save(broker);
            id = newBroker.getId();
            if (broker.getStatus().equals("active"))
                broker.setOnboardedDate(LocalDate.now());
            brokerRepository.save(newBroker);
        }catch (DataAccessException e){
            e.printStackTrace();
        }

        return "redirect:/edit/" id;
    }

    @RequestMapping(value="/edit/{id}")
    public String editbroker(Model model, @PathVariable("id") Long id, Broker broker){
        Broker existing= brokerRepository.getOne(id);
        model.addAttribute("broker",existing);
        return "brokerProfile";
    }


    @RequestMapping(value="/saveBroker")
    @ResponseBody
    public JSONObject saveBroker(Model model, @ModelAttribute(value="broker") Broker broker)
    {
        Boolean saved=false;
        JSONObject response=new JSONObject();
        Broker brokerBeforeUpdate = brokerRepository.getOne(broker.getId());

        if (brokerBeforeUpdate!=null amp;amp; !brokerBeforeUpdate.getStatus().equals("active") amp;amp; broker.getStatus().equals("active"))
            broker.setOnboardedDate(LocalDate.now());
        else if (!broker.getStatus().equals("active"))
            broker.setOnboardedDate(null);
            try{
                brokerBeforeUpdate=brokerRepository.save(broker);
                saved=true;
                response.put("brokerId",broker.getId());

            }catch (DataAccessException e) {
                e.printStackTrace();
                response.put("error",e.getLocalizedMessage());
                response.put("cause",e.getLocalizedMessage());
            }
        response.put("success",saved);
        return response;
    }
}
  

Мой репозиторий, содержащий getOne () / findById

 public interface BrokerRepository extends CrudRepository<Broker,Long>, JpaSpecificationExecutor {

    Broker save(Broker entity);

//    <Optional>Broker findById(Long id);

    Broker getOne(Long id);


    void delete(Broker entity);

    List<Broker> findAll();

}
  

Брокер. фрагмент Java, относящийся к ID

 @Entity
@Table(name="Broker")
public class Broker {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "brokerId")
    private Long id;

        public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

}
  

Комментарии:

1. я не вижу этого метода в CrudRepository docs.spring.io/spring-data/commons/docs/current/api/org / …

2. @Deadpool если я использую brokerRepository.findById(broker.getId()); Я получаю эту ошибку: Ошибка: (61, 53) java: ссылка на findById неоднозначна для обоих методов findById (ID) в org.springframework.data.repository. CrudRepository и метод <Необязательно>findById (java.lang. Долго) в com.project1.repositories. Совпадение репозитория BrokerRepository. Я нашел опцию getOne в вопросе stackoverflow.

3. @Deadpool, я не уверен, как использовать опции. Если я изменю его на <Необязательно> B findById (длинный идентификатор), как я должен вызывать это в своих функциях? brokerRepository.findById(—что здесь происходит??—) ?

4. brokerRepository.findById( ---what goes in here??---) идентификатор отправляется туда brokerRepository.findById( id)

5. @Deadpool Это не работает, потому что я получаю ошибку: java: ссылка на findById неоднозначна для обоих методов findById (ID) org.springframework.data.repository. CrudRepository и метод <Необязательно>findById (java.lang. Длинный) в com. Портал.репозитории. Совпадение репозитория BrokerRepository

Ответ №1:

Я думаю, вам нужно указать метод, используемый в @RequestMethod, потому что у него нет значения по умолчанию

 @RequestMapping(path="/",method=RequestMethod.GET or POST)
  

но вы используете это вместо @RequestMethod

 @PostMethod(path='/')
@GetMethod(path='/')

  

Комментарии:

1. GET по умолчанию для @RequestMapping

2. Я не уверен, что проблема в @RequestMapping, поскольку он публикует новых брокеров. Если я укажу Post метода Get, мне придется повторить код в методе, чтобы он работал для обоих, иначе я получу ошибку 405. Нет ли способа заставить метод работать при поиске идентификатора?