[RESOLVIDO]Select não retorna data - banco MySQL

Amigos ;

Sou novato no fórum e estou com um problema que pode ser uma besteira para resolver, mas está me empacando meu sistema em Javafx e peço a ajuda de todos para uma solução.
Tenho um formulário em que são inseridos vários dados, inclusive a data via DatePicker. Todos os dados são inseridos corretamente em uma tabela no banco MySQL com campo DATE, marcado com NOT NULL. Consigo inserir e alterar os dados.
O problema está em fazer uma consulta ao banco de dados. Se uso “SELECT * FROM processos”, ocorre o erro: “java.sql.SQLException: Value ‘0000-00-00’ can not be represented as java.sql.Date”. Agora, se uso: "“SELECT * FROM processos WHERE data BETWEEN ‘2000-01-12’ AND ‘2040-01-12’”, a consulta é feita sem erros.
Alguns dados para auxiliar a análise do problema:
O model é o arquivo Processos.java:
package sistemaGab.model.domain;

import java.io.Serializable;
import java.time.LocalDate;


public class Processos implements Serializable
  {
    private int id;
    private String numero;
    private String requerente;
    private String requerido;
    private String nomeClasse;
    private String liminar;
    
    private LocalDate dataDistribuicao;
    
    private Classes classe;
    
    public Processos()
      {
        
      }
    
    public Processos (int id, String numero, String requerente, String requerido, String nomeClasse, String liminar, LocalDate dataDistribuicao)
      {
        this.id = id;
        this.numero = numero;
        this.requerente = requerente;
        this.requerido = requerido;
        this.nomeClasse = nomeClasse;
        this.liminar = liminar;
        this.dataDistribuicao = dataDistribuicao;
      }

    public int getId()
      {
        return id;
      }

    public String getNumero()
      {
        return numero;
      }

    public String getRequerente()
      {
        return requerente;
      }

    public String getRequerido()
      {
        return requerido;
      }
    
    public String getnomeClasse()
      {
        return nomeClasse;
      }
    
     public String getLiminar()
      {
        return liminar;
      }
     
     public LocalDate getDataDistribuicao()
       {
         return dataDistribuicao;
       }

    public void setId(int id)
      {
        this.id = id;
      }

    public void setNumero(String numero)
      {
        this.numero = numero;
      }

    public void setRequerente(String requerente)
      {
        this.requerente = requerente;
      }

    public void setRequerido(String requerido)
      {
        this.requerido = requerido;
      }
    
    public void setNomeClasse(String nomeClasse)
      {
        this.nomeClasse = nomeClasse;
      }
    
    public void setLiminar(String liminar)
      {
        this.liminar = liminar;
      }
    
    public void setDataDistribuicao(LocalDate dataDistribuicao)
      {
        this.dataDistribuicao = dataDistribuicao;
      }
    
    public Classes getClasse()
      {
        return classe;
      }
    
    public void setClasse(Classes classe)
      {
        this.classe = classe;
      }
   
  }

O DAO, é o arquivo ProcessoDAO.java:
package sistemaGab.model.dao;

import java.io.IOException;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import sistemaGab.model.domain.Processos;
import sistemaGab.model.domain.Classes;


public class ProcessoDAO {

    private Connection connection;

    public Connection getConnection() 
    {
        return connection;
    }

    public void setConnection(Connection connection) 
    {
        this.connection = connection;
    }
    
    public boolean inserir(Processos processo) {
        String sql = "INSERT INTO processos(data, numero, requerente, requerido, idClasse, liminar) VALUES(?,?,?,?,?,?)";
        try {
            PreparedStatement stmt = connection.prepareStatement(sql);
            
            stmt.setDate(1, Date.valueOf(processo.getDataDistribuicao()));
            stmt.setString(2, processo.getNumero());
            stmt.setString(3, processo.getRequerente());
            stmt.setString(4, processo.getRequerido());
            stmt.setInt(5, processo.getClasse().getIdClasse());
            stmt.setString(6, processo.getLiminar());

            stmt.execute();
            
    
            return true;
        } catch (SQLException ex) {
            Logger.getLogger(ProcessoDAO.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }
    
    public boolean alterar(Processos processo) throws IOException {
        String sql = "UPDATE processos SET numero=?, requerente=?, requerido=?, idClasse=?, liminar=?, data=? WHERE id=?";
        try {
            PreparedStatement stmt = connection.prepareStatement(sql);
            stmt.setString(1, processo.getNumero());
            stmt.setString(2, processo.getRequerente());
            stmt.setString(3, processo.getRequerido());
            stmt.setInt(4, processo.getClasse().getIdClasse());
            stmt.setString(5, processo.getLiminar());
            stmt.setDate(6, Date.valueOf(processo.getDataDistribuicao()));
            stmt.setInt(7, processo.getId());
            
            stmt.execute();
            return true;
        } catch (SQLException ex) {
            Logger.getLogger(ProcessoDAO.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }
    
    public boolean remover(Processos processo) {
        String sql = "DELETE FROM processos WHERE id=?";
        try {
            PreparedStatement stmt = connection.prepareStatement(sql);
            stmt.setInt(1, processo.getId());
            stmt.execute();
            return true;
        } catch (SQLException ex) {
            Logger.getLogger(ProcessoDAO.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }

    public List<Processos> listar() {
        String sql = "SELECT * FROM processos WHERE data BETWEEN '2000-01-12' AND '2040-01-12'";
        
        List<Processos> retorno = new ArrayList<>();
        try {
            PreparedStatement stmt = connection.prepareStatement(sql);
            ResultSet resultado = stmt.executeQuery();
            while (resultado.next()) {
                Processos processo = new Processos();
                Classes classe = new Classes();
                processo.setId(resultado.getInt("id"));
                processo.setNumero(resultado.getString("numero"));
                processo.setRequerente(resultado.getString("requerente"));
                processo.setRequerido(resultado.getString("requerido"));
                processo.setLiminar(resultado.getString("liminar"));
                processo.setDataDistribuicao(resultado.getDate("data").toLocalDate());
                classe.setIdClasse(resultado.getInt("idClasse"));
                
                ClasseDAO classeDAO = new ClasseDAO();
                classeDAO.setConnection(connection);
                classe = classeDAO.buscar(classe);
             
                processo.setClasse(classe);
                retorno.add(processo);
            }
        } catch (SQLException ex) {
            Logger.getLogger(ProcessoDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return retorno;
    }

    public Processos buscar(Processos processo) {
        String sql = "SELECT * FROM processos WHERE id=?";
        Classes classe = new Classes();
        Processos retorno = new Processos();
        try {
            PreparedStatement stmt = connection.prepareStatement(sql);
            stmt.setInt(1, processo.getId());
            ResultSet resultado = stmt.executeQuery();
            if (resultado.next()) {
                classe.setIdClasse(resultado.getInt("idClasse"));
                processo.setNumero(resultado.getString("numero"));
                processo.setRequerente(resultado.getString("requerente"));
                processo.setRequerido(resultado.getString("requerido"));
                processo.setDataDistribuicao(resultado.getDate("dataDistribuicao").toLocalDate());
                retorno = processo;
            }
        } catch (SQLException ex) {
            Logger.getLogger(ProcessoDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return retorno;
    }
    
     
}

O controller da tela de cadastro está assim:
package sistemaGab.controller;

import com.jfoenix.controls.JFXButton;
import java.net.URL;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.web.HTMLEditor;
import javafx.stage.Stage;
import sistemaGab.model.dao.ClasseDAO;
import sistemaGab.model.dao.ProcessoDAO;
import sistemaGab.model.database.Database;
import sistemaGab.model.database.DatabaseFactory;
import sistemaGab.model.domain.Classes;
import sistemaGab.model.domain.Processos;

public class FXML_telaCadastroProcessosController implements Initializable
  {
    @FXML
    private Label labelRequerido;

    @FXML
    private JFXButton btnConfirmar;

    @FXML
    private Label labelObjeto;

    @FXML
    private Label labelNumero;

    @FXML
    private Label labelLocalizacao;

    @FXML
    private TextField txtRequerido;

    @FXML
    private Label labelDisciplinar;

    @FXML
    private TextField txtClasse;

    @FXML
    private Label labelClasse;

    @FXML
    private TextField txtNumero;

    @FXML
    private ComboBox<?> comboDisciplinar;
    
     @FXML
    private ComboBox comboBoxClasse;

    @FXML
    private HTMLEditor txtAndamentos;

    @FXML
    private Label labelRequerente;

    @FXML
    private Label labelProcessoDistribuicao;

    @FXML
    private DatePicker txtDataDistribuicao;

    @FXML
    private ComboBox <String> comboBoxLiminar;

    @FXML
    private TextField txtRequerente;

    @FXML
    private Label labelAndamentos;

    @FXML
    private Label labelPedidoLiminar;

    @FXML
    private JFXButton btnCancelar;

    @FXML
    private ComboBox<?> comboLocalizacao;

    @FXML
    private TextField txtObjeto;
    
    @FXML
    private List<Classes> listClasse;
    
    @FXML
    private ObservableList<Classes>observableListClasse;
    
    @FXML
    private ObservableList <String> observableListLiminar;
    
    private final Database database = DatabaseFactory.getDatabase("mysql");
    private final Connection connection = database.conectar();
    private final ClasseDAO classeDAO = new ClasseDAO();
    private final ProcessoDAO processoDAO = new ProcessoDAO();
    
    private Stage dialogStage;
    private boolean buttonConfirmarClicked = false;
    private Processos processo;
    private Classes classe;
    private ResultSet rs;
        
     /**
     * @return the dialogStage
     */
    public Stage getDialogStage()
      {
        return dialogStage;
      }

    /**
     * @param dialogStage the dialogStage to set
     */
    public void setDialogStage(Stage dialogStage)
      {
        this.dialogStage = dialogStage;
      }

    /**
     * @return the buttonConfimarClicked
     */
    public boolean isButtonConfirmarClicked()
      {
        return buttonConfirmarClicked;
      }

    /**
     * @param buttonConfirmarClicked the buttonConfimarClicked to set
     */
    public void setButtonConfirmarClicked(boolean buttonConfirmarClicked)
      {
        this.buttonConfirmarClicked = buttonConfirmarClicked;
      }

    /**
     * @return the processo
     */
    public Processos getProcesso()
      {
        return processo;
      }

    /**
     * @param processo the processo to set
     */
    public void setProcesso(Processos processo)
      {
        
        this.processo = processo;
        this.txtNumero.setText(processo.getNumero());
        this.txtRequerente.setText(processo.getRequerente());
        this.txtRequerido.setText(processo.getRequerido());
        this.comboBoxClasse.getSelectionModel().select(processo.getClasse());
        this.comboBoxLiminar.getSelectionModel().select(processo.getLiminar());
        this.txtDataDistribuicao.setValue(processo.getDataDistribuicao());
      
      }
    
       
    @FXML
    public void handleButtonConfirmar()
      {
        
            processo.setClasse((Classes) comboBoxClasse.getSelectionModel().getSelectedItem());
            processo.setNumero(txtNumero.getText());
            processo.setRequerente(txtRequerente.getText());
            processo.setRequerido(txtRequerido.getText());
            processo.setLiminar(comboBoxLiminar.getSelectionModel().getSelectedItem());
            processo.setDataDistribuicao(txtDataDistribuicao.getValue());

            buttonConfirmarClicked = true;
            dialogStage.close();
                
      }
    
    @FXML
    public void handleButtonCancelar()
      {
        dialogStage.close();
      }
    
    public void carregarComboBoxClasse() throws SQLException
      {
        listClasse = classeDAO.listar();
        observableListClasse = FXCollections.observableArrayList(listClasse);
        comboBoxClasse.setItems(observableListClasse); 
       
      }
    
    public void carregarComboBoxLiminar() 
      {
        observableListLiminar = FXCollections.observableArrayList("NÃO","SIM");
        comboBoxLiminar.setItems(observableListLiminar);
      }
    
       
    @Override
    public void initialize(URL url, ResourceBundle rb)
      {
        classeDAO.setConnection(connection);
         
        try
          {
            carregarComboBoxClasse();
            
          } catch (SQLException ex)
          {
            Logger.getLogger(FXML_telaCadastroProcessosController.class.getName()).log(Level.SEVERE, null, ex);
          }
        
        carregarComboBoxLiminar();
        
      }    
    
  }

O controller da tela que aparece a tabela com os dados e também chama o formulário de cadastro está assim:
package sistemaGab.controller;

import com.jfoenix.controls.JFXButton;
import java.io.IOException;
import java.net.URL;
import java.sql.Connection;
import java.sql.SQLException;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import sistemaGab.model.dao.ProcessoDAO;
import sistemaGab.model.database.Database;
import sistemaGab.model.database.DatabaseFactory;
import sistemaGab.model.domain.Processos;

public class FXML_telaProcessosGabineteController implements Initializable
  {

    @FXML
    private TableColumn<Processos, Integer> tableColumnProcessosId;

    @FXML
    private TableColumn<Processos, Processos> tableColumnProcessosRqte;

    @FXML
    private TableColumn<Processos, Processos> tableColumnProcessosRqdo;

    @FXML
    private JFXButton btnAlterar;

    @FXML
    private TableView<Processos> tableProcessos;

    @FXML
    private JFXButton btnInserir;

    @FXML
    private TableColumn<Processos, Processos> tableColumnProcessosNumero;

    @FXML
    private TableColumn<Processos, Processos> tableColumnProcessosClasse;

    @FXML
    private JFXButton btnRemover;
    
    @FXML
    private Label labelProcessoReqte;

    @FXML
    private Label labelProcessoNumero;

    @FXML
    private Label labelProcessoDistribuicao;

    @FXML
    private Label labelProcessoDisciplinar;

    @FXML
    private Label labelProcessoAndamento;

    @FXML
    private Label labelProcessoClasse;

    @FXML
    private Label labelProcessoLiminar;

    @FXML
    private Label labelProcessoReqdo;

    @FXML
    private Label labelProcessoObjeto;

    @FXML
    private Label labelProcessoId;
    
    @FXML
    private JFXButton fecharTela;
    
    @FXML
    private List<Processos> listProcessos;
    @FXML
    private ObservableList<Processos>observableListProcessos;
    
    private final Database database = DatabaseFactory.getDatabase("mysql");
    private final Connection connection = database.conectar();
    private final ProcessoDAO processoDAO = new ProcessoDAO();

    @Override
    public void initialize(URL url, ResourceBundle rb)
      {
        processoDAO.setConnection(connection);
        carregarTableViewProcesso();
        
        tableProcessos.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) ->
            selecionarItemTableProcessos(newValue));
   
        
      }
   
    public void carregarTableViewProcesso()
      {
        tableColumnProcessosId.setCellValueFactory(new PropertyValueFactory<>("id"));
        tableColumnProcessosNumero.setCellValueFactory(new PropertyValueFactory<>("numero"));
        tableColumnProcessosRqte.setCellValueFactory(new PropertyValueFactory<>("requerente"));
        tableColumnProcessosRqdo.setCellValueFactory(new PropertyValueFactory<>("requerido"));
        tableColumnProcessosClasse.setCellValueFactory(new PropertyValueFactory<>("classe"));
        
            
        listProcessos = processoDAO.listar();
        observableListProcessos = FXCollections.observableArrayList(listProcessos);
        tableProcessos.setItems(observableListProcessos);
              
      }
    
    public void selecionarItemTableProcessos(Processos processo)
      {
        if(processo != null)
          {
            labelProcessoId.setText(String.valueOf(processo.getId()));
            labelProcessoClasse.setText(processo.getClasse().toString());
            labelProcessoNumero.setText(processo.getNumero());
            labelProcessoReqte.setText(processo.getRequerente());
            labelProcessoReqdo.setText(processo.getRequerido());
            labelProcessoDistribuicao.setText(String.valueOf(processo.getDataDistribuicao().format(DateTimeFormatter.ofPattern("dd/MM/yyyy"))))

            ;
          }
        else
          {
           labelProcessoId.setText("");
           labelProcessoClasse.setText("");
           labelProcessoNumero.setText("");
           labelProcessoReqte.setText("");
           labelProcessoReqdo.setText("");
           labelProcessoLiminar.setText("");
           labelProcessoDistribuicao.setText("");
          }
      }
    
    @FXML
    public void handleButtonInserir() throws IOException
      {
        Processos processo = new Processos();
        
        boolean buttonConfirmarClicked = showFXML_telaCadastroProcessos(processo);
        
        if(buttonConfirmarClicked)
          {
            processoDAO.inserir(processo);
            carregarTableViewProcesso();
          }
      }
    
    @FXML
    public void handleButtonAlterar() throws IOException, SQLException
      {
       alterarTabela();
       carregarTableViewProcesso();
        }
     
    @FXML
    public void handleButtonRemover() throws IOException
      {
        Processos processo = tableProcessos.getSelectionModel().getSelectedItem();
        
        if(processo != null)
          {
            processoDAO.remover(processo);
            carregarTableViewProcesso();
          }
        else
          {
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setContentText("Selecione um processo!");
            alert.show();
          }
        
      }
    
    public boolean showFXML_telaCadastroProcessos(Processos processo) throws IOException
      {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(FXML_telaCadastroProcessosController.class.getResource("/sistemaGab/view/FXML_telaCadastroProcessos.fxml"));
        AnchorPane page = (AnchorPane) loader.load();
        
        Stage dialogStage = new Stage();
        dialogStage.setTitle("Cadastro de Processos");
        Scene scene = new Scene (page);
        dialogStage.setScene(scene);
        
        FXML_telaCadastroProcessosController controller = loader.getController();
        controller.setDialogStage (dialogStage);
        controller.setProcesso(processo);
        
        dialogStage.showAndWait();
     
        
        return controller.isButtonConfirmarClicked();
      }
    
    public void alterarTabela() throws IOException, SQLException
      {
        Processos processo = tableProcessos.getSelectionModel().getSelectedItem();
        
        if(processo != null)
        {
            boolean buttonConfirmarClicked = showFXML_telaCadastroProcessos(processo);
           
            if(buttonConfirmarClicked)
            {
             
                    processoDAO.setConnection(connection);
                    processoDAO.alterar(processo);
                   
                    carregarTableViewProcesso();
               
            }
            
        }
        else
            {
                Alert alert = new Alert(Alert.AlertType.ERROR);
                alert.setContentText("Selecione um processo!");
                alert.show();
            } 
      }
   }

Valew!

O problema provavelmente é que o mysql lhe retorna um sqlDate, e seu objeto foi criado com atributo do tipo javaDate.
Você vai precisar fazer a conversão do sqlDate para javaDate

java.sql.Date sqlDate = readDateFromDatabase(); 
java.util.Date utilDate = new java.util.Date(sqlDate.getTime()); 
System.out.println("sql date from database: " + sqlDate); 
System.out.println("util date in Java: " + utilDate);

Read more: https://javarevisited.blogspot.com/2016/06/how-to-convert-javasqldate-to-java-util-date-jdbc-example.html#ixzz5c6dAnCEF

SELECT * FROM processos WHERE data BETWEEN CAST('2000-01-12' AS DATE) AND CAST('2040-01-12' AS DATE)

Você tem algum registro na base com a data 0000-00-00, esta data é válida para o MySQL mas não é válida para o Java.

Configure a seguinte propriedade na sua conexão JDBC que daí as datas 0000-00-00 serão retornadas como null pelo Java:

zeroDateTimeBehavior=convertToNull

Outra coisa, como você está utilizando PreparedStatement, não utilize o método execute().
Utilize executeUpdate() para realizar seus INSERT, DELETE e UPDATE.
Utilize executeQuery() para realizar seus SELECT.

Você tem algum registro na base com a data 0000-00-00, esta data é válida para o MySQL mas não é válida para o Java.

Configure a seguinte propriedade na sua conexão JDBC que daí as datas 0000-00-00 serão retornadas como null pelo Java:

Cara, era só isso mesmo. Às vezes a gente fica pensando que a solução do problema é complicada e esquece de olhar o básico.
Agradeço a todos pela ajuda.
Moderador, pode marcar como resolvido.

2 curtidas