how to solve this problem and what is wrong in this code?
i know that the question has been asked before but i cant solve the problem
private void cb_categoriesPopupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
cb_categories.removeAllItems();
try {
String sql_c = "SELECT * FROM inventory.categories";
cc.pst = cc.c.prepareStatement(sql_c);
cc.rs = cc.pst.executeQuery();
while (cc.rs.next()) {
String c_name = cc.rs.getString("CategoryName");
cb_categories.addItem(c_name);
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
} finally {
try {
cc.rs.close();
cc.pst.close();
} catch (Exception e) {
}
}
}
Your ResultSet and PreparedStatement are not declared in method scope, so I have to assume that you've declared them elsewhere.
That's a big mistake.
You should declare the Statement and ResultSet in method scope.
You make an attempt to close your resources, but you should wrap them in individual try/catch blocks. You cannot risk one being closed and not the other.
There are other things I'd criticize about your code (e.g. SELECT *, mingling UI and database code together in a single class), but that's enough to start.
Start with an interface:
package persistence;
import java.util.List;
/**
* Created by Michael
* Creation date 8/20/2017.
* #link https://stackoverflow.com/questions/45787151/com-mysql-jdbc-exception-jdbc4-mysqlnontransientconnectionexception-no-operatio/45787321?noredirect=1#comment78532554_45787321
*/
public interface CategoryDao {
List<String> findAllCategories();
}
Then write a concrete implementation:
package database;
import database.util.DatabaseUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.sql.DataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Michael
* Creation date 8/20/2017.
* #link https://stackoverflow.com/questions/45787151/com-mysql-jdbc-exception-jdbc4-mysqlnontransientconnectionexception-no-operatio/45787321?noredirect=1#comment78532554_45787321
*/
public class CategoryDaoImpl implements CategoryDao {
private static final Log LOGGER = LogFactory.getLog(CategoryDaoImpl.class);
private static String SELECT_CATEGORIES = "SELECT CategoryName from inventory.Categories ";
private DataSource dataSource;
public CategoryDaoImpl(DataSource dataSource) {
this.dataSource = dataSource;
}
#Override
public List<String> findAllCategories() {
List<String> categories = new ArrayList<>();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = this.dataSource.getConnection().prepareStatement(SELECT_CATEGORIES);
rs = ps.executeQuery();
while (rs.next()) {
categories.add(rs.getString("CategoryName"));
}
} catch (SQLException e) {
LOGGER.error(String.format("Exception caught while selecting all category names"), e);
} finally {
DatabaseUtils.close(rs);
DatabaseUtils.close(ps);
}
return categories;
}
}
This is something that you can test with JUnit off to the side. Get it running perfectly, then give a reference to your UI code. It'll keep the UI and database code separate. You can use this DAO in any application without worrying about Swing or web UI.
Related
This question already has answers here:
ResultSet exception - before start of result set
(6 answers)
Closed 5 years ago.
I'm thinking about the MVC application and for that and in the loading method of the lists that can be deleted with elements that are going to be chosen to make the query.
The classes associated with this are:
package modelo;
import java.sql.*;
import controlador.*;
public class CargaMenus {
public CargaMenus() {
miconexion = new Conexion();
}
public String ejecutaConsultas() { //Va a devolver el nombre de las tareas en el conbobox
Tareas miTarea = null;
Connection accesoBBDD = miconexion.dameConexion();
try {
Statement secciones = accesoBBDD.createStatement();
Statement descripciones = accesoBBDD.createStatement();
rs = secciones.executeQuery("SELECT DISTINCTROW NOMTAREA FROM TAREAS");
rs2 = descripciones.executeQuery("SELECT DISTINCTROW DESCTAREA FROM TAREAS");
miTarea = new Tareas();
miTarea.setNomtarea(rs.getString(1));
miTarea.setDesctarea(rs2.getString(1));
rs.close();
rs2.close();
} catch (SQLException e) {
System.out.println("Error en la conexión CARGAMENUS");
e.printStackTrace();
}
return miTarea.getNomtarea();
}
public Conexion miconexion;
public ResultSet rs;
public ResultSet rs2;
private String consulta = "SELECT DISTINCTROW NOMTAREA FROM TAREAS";
private String consulta2 = "SELECT DISTINCTROW DESCTAREA FROM TAREAS";
}
and the class that executes the method and travel what is returned by the database is:
package controlador;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.sql.ResultSet;
import modelo.CargaMenus;
import vista.Marco_Aplicacion2;
public class ControladorCargaMenus extends WindowAdapter {
public ControladorCargaMenus(Marco_Aplicacion2 elmarco) {
this.elmarco = elmarco;
}
public void windowOpened(WindowEvent e) {
obj.ejecutaConsultas();
try {
while(obj.rs.next()) {
elmarco.secciones.addItem(obj.rs.getString(1));
}
while(obj.rs2.next()) {
elmarco.paises.addItem(obj.rs2.getString(1));
}
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
CargaMenus obj = new CargaMenus();
private Marco_Aplicacion2 elmarco;
}
When I run the program, I only see a combobox of the 2 that I designed.
and the following error
I thought the problem would be my sql queries but I validated them and there is no problem when I run them in my mysql.
and when I only load one of the lists (the first one) commenting the lines associated with the second list, the application loads me even if it throws errors in the console
The link I'm learning about is link of tutorial
How could I do to load the lists?
You should call rs.next before getting result.
if (rs.next()) {
miTarea.setNomtarea(rs.getString(1));
miTarea.setDesctarea(rs2.getString(1));
}
The root cause is that you are not calling rs.next() before rs.getString, it is only called after the ejecutaConsultas method is run. Same applies to rs2 usage.
Also you need to follow some best practices in your code such not exposing ResultSet to outside of your class and doing proper JDBC exception handling and closing of ResultSets andConnections.
I have linked up a database to my Java application using the JDBC in Netbeans.
But whenever I try to write something from a TextField to a MySQL table, it doesn't work.
I have a pre-made class to make the database connection.
Here is my database class:
package testswitch;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author Maarten
*/
public class Database {
public final static String DB_DRIVER_URL = "com.mysql.jdbc.Driver";
public final static String DB_DRIVER_PREFIX = "jdbc:mysql://";
private Connection connection = null;
public Database(String dataBaseName, String serverURL, String userName, String passWord) {
try {
// verify that a proper JDBC driver has been installed and linked
if (!selectDriver(DB_DRIVER_URL)) {
return;
}
if (serverURL == null || serverURL.isEmpty()) {
serverURL = "localhost:3306";
}
// establish a connection to a named Database on a specified server
connection = DriverManager.getConnection(DB_DRIVER_PREFIX + serverURL + "/" + dataBaseName, userName, passWord);
} catch (SQLException eSQL) {
logException(eSQL);
}
}
private static boolean selectDriver(String driverName) {
// Selects proper loading of the named driver for Database connections.
// This is relevant if there are multiple drivers installed that match the JDBC type.
try {
Class.forName(driverName);
// Put all non-prefered drivers to the end, such that driver selection hits the first
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver d = drivers.nextElement();
if (!d.getClass().getName().equals(driverName)) {
// move the driver to the end of the list
DriverManager.deregisterDriver(d);
DriverManager.registerDriver(d);
}
}
} catch (ClassNotFoundException | SQLException ex) {
logException(ex);
return false;
}
return true;
}
public void executeNonQuery(String query) {
try (Statement statement = connection.createStatement()) {
statement.executeUpdate(query);
} catch (SQLException eSQL) {
logException(eSQL);
}
}
public ResultSet executeQuery(String query) {
Statement statement;
try {
statement = connection.createStatement();
ResultSet result = statement.executeQuery(query);
return result;
} catch (SQLException eSQL) {
logException(eSQL);
}
return null;
}
private static void logException(Exception e) {
System.out.println(e.getClass().getName() + ": " + e.getMessage());
e.printStackTrace();
}
}
And here's my JavaFX controller.
What I want is that when the "handle" button is pressed, that the data filled in the TextField gets inserted into the database.
package testswitch;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import testswitch.Database;
/**
*
* #author Maarten
*/
public class gebruikerToevoegenController {
//TextFields
#FXML
private TextField FXVoornaam, FXTussenvoegsel, FXAchternaam, FXGebruikersnaam;
#FXML
private TextField FXWachtwoord, FXEmail, FXTelefoonnummer;
//Boolean checkbox positie
#FXML
private CheckBox ManagerPosition;
#FXML
private Button gebruikerButton;
public final String DB_NAME = "testDatabase";
public final String DB_SERVER = "localhost:3306";
public final String DB_ACCOUNT = "root";
public final String DB_PASSWORD = "root";
Database database = new Database(DB_NAME, DB_SERVER, DB_ACCOUNT, DB_PASSWORD);
public void handle(ActionEvent event) throws SQLException {
String query = "INSERT INTO testDatabase.Gebruikers (Voornaam) VALUES " + FXVoornaam.getText();
try {
database.executeQuery(query);
} catch (Exception e) {
}
}
}
Thanks in advance
The string in your SQL query doesn't seem to be properly quoted. It's best to use PreparedStatement for this scenario:
public class Database {
public PreparedStatement prepareStatement(String query) throws SQLException {
return connection.prepareStatement(query);
}
...
public void handle(ActionEvent event) throws SQLException {
String query = "INSERT INTO testDatabase.Gebruikers (Voornaam) VALUES (?);";
PreparedStatement statement = database.prepareStatement(query);
try {
statement.setString(1, FXVoornaam.getText());
statement.executeUpdate();
} catch (Exception e) {
// log info somewhere at least until it's properly tested/
// you implement a better way of handling the error
e.printStackTrace(System.err);
}
}
You have to add like this in JavaFx :
String query = "INSERT INTO testDatabase.Gebruikers (Voornaam) VALUES ('{FXVoornaam.getText()}') ";
String query = "INSERT INTO testDatabase.Gebruikers(Voornaam)
VALUES('" + FXVoornaam.getText() + "')";
I am using neo4-jdbc with pool lib BasicDataSource.
I had huge latency problems so we profiled the app and we found out that opening connection is the cause. I didnt understand why open-connection takes so long we using pool. this is screenshot from our profiles:
This is how the Neo4jDatasourceRemote looks like:
package com.comp.wm.common.repo;
import com.comp.wm.common.utils.Constants;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import javax.annotation.PostConstruct;
import java.sql.Connection;
import java.sql.SQLException;
private final Logger logger = Logger.getLogger(Neo4jDataSourceRemote.class);
private BasicDataSource ds;
#Value("${neo4j.host:localhost}")
private String NEO4J_HOST;
#Value("${neo4j.port:7474}")
private String NEO4J_PORT;
#Value("${neo4j.username:nouser}")
private String NEO4J_USERNAME;
#Value("${neo4j.password:nopass}")
private String NEO4J_PASSWORD;
#Value("${neo4j.pool.size:200}")
private int NEO4J_POOL_SIZE;
private String GetUrl() {
return String.format(Constants.NEO4J_JDBC_CONNECTIVITY_STRING, NEO4J_HOST, NEO4J_PORT);
}
#PostConstruct
public void init(){
ds = new BasicDataSource();
ds.setInitialSize(300);
ds.setDriverClassName("org.neo4j.jdbc.Driver");
ds.setUrl(GetUrl());
ds.setUsername(NEO4J_USERNAME);
ds.setPassword(NEO4J_PASSWORD);
}
#Override
public Connection openConnection() throws SQLException {
return this.ds.getConnection();
}
#Override
public void closeConnection(Connection conn) {
try {
if (conn != null)
conn.close();
} catch (SQLException ex) {
logger.info("error closing connection", ex);
}
}
}
and this is a sample of how I execute query against the graph:
public List<NearbyItem> executeQuery(..) {
conn = neo4jDataSource.openConnection();
String getUsersStatement = "some query..";
try (PreparedStatement ps = conn.prepareStatement(getUsersStatement)) {
..
ResultSet rs = ps.executeQuery();
while (rs.next()) {
...
}
} catch (Exception e) {
throw new RuntimeException("Error returning userId=" + userIdInput, e);
} finally {
neo4jDataSource.closeConnection(conn);
}
return distItemDatas;
}
any ideas?
Based on comments above, I'll add this as a reply.
By default Neo4j runs in the http interface 10 threads for core. You can tweak the total number of threads in neo4j-server.properties
org.neo4j.server.webserver.maxthreads=200
However the more threads you have the more you're suffering from context switches and lock contention. If you increase the number of threads I won't expect a large increase of throughput, you just shift the point where you have to wait. From initialization (openCOnnection) to processing the query.
I am working on a dictionary project in Java on Netbeans. I have two classes here:
"dictionary.java" where the main method is
"DictionaryGuiController.java" where GUI code is constructed with javafx platform
I connected the database and project with JDBC driver and using these codes in main method:
Connection conn = null;
Statement statement = null;
ResultSet rs = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost/world", "root", "root");
statement = conn.createStatement();
rs = statement.executeQuery("SELECT * FROM country");
while (rs.next()) {
System.out.println(rs.getString("code") + ":" + rs.getString("name"));
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
}
Here I created a connection object as conn to create statements and executing the SQL query.
I want to retrieve data from a sample database in Mysql called "world". With this code I am able to retrieve data in a small project that has only one class and main method. But in this project when I run the program I see the GUI interface but I can not see any results in the console, it keeps saying:
Executing C:\Users\Bar\Documents\NetBeansProjects\Dictionary\dist\run414351490\Dictionary.jar using platform C:\Program Files\Java\jdk1.7.0_45\jre/bin/java
and program never stops until program exits.
Here is the complete code of the classes:
Dictionary.java:
package dictionary;
import java.io.IOException;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import java.sql.*;
public class Dictionary extends Application {
#Override
public void start(Stage stage) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("DictionaryGui.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* The main() method is ignored in correctly deployed JavaFX application.
* main() serves only as fallback in case the application can not be
* launched through deployment artifacts, e.g., in IDEs with limited FX
* support. NetBeans ignores main().
*
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
Connection conn = null;
Statement statement = null;
ResultSet rs = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost/world", "root", "root");
statement = conn.createStatement();
rs = statement.executeQuery("SELECT * FROM country");
while (rs.next()) {
System.out.println(rs.getString("code") + ":" + rs.getString("name"));
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
}
}
}
DictionaryGuiController.java:
package dictionary;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
public class DictionaryGuiController implements Initializable {
#FXML
private TextField searchfield;
#FXML
private Button buttonsearch;
#FXML
private TextArea listview;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
#FXML
private void handleButtonAction(ActionEvent event) {
listview.setText(searchfield.getText());
}
}
What could be the problem? Any help would be appreciated.
Two quick things that it could be. First, is your instance of MySQL already running? Secondly, I tend to do all my database connection stuff outside the main method. So I will have a method in the controller class called initDB() or connectToDB() and I put the code in there.
The convention I've seen for the main() method in JavaFX programs is that launch() is the only method called. I could be wrong, but check those two things and see if you have any luck.
I've read about inheritance or using the import. I just simply am unable to get the right answer. Firstly my code is of the following form:
class queries{
String query1="Select * from "+tableName+";
String query2="Select "+columnName+" from "+tableName+";
}
Now, I have another class where I wish to make make SQL queries using the queries mentioned in the queries class:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
class test{
public static void main(String args[])throws SQLException
{
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("This is Wrong");
// TODO Auto-generated catch block
e.printStackTrace();
}
Connection connect = DriverManager
.getConnection("SQLCONNECTION");
PreparedStatement preparedStatement = connect
.prepareStatement(THIS SHOULD CALL query1 or query2);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.println("THIS RUNS");
//display text
}
preparedStatement.close();
connect.close();
}
}
So well, I need to figure out how to call query1 or query2 from the queries class in test. Sorry, but I hope someone can help me how to do this in a clean way. I can also create a Hashtable in queries where I call the respective query based on its name.
Thanks a lot.
class queries
{
public static String getQuery1(String tableName)
{
return "Select * from "+tableName;
}
public static String getQuery2(String tableName, String columnName)
{
return "Select "+columnName+" from "+tableName;
}
}
Then do this:
PreparedStatement preparedStatement =
connect.prepareStatement(queries.getQuery1("INSERT TABLE NAME HERE"));