Problema com SQLite

Olá pessoal, estou com dificuldades em entender qual o erro que foi gerado durante a criação do banco de dados do SQLite. Minha aplicação é em JavaFX e estou aprendendo a usar banco de dados em aplicações Java agora.
O código segue abaixo.

O erro é: java.sql.SQLException: Values not bound to statement

Minha Main.java

package controller;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import model.Veiculo;
import model.sqlite.VeiculoSQLite;

import java.util.ArrayList;

public class Main extends Application {

private static Stage stage;

private static Scene mainScene;
private static Scene datailsScene;

@Override
public void start(Stage primaryStage) throws Exception {

    Veiculo veiculo = new Veiculo("Volkswagen","Brasília",60);

    VeiculoSQLite database = new VeiculoSQLite();

    database.create(veiculo);

    System.out.println(database.all());

    System.exit(0);

    stage = primaryStage;

    primaryStage.setTitle("ExemploLOO");

    Parent fxmlMain = FXMLLoader.load(getClass().getResource("../view/main_screen.fxml"));
    mainScene = new Scene(fxmlMain, 640, 400);

    Parent fxmlDetails = FXMLLoader.load(getClass().getResource("../view/details_screen.fxml"));
    datailsScene = new Scene(fxmlDetails, 640, 400);

    primaryStage.setScene(mainScene);
    primaryStage.show();
}


public static void changeScreen(String scr, Object userData){
    switch (scr){
        case "main":
            stage.setScene(mainScene);
            notifyAllListeners("main", userData);
            break;
        case "details":
            stage.setScene(datailsScene);
            notifyAllListeners("details", userData);
            break;
    }
}

public static void changeScreen(String scr){
    changeScreen(scr, null);
}


public static void main(String[] args) {
    launch(args);
}

//----------- Observer

private static ArrayList<OnChangeScreen> listeners = new ArrayList<>();

public static interface OnChangeScreen{
    void onScreenChanged(String newScreen, Object userData);

}

public static void addOnChangeScreenListener(OnChangeScreen newListener){
    listeners.add(newListener);
}

private static void notifyAllListeners(String newScreen, Object userData){
    for(OnChangeScreen l : listeners)
        l.onScreenChanged(newScreen, userData);
}

}

Minha base p/ o SQLite

package model.sqlite;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class SQLiteBase {

    protected Connection conn;

    public Connection open(){

        try {
            conn = DriverManager.getConnection("jdbc:sqlite:my_database");
            return conn;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public void close(){
        if (conn != null)
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
    }
}

A classe que tem o objeto que trabalha com o BD

package model.sqlite;

import model.Veiculo;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class VeiculoSQLite extends SQLiteBase{

    public VeiculoSQLite(){

        open();

        try {
            PreparedStatement stm = conn.prepareStatement( "CREATE TABLE IF NOT EXISTS  Veiculos ("+
                    "id INTEGER PRIMARY KEY AUTOINCREMENT,"+
                    "marca TEXT," +
                    "modelo TEXT," +
                    "hp INTEGER);");

            stm.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close();
        }

    }

    public void create(Veiculo v){

        open();

        try {

            PreparedStatement stm = conn.prepareStatement("INSERT INTO Veiculos VALUES (?,?,?,?);");

            stm.setString(2,v.getMarca());
            stm.setString(3,v.getModelo());
            stm.setInt(4,v.getHp());

            stm.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close();
        }
    }

    public List<Veiculo>all(){
        ArrayList<Veiculo> result = new ArrayList<>();

        open();

        try {

            PreparedStatement stm = conn.prepareStatement("SELECT * FROM Veiculos ORDER BY id ASC;");

            ResultSet rs = stm.executeQuery();

            while (rs.next()){

                Veiculo v = new Veiculo(
                        rs.getInt(1),//id
                        rs.getString(2),//marca
                        rs.getString(3),//modelo
                        rs.getInt(4));//hp

                result.add(v);

            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close();
        }

        return  result;
    }

}

Se alguém puder me dar uma luz eu agradeço muito.
Até mais

Cadê o stm.setBlablabla(1, QLQ_COISA);

???

Darlan, o parâmetro 1 é o id

Poderia ser até bananas e chuchus, se você disse para o JDBC que vai informar um parâmetro, colocando um ? no código, você é obrigado a informar.
Se o campo é auto increment, você só precisa definir os parâmetros faltantes, ou seja, marca, modelo e hp, ou seja, deixando 3 ? na query e setando com início na posição 1 do PreparedStatement.

Ficaria

PreparedStatement stm = conn.prepareStatement("INSERT INTO Veiculos VALUES (?,?,?);");

      stm.setString(1,v.getMarca());
      stm.setString(2,v.getModelo());
       stm.setInt(3,v.getHp());

Assim?

Testei, não rolou

Não rolou = ???
Erro? Exceção? Em que linha de código aconteceu? Debugou? Qual o log?

Sinto informar-lhe, mas, a tabela veículos foi criada com um ID que não é auto incrementável. Caso contrário, você conseguiria.
Se quiser comprovar o que estou dizendo, pode tentar usar a query antiga, definindo isso:

PreparedStatement stm = conn.prepareStatement("INSERT INTO Veiculos VALUES (?,?,?,?);");
stm.setString(1, 111);
stm.setString(2,v.getMarca());
stm.setString(3,v.getModelo());

Darlan, quando eu troquei p/ o número ele já me reclamou, pois ele está aguardando um objeto de veículo, v.get_alguma coisa
A a IDE já me parou no erro desta linha.
Tipo o meu problema é aquele do java.sql.SQLException: Values not bound to statement

Estou aprendendo com aulas no seguinte link: https://www.youtube.com/watch?v=qar-Eqvbgaw&list=PLd4Jo6d-yhDJDu6z0luwaKpW2QD-jGVGc&index=12

Se estou aprendendo errado eu gostaria de saber como ficaria p/ fazer certo

Coisas como essa me preocupam

Eu não conheço o cara, não sei quem é, mas, essa resposta é bem suspeita.

Seguinte, ainda estou olhando os vídeos, mas, não faz nenhum sentido colocar 4 interrogações e só 3 parâmetros.
A própria documentação do SQLite exemplifica um insert, a partir do java, nos moldes do que eu orientei:, basta checar: http://www.sqlitetutorial.net/sqlite-java/insert/

Ok, irei ler a documentação

Boa tarde. Também estou assistindo essas aulas e estava com o mesmo problema. Não sei se o que eu fiz está correto, mas funcionou.

public void create(Veiculo v) {
open();

	try {
		PreparedStatement stm = conn.prepareStatement("INSERT INTO Veiculos VALUES(**null**,?,?,?);");
		
		stm.setString(**1**, v.getMarca());
		stm.setString(**2**, v.getModelo());
		stm.setInt(**3**, v.getHp());
		stm.executeUpdate();

Essas informações em negrito foi o que eu deixei diferente para as vídeo aulas.

Você resolveu de outra forma? Compartilha conosco.

Obrigado.

Desconsidera esses “*”, achei que ficaria negrito. Coloquei “null” no primeiro “?” e coloquei 1,2,3 ao invés de 2,3,4.

Gente, é por causa da versão do SQLite de vocês, baixem a 3.18 que é a que ele usa, vai funcionar

Eu estava com esse mesmo erro. Fiz assim e funcionou.

essa linha aqui:
PreparedStatement stm = conn.prepareStatement(“INSERT INTO Veiculos VALUES (?,?,?,?);”);
eu deixei assim:
PreparedStatement stm = conn.prepareStatement(“INSERT INTO Veiculos (marca, modelo, hp) VALUES (?,?,?);”);

e essas aqui:
stm.setString(2,v.getMarca());
stm.setString(3,v.getModelo());
stm.setInt(4,v.getHp());

eu deixei assim:
stm.setString(1,v.getMarca());
stm.setString(2,v.getModelo());
stm.setInt(3,v.getHp());

não sei se é a maneira mais correta, pois ainda sou iniciante em programação, mas, para o meu propósito resolveu.