Correção na fj-21

Boa tarde a todos,

Gostaria de divulgar aqui um pequeno problema que ocorreu comigo enquanto apreciava a apostila de desenvolvimento web da caelum, a fj-21.

No exercício 2.11 da página (pagina 17 e 18) ele faz um pequeno código para conexao e inserção ao banco de dados:

O código gerado pelo eclipse seguindo a risca a apostila fica da seguinte forma

Classe Contato:

package br.com.caelum.jdbc.modelo;

import java.util.Calendar;

public class Contato {
	private Long id;
	private String nome;
	private String email;
	private String endereco;
	private Calendar dataNascimento;
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getEndereco() {
		return endereco;
	}
	public void setEndereco(String endereco) {
		this.endereco = endereco;
	}
	public Calendar getDataNascimento() {
		return dataNascimento;
	}
	public void setDataNascimento(Calendar dataNascimento) {
		this.dataNascimento = dataNascimento;
	}
}

O problema encontrado foi na classe seguinte, ContatoDAO

Na apostila está dessa forma:

package br.com.caelum.jdbc.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;

import br.com.caelum.jdbc.ConnectionFactory;
import br.com.caelum.jdbc.modelo.Contato;

public class ContatoDAO {

	// a conexao com o banco de dados
	private Connection connection;
	
	public ContatoDAO() {
		this.connection = new ConnectionFactory().getConnection();
	}
	
	public void adiciona(Contato contato) {
		String sql = "insert into contatos (nome,email,endereco,dataNascimento) values (?,?,?,?)";
		
		try {
			// prepared statement para inserção
			PreparedStatement stmt = connection.prepareStatement(sql);
			
			// seta os valores
			stmt.setString(1, contato.getNome());
			stmt.setString(2, contato.getEmail());
			stmt.setString(3, contato.getEndereco());
			stmt.setDate(4, new Date(contato.getDataNascimento().getTimeInMillis()));
			
			// executa
			stmt.execute();
			stmt.close();
		} catch (SQLException e) {
			throw new RuntimeException();
		}
	}
}

Porém, quando você cria a classe seguinte (TestaInsere) ele dá um problema de compilação:

Conectado ao Banco de Dados!
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The method setDate(int, Date) in the type PreparedStatement is not applicable for the arguments (int, Date)

	at br.com.caelum.jdbc.dao.ContatoDAO.adiciona(ContatoDAO.java:31)
	at br.com.caelum.jdbc.teste.TestaInsere.main(TestaInsere.java:22)

Como fiz e refiz tudo com a máxima atenção, tentei descobrir o problema: e o problema está nesta linha em ContatoDAO

stmt.setDate(4, new Date(contato.getDataNascimento().getTimeInMillis()));

Ao invés de utilizar desta forma, com a ajuda do compilador, propus a seguinte solução e funcionou sem problemas:

stmt.setDate(4, new java.sql.Date(contato.getDataNascimento().getTimeInMillis()));

Caso eu não tenha errado nada, ou esqueça de algo (estou iniciando em desenvolvimento web com java), me digam. Caso contrário, esta é uma sugestão de atualização.

Que, por sinal, é excelente! Parabéns aos que ajudaram a construir, estou achando um máximo estudar por ela.

Obrigado

Posta o seu TesteInsere ai

package br.com.caelum.jdbc.teste;

import java.util.Calendar;

import br.com.caelum.jdbc.dao.ContatoDAO;
import br.com.caelum.jdbc.modelo.Contato;

public class TestaInsere {
	public static void main(String[] args) {
		
		// pronto para gravar
		Contato contato = new Contato();
		contato.setNome("Caelum");
		contato.setEmail("contato@caelum.com.br");
		contato.setEndereco("R. Vergueiro 3185 cj57");
		contato.setDataNascimento(Calendar.getInstance());
		
		// grave nessa conexao !
		ContatoDAO dao = new ContatoDAO();
		
		// método elegante
		dao.adiciona(contato);
		
		System.out.println("Gravado!");
	}
}

Feito dessa forma que propus, evitei tbm um pequeno problema que surgiu de casting, entre as classes java.sql.date e java.util.date. Utilizo o eclipse helios

Sendo mais simples, acho que em vez de vc colocar o nome completo da classe (java.sql.Date), vc poderia dar um import desta classe, em vez de dar importa da java.util.Date.

Não tenho como testar, mas isso deve resolver este problema de forma mais fácil…

[quote=felipe.sales]Sendo mais simples, acho que em vez de vc colocar o nome completo da classe (java.sql.Date), vc poderia dar um import desta classe, em vez de dar importa da java.util.Date.

Não tenho como testar, mas isso deve resolver este problema de forma mais fácil…[/quote]

Faça como citado acima, importe java.sql.Date não o java.util.Date como vc fez na classe ContatoDAO.

Isso é citado na apostila após o código na página 19:[quote] Lembre-se de importar as classes de SQL do pacote java.sql, inclusive a classe Date![/quote]

oi sharingan! é realmente isso: na hora de dar o Organize Imports do eclipse, escolha o java.sql.Date.

legal que esteja gostando da apostila. vai gostar ainda mais quando caminhar dai para hibernate e vraptor. a gente gosta de mostrar tudo que esta por baixo dos panos, entao os primeiros capitulos estao usando as APIs na raça

so reportando outro problema… realmente a apostila é muito boa, mas no capitulo do do vraptor… ele começa um projeto… e pede para usarmos o projeto ja pronto controle-produtos… so que ele nao vem no download da apostila…

Romarcio, eu conferi agora e vc tem razão. Obrigado por ter me alertado :smiley:

Só fiz a sugestão, pq esse é um exercício passo a passo. Para um iniciante como eu, fica facilmente cunfuso quando aparece a conversão de datas! Pra ser sincero, a forma nativa de tratar datas em java é bem complicado.
Eu já li na própria API da oracle, e fico confuso de como fazer as conversões.

Um amigo sugeriu-me que ao invés de tratar nativamente, fizesse uso de uma biblioteca chamada “jodatime”. Estou começando a ver com calma essa bibilioteca agora.

Então, fica a sugestão para a apostila. A parte de datas é muito usada quando cria-se sistemas pra web, essa parte poderia ser reforçada [ou ela já é reforçada em algum lugar e eu não to sabendo?]

Se não me engano, existe um projeto de uma loja completa utilizando v-raptor + hibernate. Se não me engano é a fj-28.

Sei disso pq não vejo a hora de ver o framework (antes de aprender java, já utilizava php com o zend framework). Então, fico naquela indolência pra fazer as coisas básicas no braço, mas to segurando a onda aqui na calma :smiley: