0

Mi proyecto genera un erorr que no entiendo. Antes funcionaba muy bien el hola mundo, pero al intentar implementar una lista extraida de postgreSQL me causa error.

Tengo estos dos archivos. La clase persona que contiene un idpersona y nombre, y el repositorio IPersonaRepo que hereda de JpaRepository de la siguiente manera:

extends JpaRepository<Persona, Integer>

Este es el controller:

package com.javierito.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.javierito.model.Persona;
import com.javierito.repository.IPersonaRepo;

@Controller
public class DemoController {

    private IPersonaRepo repo;

    @GetMapping("/saludos")
    public String saludos(@RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
        Persona persona= new Persona();
        persona.setIdPersona(1);
        persona.setNombre("javierito");
        repo.save(persona);
        model.addAttribute("name", name);
        return "greeting";

    }
    @GetMapping("/lista")
    public String greeting(Model model) {
        //logica                            
        model.addAttribute("personas", repo.findAll());
        return "greeting";
    }
}

El html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <p th:text="'Hello, ' + ${name} + '!'" />

    <table>
        <th:block th:each="per : ${personas}">
            <tr>
                <td th:text="${per.idPersona}"></td>
                <td th:text="${per.nombre}"></td>
            </tr>
        </th:block>
    </table>
</body>
</html>

Este es el mensaje de error que me da en el navegador:

Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback.

Wed Jul 10 01:29:31 CLT 2019 There was an unexpected error (type=Internal Server Error, status=500). No message available java.lang.NullPointerException at com.javierito.controller.DemoController.saludos(DemoController.java:21) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:109) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Unknown Source)

cavpollo
  • 1,052
  • 5
  • 16
  • 3
    Posible duplicado de [¿Cuál es la solución a todos los errores NullPointerException presentes, pasados y futuros?](https://es.stackoverflow.com/questions/42977/cu%c3%a1l-es-la-soluci%c3%b3n-a-todos-los-errores-nullpointerexception-presentes-pasados) – kerten Jul 10 '19 at 12:42

2 Answers2

0

Efectivamente tienes un NullPointerException, y segun los logs que provees, es en la linea 21. Esta es tu primera y unica pista que necesitas, ya que en esa linea asumo que tienes lo siguiente:

repo.save(persona);

Que significa esto? Si encuetras un poco de tiempo para leer lo que @Kerten a copartido en los comentarios "¿Cuál es la solución a todos los errores NullPointerException presentes, pasados y futuros?", te daras cuenta que esto es simptoma de que tu variable repo no esta inicializada.

Ahora, el por que no esta inicializada esta variable es lo importante. Spring, con solo definir una variable global, no te proveera con la implementacion de IPersonaRepo. Para ello debes hacer un "Autowire" de dicha implementacion. Para lograr esto tienes 2 opciones.

La primera opcion es utilizar la anotacion @Autowired. Esto debes hacerlo con cada uno de los Beans que quieres incluir en tu Controller, servicio o componente:

import org.springframework.beans.factory.annotation.Autowired;

@Controller
public class DemoController {
    @Autowired
    private IPersonaRepo repo;

    ...
}

La segunda manera, es tomar ventaja de el constructor de tu clase:

import org.springframework.beans.factory.annotation.Autowired;

@Controller
public class DemoController {
    private IPersonaRepo repo;

    @Autowired
    public DemoController(IPersonaRepo repo) {
        this.repo = repo;
    }

    ...
}

A partir de Spring 4.3, el uso de la anotacion @Autowired ya no es necesaria si utilizas un solo constructor. A esto le llaman "Implicit Constructor Injection":

@Controller
public class DemoController {
    private IPersonaRepo repo;

    public DemoController(IPersonaRepo repo) {
        this.repo = repo;
    }

    ...
}
cavpollo
  • 1,052
  • 5
  • 16
0

DemoController requiere que el objeto realice su acción. Debe informar al marco de Spring para inyectar la dependencia. As cavpollo mention

Simplemente puede usar la inyección basada en el campo

@Controller
public class DemoController {

    @Autowired
    private IPersonaRepo repo;

}

Como se mencionó cavpollo, puede usar la dependencia basada en constructores. Pero la inyección basada en el campo sería más simple. Solo tenías que agregar la anotación @Autowired