I have this code
public PreparedStatement InsertDepartmentQuery() {
try {
ps = conn.prepareStatement("INSERT INTO department (DepartmentNo,DepartmentName,DepartmentLocation) VALUES (?,?,?)");
}
catch(SQLException e) {
e.printStackTrace();
}
return ps;
}
and
public void InsertyTuple() {
int a = -1;
ps = InsertDepartmentQuery();
try {
ps.setInt(1, DeptNo);
ps.setString(2, DeptName);
ps.setString(3, DeptLocation);
a = ps.executeUpdate();
}
catch(SQLException e) {
e.printStackTrace();
}
System.out.println(a);
}
and
Department test = new Department(106, "TB_1", "Tabuk");
test.InsertyTuple();
It executes fine in Eclipse, even a select query in there returns the expected results. But none of the inserts are showing up in MySQL Workbench. I tried restarting the connection and it didn't work. Autocommits are on as when I tried to do a manual commit it told me so.
Wrong schema name
Well I found the problem so I'll just leave the answer and feel stupid later.
I had the connection started as
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql?zeroDateTimeBehavior=CONVERT_TO_NULL", username, password);
when it should've been
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/project?zeroDateTimeBehavior=CONVERT_TO_NULL", username, password);
the "project" replacing "mysql" is the name of my schema in MySQL.
Related
I've encountered an some inconsistencies regarding the results from an SQL query.
Here is the query which I'm using as a prepared statement.
delete ROLE_USER_MAP
from ROLE_USER_MAP inner join ROLE_MANAGER on ROLE_USER_MAP.R_ID=ROLE_MANAGER.R_ID
where ROLE_USER_MAP.U_ID= ? and ROLE_MANAGER.M_ID= ?
Here is how I calling the prepared statement in my Java application.
public void deleteRoles(String mID, String uID) throws OperationFailedException
{
Connection conn = null;
try
{
conn = this.getConnection();
this.deleteRoles(mID, uID, conn);
}
catch (Exception e)
{
AdminLogger.error(this.getClass(), e);
throw new OperationFailedException("Failed to remove roles for user.");
}
finally
{
try
{
conn.close();
}
catch (Exception e)
{
}
}
}
private void deleteRoles(String mID, String uID, Connection conn) throws SQLException
{
PreparedStatement stmt = null;
try
{
stmt = *retrieving ps*
stmt.setString(1, uID);
stmt.setString(2, mID);
int i = stmt.executeUpdate(); // returns 1 here
if (i < 1)
{
throw new SQLException("Failed to remove roles for user.");
}
} finally
{
stmt.close();
}
}
It runs fine locally and in SSMS with all rows fitting the where clause being deleted but when I try to deploy it to my hosted server, only the first row in the table is being deleted.
Can anyone help me with this?
Thanks in advance.
I'm trying to display a list of the names of people in the database from the terminal, but not sure about how I would go about this. Right now I'm using a prepared statement
public static void showNames() throws SQLException {
Statement stmt=null;
Connection conn=null;
try {
conn = DriverManager.getConnection(DB_URL, USER, PASS);
stmt = conn.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
String selectTable="SELECT * FROM userInfo;";
stmt.execute(selectTable);
}
You're close.
Below code is not a complete answer, but hopefully enough to get you moving in the direction of obtaining a complete answer. The below code is basically the code you posted with some modifications.
public static void showNames() throws SQLException {
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;
String selectTable="SELECT * FROM userInfo;";
try {
conn = DriverManager.getConnection(DB_URL, USER, PASS);
stmt = conn.createStatement();
rs = stmt.executeQuery(selectTable);
while (rs.next()) {
Object obj = rs.getObject("name of column in database table USERINFO");
System.out.println(obj);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.close();
}
}
}
You didn't post the structure of database table USERINFO, so replace name of column in database table with the actual column name.
By the way, there are many examples of how to do this on the Internet, for example Processing SQL Statements with JDBC.
This is my code at the moment. I have or had several problems:
Database is busy - error
SQL error or missing database
Resultset closed
Which code structure should I use if I want to prevent both of these errors?
Do I need to connect in the try block? Where do I need to close the connection? Where do I need to close the preparedStatement?
I was not able to find a solution by connecting the information of different pages by myself until now.
public boolean checkForUser(String username){
try(Connection con = this.connect();
PreparedStatement pstmt = createPreparedStatementRegistrate(conn, username);
ResultSet rs= pstmt.executeQuery();)
{
if (rueck.next()){
pstmt.close();
rs.close();
con.close();
//do some stuff
}
}catch(SQLException e){
e.printStackTrace();
}
return null;
}
private PreparedStatement createPreparedStatementRegistrate(Connection conn, String username) throws SQLException {
String sql = "SELECT * FROM users WHERE username = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username);
return pstmt;
}
private Connection connect() {
String url = "jdbc:sqlite:user.db";
Connection con = null;
try {
con = DriverManager.getConnection(url);
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
java.sql.SQLException: ResultSet closed
at org.sqlite.core.CoreResultSet.checkOpen(CoreResultSet.java:69)
at org.sqlite.jdbc3.JDBC3ResultSet.findColumn(JDBC3ResultSet.java:38)
at org.sqlite.jdbc3.JDBC3ResultSet.getString(JDBC3ResultSet.java:443)
at zugriffsverwaltung.Zugriffsverwaltung.loeschen(Zugriffsverwaltung.java:215)
at zugriffsverwaltung.Zugriffsverwaltung.<init>(Zugriffsverwaltung.java:37)
at main.Server.<init>(Server.java:29)
at main.Server.main(Server.java:46)
org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (Connection is closed)
at org.sqlite.core.DB.newSQLException(DB.java:909)
at org.sqlite.core.CoreStatement.internalClose(CoreStatement.java:115)
at org.sqlite.jdbc3.JDBC3Statement.close(JDBC3Statement.java:35)
at org.sqlite.jdbc4.JDBC4Statement.close(JDBC4Statement.java:27)
at zugriffsverwaltung.Zugriffsverwaltung.loeschen(Zugriffsverwaltung.java:238)
at zugriffsverwaltung.Zugriffsverwaltung.<init>(Zugriffsverwaltung.java:37)
at main.Server.<init>(Server.java:29)
at main.Server.main(Server.java:46)
The problem is that you are closing the result set, statement and connection before you do things with the result set. This is not allowed: a result set needs to be open when you retrieve values using getString (not shown in your code, but present in your stack trace).
As you are using try-with-resource which will close the resource on exit, it is even unnecessary to explicitly close. It also looks like the SQLite driver does not meet the JDBC requirements that closing an already closed resource should be a no-op, as it is throwing an exception that the connection is closed when closing the statement (likely by the try-with-resources).
You need to change your code to
public boolean checkForUser(String username){
try(Connection con = this.connect();
PreparedStatement pstmt = createPreparedStatementRegistrate(conn, username);
ResultSet rs= pstmt.executeQuery();)
{
if (rueck.next()){
//do some stuff
}
}catch(SQLException e){
e.printStackTrace();
}
return null;
}
That is, remove the lines
pstmt.close();
rs.close();
con.close();
Please explain how I can test CRUD operations in java like these:
public void insert(User user) {
Connection con = null;
PreparedStatement ps;
try {
con = DatabaseConnection.dbCon();
ps = con.prepareStatement("insert into usert (name,surname,role_id,login,password) values(?,?,?,?,?)");
ps.setString(1, user.getName());
ps.setString(2, user.getSurname());
ps.setInt(3, user.getRole().getId());
ps.setString(4, user.getLogin());
ps.setString(5, user.getPassword());
ps.execute();
if (con != null) {
con.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* deletes user
* #param user
*/
public void delete(User user) {
Connection con = null;
PreparedStatement ps;
try {
con = DatabaseConnection.dbCon();
ps = con.prepareStatement("delete from usert where id = ?");
ps.setInt(1, user.getId());
ps.execute();
if (con != null) {
con.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
Now, I wrote unit tests for models like User and etc. I don't understand how to test buttons and another operations like above.
Actually there are many drawbacks about your code. For example, you are trying to close a connection in 'try' block, instead of finally.
Anyway, up to your question.
Note that my advice will make sence only if you are not using standard sql-syntaxis, common for all databases (it's ok for learning, but a rare situation in real-life). And unless you are learnin JDBC, I would also recomend you to take a look an ORM's like Hibernate.
For testing database-operations, you can do this:
Create a non- static getConnection method, that triggers your DatabaseConnection.dbConn().
Mock it using mockito library, providing some lightweight database like hsql.
Do your tests
So, the logic of interracting with database will remain the same, the only thing that will cange is the storage.
BTW, there is no need to extract DatabaseConnection.dbConn() in a seperate method. You can use power-mock and it would work fine. But I recomend you to learn mockito first.
I have a mysql database on my ubuntu server. When i delete rows with MYSQL workbench on this database and than try to select these rows with my Java program, i still get the deleted rows. (I have committed the command with MYSQL workbench)
In my java program I access the database over a Java Restful webservice which also runs on my server.
my webservice looks like:
#Path("/getAll")
#GET
#Produces({MediaType.APPLICATION_XML})
public List<PV> getAllPV() {
List<PV> ret =null;
try {
ret=Database.getInstance().getAllPV();
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
My Database:
public List<PV> getAllPV() throws Exception{
Connection conn = null;
PreparedStatement ps=null;
Statement s = null;
conn = getDBConnection();
conn.setAutoCommit(false);
List<PV> ret = new ArrayList<PV>();
s = conn.createStatement();
ResultSet rs = s.executeQuery("select * from PV");
...
conn.close();
}
Has anyone an idea ?