Problemas ao adicionar no banco dados

7 respostas
M

Galera, tenho o seguinte problema, eu tenho uma classe matéria com os seguintes atributos:

private Long id;
	private String nome;
	private int quantidade;
//getter and setters

bem como no banco de dados, que tem os mesmos campos…

tenho um form de adição de matérias assim:

<form method="post" action="adicionaMateria">
Nome da Matéria:<br />
<input type="text" name="materia.nome"/><br />
Quantidade:<br />
<input type="text" name="materia.quantidade"/><br />
<input type="submit" value="Adicionar" />
</form>

Uso Struts 2, a Action “adicionaMateria” só chama o DAO passando uma matéria

public void adicionaMateria(Materia materia) {
		try {
			PreparedStatement stm = connection
					.prepareStatement("insert into materias(nome,quantidade) values(?,?)");
			stm.setString(1, materia.getNome());
			stm.setInt(2, materia.getQuantidade());
			stm.execute();
			stm.close();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

To pegando um erro aqui estranho, no console do eclipse da o seguinte:

GRAVE: The web application [/coisas-da-bruna] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
15/02/2011 17:29:54 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
GRAVE: The web application [/coisas-da-bruna] appears to have started a thread named [MySQL Statement Cancellation Timer] but has failed to stop it. This is very likely to create a memory leak.
15/02/2011 17:29:54 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
GRAVE: The web application [/coisas-da-bruna] created a ThreadLocal with key of type [com.opensymphony.xwork2.inject.ContainerImpl$10] (value [com.opensymphony.xwork2.inject.ContainerImpl$10@165ab39]) and a value of type [java.lang.Object[]] (value [[Ljava.lang.Object;@1cc5d23]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak. 
15/02/2011 17:29:55 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info

alguma idéia do que pode ser?

7 Respostas

F

Connection.close() omisso talvez?

M

Bem lembrado, mas continua dando erro, mas agora sumiram aqueles do console e agora na página ta dando NullPointer na linha do nome no adiciona do DAO, mas eu preencho os dois campos…

teria algum método pra fazer no DAO pra sempre que sair do DAO ele fechar a conexão ou tem que colocar um connection.close(); em todos os métodos?

java.lang.NullPointerException
	br.com.bruna.dao.MateriasDAO.adicionaMateria(MateriasDAO.java:59)
	br.com.bruna.actions.MateriaAction.adicionar(MateriaAction.java:61)
	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)
	com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:441)
	com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:280)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:243)
	br.com.bruna.interceptor.AutorizadorInterceptor.intercept(AutorizadorInterceptor.java:26)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
	org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
	org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:488)
	org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
	org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)

edit: achei, tinha colocado o interceptor no lugar errado

vlw

R

Pode tentar colocar o close no finally do try.

public void adicionaMateria(Materia materia) {
PreparedStatement stm = null;
		try {
			stm = connection
					.prepareStatement("insert into materias(nome,quantidade) values(?,?)");
			stm.setString(1, materia.getNome());
			stm.setInt(2, materia.getQuantidade());
			stm.execute();
			
		} catch (SQLException e) {
			throw new RuntimeException(e);
		} finally {
                        stm.close();
                }

	}
M

Sim, mas eu tenho vários métodos dentro da classe, e todos fazem conexão com o bd, não teria um método da classe funcionasse como um finally?

F
Usa um Singleton de conexao. Para que ele faça a conexao somente uma vez e fique disponivel para todos os metodos.
public class ConnectionFactory {  
           
                 
      private static ConnectionFactory connectionFactory = null;  
       private static Connection connection = null;  
        
       private String url         = "jdbc:postgresql://localhost:5432/db";     
       private String username  = "user";  
      private String password  = "senha";  
  
  
      private ConnectionFactory(){   }  
     
  
      public static ConnectionFactory getInstance(){  
              
            if(connectionFactory == null)  
               connectionFactory = new ConnectionFactory();   
  
            return connectionFactory;  
  
      }  
  
  
                    
      public Connection getConnection() throws ConnectionException{  
  
            if(connection == null){  
                 try {  
                      DriverManager.registerDriver(new Driver());  
                      connection = DriverManager.getConnection(url, username, password);  
                }   
                catch (SQLException e) {  
                  System.out.println("\n>> Problema ao obter conexao\n");  
                  e.printStackTrace();  
                  throw new ConnectionException();  
               }  
            }  
  
         return connection;  
           }  
  
  
  
        
          public void closeConnection(){  
  
           if(connection != null){  
  
               try {     
                                                 connection.close();   
                                        }   
               catch (SQLException e) {  
  
                  System.out.println("\n>> Problema ao fechar conexao\n");  
                  e.printStackTrace();  
  
               }  
         }  
      
          }  
             
  
  
  
                public void finalize(){  
                         
                         closeConnection();  
               }  
  
  
   }
Connection conexao = ConnectionFactory.getInstance()
//termino de usar 

conexao.closeConnection();
M

Não conheço como funciona o Singleton, dei uma pesquisada aqui e pelo o que eu entendi é um design pattern que só te deixa instanciar a classe uma única vez, é isso?

R

Pensando em design simples, poderia criar um método que faz o execute e trata a exceção, fechando a conexão:

public void execute(PreparedStatement stm) throws Exception {

		if (stm == null) {
			throw new NullPointerException();
		}

		try{
			stm.execute();
		} catch(SQLException e) {  
			throw new RuntimeException(e);  
		} finally {
			stm.close();  
		}  

	}

Aí, nos outros métodos, chamar esse novo método.

public void adicionaMateria(Materia materia) {
		PreparedStatement stm = null;
		try {
			stm = connection
					.prepareStatement("insert into materias(nome,quantidade) values(?,?)");
			 stm.setString(1, materia.getNome());  
	         stm.setInt(2, materia.getQuantidade());
			execute(stm);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}
Criado 15 de fevereiro de 2011
Ultima resposta 15 de fev. de 2011
Respostas 7
Participantes 3