Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Erro spring - Conexão fechada

Erro spring conexão fechada. Fiz as alterações do @Repository e @Autowired, porém quando chamo no browser a /listaContas pela segunda vez, a conexão está sempre fechada.

Parece que depois que o Spring instancia pela primeira vez, as demais não são novamente instanciadas.

Erro:

java.lang.RuntimeException: java.sql.SQLException: Connection is closed.
    br.com.caelum.contas.dao.ContaDAO.adiciona(ContaDAO.java:46)
    br.com.caelum.contas.controller.ContaController.adicionaConta(ContaController.java:41)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:644)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
@Repository
public class ContaDAO {
    private Connection connection;

    @Autowired
    public ContaDAO(DataSource ds) {
        try {
            this.connection = ds.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
//outros metodos
@Controller
public class ContaController {

    private ContaDAO dao;

    @Autowired
    public ContaController(ContaDAO dao) {
        this.dao = dao;
    }

    @RequestMapping("/form")
    public String form() {
        return "form";
    }

    @RequestMapping("/adicionaConta")
    public String adicionaConta(@Valid Conta conta, BindingResult result) {

        if (result.hasErrors()) {
            return "form";
        }    

        //System.out.println("Conta --> " + conta.getDescricao());
        dao.adiciona(conta);        
        return "conta_adicionada";
    }

    @RequestMapping("/listaContas")
    public ModelAndView listaContas() {        
        List<Conta> contas = dao.lista();

        ModelAndView mv = new ModelAndView("conta/lista");
        mv.addObject("contas", contas);

        return mv;
    }

    //outro jeito de mandar dados para a view atraves de Model somente
    @RequestMapping("/listaContas2")
    public String listaContas(Model mv) {        
        List<Conta> contas = dao.lista();        
        mv.addAttribute("contas", contas);        
        return "conta/lista";
    }

    @RequestMapping("/removeConta")
    public String removeConta(Conta conta) {        
        dao.remove(conta);
        //return "conta/remove";
        //para redirecionar para a listagem novamente, teria que replicar o cídog do listaContas
        //o mais correto é redirecionar
        //tem duas formas (lado servidor - forward) e (lado cliente - redirect)
        //forward deixa a url como removeConta?conta.id=2, o que se chamada de novo pelo usuário
        //leva ao erro de tentar excluir uma conta já excluida
        //redirect envio o browser para listaContas, o q é mais correto
        //return "forward:listaContas";
        return "redirect:listaContas";
    }

    @RequestMapping("/mostraConta")
    public String mostra(Long id, Model model) {
        Conta conta = dao.buscaPorId(id);
        model.addAttribute("conta", conta);
        return "conta/mostra";
    }

    @RequestMapping("/alteraConta")
    public String altera(Conta conta) {
        dao.altera(conta);        
        return "redirect:listaContas";
    }

    @RequestMapping("/pagaConta")
    public void finaliza(Long id, HttpServletResponse response) {      
      dao.paga(id);
      response.setStatus(200);
    }
}
5 respostas

Também estou enfrentando o mesmo problema.

José, o Victor esclareceu o problema no tópico "Fechamento conexao".

Dê uma olhada lá.

Resolveu aqui.

Abraços.

Muito Obrigado, Ricardo.

Resolveu a dúvida. Acho que seria interessante a Caelum mencionar isso no curso já que isso é bastante esclarecedor e deve ser dúvida de todos que fazem o curso.

Abraços,

tive o mesmo problema e foi também resolvido com o link acima