JBDC and MYSQL Null values inserting into table - mysql

Below is simple Login system. At the moment it will allow me to enter a blank username and password, into the table even though each index is specified as being NOT NULL? It wont allow me to enter duplicates which is what I wanted but how do I catch blank parameters from being entered? What am I missing?
Registration Servlet
....
LoginService loginService = new LoginService();
connection = loginService.getConnection(connection);
loginService.addNewUser(preparedStatement, connection, newUserId, newUserPassword, newUserFirstName, newUserLastName);
...
LoginService method addNewUser
public void addNewUser(PreparedStatement ps, Connection connection, String newUserId, String newUserPassword,String newUserFirstName,String newUserLastname) throws SQLException
{
ps = connection.prepareStatement("INSERT INTO users (userId ,password , userFirstName, userLastName)VALUES(?,?,?,?)");
ps.setString(1, newUserId);
ps.setString(2, newUserPassword);
ps.setString(3, newUserFirstName);
ps.setString(4, newUserLastname);
ps.executeUpdate();
}

To get around of your current issue, you can add this to the beginning of addNewUser method (before the line: ps = connection.prepareStatement("...");)
if (newUserId != null && "".equals(newUserId.trim()))
newUserId = null;
if (newUserPassword != null && "".equals(newUserPassword.trim()))
newUserPassword = null;
You should pass real NULL value in the JDBC parameters (empty strings are not good enough)

Related

executeUpdate in createQuery does not update my database

public void updateUserState(User user) {
Session sess=getSession();
sess.setFlushMode(FlushMode.MANUAL);
String queryStr = "update User usr set usr.logCount = :logCount , usr.isLocked = :isLocked , usr.lastLogin = :lastLogin where usr.userId=:userId";
Query query=null;
query = sess.createNativeQuery(queryStr);
query.setParameter("logCount", user.getLogCount());
query.setParameter("isLocked", user.getIsLocked());
query.setParameter("lastLogin", user.getLastLogin());
query.setParameter("userId", user.getUserId());
query.executeUpdate();
}
This is my code. This does not update mu user table in database , neither does this throw any error. It reflects the correct value till set parameter but after executeUpdate, I cannot see any update in my table. It would be really nice if anyone of you can tell me, where am I going wrong. Thanks in advance!
According to the hibernate documentation flush type MANUAL assume:
The Session flushing is delegated to the application, which must call Session.flush() explicitly in order to apply the persistence context changes.
So, you should explicitly call Session.flush() in the end of your method.
Also your updateUserState method should be ran inside a transaction:
Session sess = getSession();
sess.setFlushMode(FlushMode.MANUAL);
Transaction txn = sess.beginTransaction();
// ...
query.executeUpdate();
sess.flush();
txn.commit();
session.close();

How I can get the correct date of my Mysql query without the query itself subtracting one day to date

My problem is that in a table of my database with 7 columns, I have a column of date type, called "Fecnac". Through MYSQLworkbrench, I execute a simple query:
"SELECT * FROM tblAsegurados ORDER BY Name,Nss"
As a result of this query, the information of my columns or fields of the table is displayed, the table contains a column named "Fecnac" that shows the correct date, for example "2018-12-31".
MYSQLworkbrench Result image
However, I developed an application in intelliJ IDEA to execute the same query, and the query "by itself" returns the date with one day less, that is, it shows "2018-12-30". And so it does with all the dates found in the "Fecnac" column of the "tblAsegurados" table in my database.
public ArrayList<Asegurados> getAseguradosList(){
ArrayList<Asegurados> aseguradosList = new ArrayList<Asegurados>();
Connection connection = getConnection();
var query = "select * from tblAsegurados order by Nombre,Nss";
Statement st;
ResultSet rs;
try{
st = connection.createStatement();
rs = st.executeQuery(query);
Asegurados asegurado;
while(rs.next()){
asegurado = new Asegurados(
rs.getString("Nss"),
rs.getString("Nombre"),
rs.getString("Curp"),
rs.getBoolean("Esposa"),
rs.getInt("Semcot"),
rs.getInt("Hijos"),
rs.getDate("Fecnac"));
aseguradosList.add(asegurado);
System.out.println(asegurado.getFecnac());
System.out.println(rs.getDate("Fecnac"));
System.out.println(rs.getDate(7));
}
} catch (Exception e){
e.printStackTrace();
}
return aseguradosList;
}
The class "Asegurados" has an attribute of type "java.sql.date" defined, to receive "rs.getdate (Fecnac).
For i be sure of the values ​​returned by the query, in my code you can see that I made a "System.out.println" for each field date, and in all three I get the same value from the date with one day less.
Could someone help me know what happens?
Console debug IntelliJ Idea image
I already found the solution. In a part of my code, the parameter of the time zone had it defined as: serverTimezone = UTC
public static Connection getMySQLConnection() throws Exception {
String driver = "com.mysql.cj.jdbc.Driver";
String url = "jdbc:mysql://localhost/imss"+
"?useUnicode=true&useJDBCCompliantTimezoneShift=true"+
"&useLegacyDatetimeCode=false&serverTimezone=America/Mexico_City"+
"&verifyServerCertificate=false"+
"&useSSL=true"+
"&requireSSL=true";
String username = "root";
String password = "juan1980";
Class.forName(driver);
return DriverManager.getConnection(url, username, password);
}
I set it to: serverTimezone = america / Mexico_City, which is the zone that corresponds to me, and ready! the date is displayed correctly.

Checking database's username and data if they match the user info or not

I want to check that the username and data which is already in database is match with the user info or not. I have written some code but it doesn't select a row.
Here is my code:
public boolean iscorrect(String name , String pass){
boolean check=false;
openConnection();
Statement st =null;
ResultSet rs = null;
try{
st = conn.createStatement();
String q = "Select * from signup where email = '"+name+"'" ;
rs=st.executeQuery(q);
System.out.println(rs.getString(1)+" "+rs.getString(2));
if(rs.getString(1).equals(name) && rs.getString(2).equals(pass)){
check = true;
}
}catch(SQLException e){
e.printStackTrace();
}
return check;
}
You need to first call rs.next() to put the cursor at the first row of data. This will return false if there is no data.
In addition to that:
please use PreparedStatement and bind variables to avoid SQL injection
you could put the checks into the WHERE clause instead of loading the whole row
please don't store clear text passwords, use a cryptographic hash function

Obscure MySql Connector/J error message - java.sql.SQLException: boo {exclamation mark}

What the hey does this MySql error message mean?
java.sql.SQLException: boo!
springframework.dao.TransientDataAccessResourceException: CallableStatementCallback; SQL [{call sp_MyStoredProc(?, ?, ?)}]; boo!
It's not particularly meaningful that's for sure. Has anybody come across this and is able to translate to less lazy~developer~ish...?
I am accessing via org.springframework.jdbc.object.StoredProcedure
I am using org.springframework.jdbc-3.1.3
#Update
The offending lines are in CallableStatetement.java (2269-2271)
if (!found) {
throw SQLError.createSQLException("boo!", "S1000", this.connection.getExceptionInterceptor());`
}
Attching the sources for mysql-connector-java-5.1.18.jar and tracing though the code reveal that the correct message should be along the lines of 'mismatch between declared and actual parameters' or similar.
Indeed correctly declaring my output parameter
declareParameter(new SqlOutParameter("output", Types.INTEGER));
rather than
declareParameter(new SqlParameter("output", Types.INTEGER));
fixed my problem. But a more meaningful error message would have saved precious time. I shall make this suggestion to the MySql Connector/J Development team.
As stated in the update to the question this is commonly caused by incorrectly using a CallableStatement. For example:
Stored Procedure uses 2 parameters, one in and one out:
CREATE DEFINER=`example`#`localhost` PROCEDURE `sp_getSensorLocation`(IN in_id VARCHAR(128), OUT loc VARCHAR(128))
BEGIN
SELECT LOCATION INTO loc FROM table.SENSORS
WHERE ID = in_id;
END
but the call to it only uses 1:
private String getSensorLocation(String sensorID) {
String location = "";
Connection c = dbr.getConnection();
String prepStatement = "{ call sp_getSensorLocation(?) } ";
try {
callableStatement cs = c.prepareCall(prepStatement);
cs.setString(1, sensorID);
ResultSet rs = cs.executeQuery();
if (rs.next()) {
location = rs.getString(1);
}
} catch (SQLException ex) {
LOG.error("Error:", ex);
}
dbr.closeConnection(c, rs, cs);
return location;
}
When the correct code is really:
private String getSensorLocation(String sensorID) {
String location = "";
Connection c = dbr.getConnection();
String prepStatement = "{ call sp_getSensorLocation(?, ?) } ";
try {
CallableStatement cs = c.prepareCall(prepStatement);
cs.setString(1, sensorID);
cs.execute();
location = cs.getString(2);
} catch (SQLException ex) {
LOG.error("Error:", ex);
}
dbr.closeConnection(c, rs, cs);
return location;
}
Notice I also changed to cs.execute as I don't expect a result set and would have issues with this as well (the example is taken from someone else's code I'm fixing, the joys -_-)

How to validate username from MySql with JSP

hello guys i am try to validate username from the database with the username that the user entered in the html from, assume
un//be the variable where username entered now from html form is stored
now how to retrieve all the columns of the uname from user table
uname //column name in mysql for usernames
user //table name in mysql
and check weather the username i.e,un entered now is present or not in the database
i am using
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/mebps","root","admin");
Statement stmt = (Statement) con.createStatement();
ResultSet rs = stmt.executeQuery("select un from userinfo");
while(rs.next())
{
if(rs.getString("uname") == un)
{
out.println("user is present");
}
}
There are at least two major mistakes:
You're comparing string instances by == instead of comparing their values by equals() method. The proper line would be if (rs.getString("uname").equals(un)).
You're not letting the DB do the job of returning the right row, instead you're copying the entire DB table into Java's memory and doing the comparison in Java. This is very inefficient. Make use of SQL powers the smart way so that it always returns exactly the information you need. There's for example a WHERE clause.
On an unrelated note, you seem not to be closing DB resources properly after use. This will result in resource leaking which is also a bad idea as it may cause your application to crash on long term. Further, the column name uname and un are not the same. But I'll assume it to be careless oversimplifying of the example.
Here's a minor rewrite:
public boolean exist(String username) throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
boolean exist = false;
try {
connection = database.getConnection();
statement = connection.prepareStatement("SELECT uname FROM userinfo WHERE uname=?");
statement.setString(1, username);
resultSet = statement.executeQuery();
exist = resultSet.next();
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException ignore) {}
if (statement != null) try { statement.close(); } catch (SQLException ignore) {}
if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}
return exist;
}
You see, if there's a match, then it returns true (at least one record), otherwise false (no one record). No need to copy the entire table into Java's memory and crawl through it in Java.
Last but not least, this code doesn't belong in a JSP file, but in a normal Java class, starting with a servlet. See also our servlets wiki page to learn more about it.