Hibernate's SQLQuery executeUpdate function starts, but does not fully execute - java

Working on a Spring application that uses Hibernate, and in my DAO layer we are running an UPDATE statement to update some values in an Oracle database.
To make sure I'm not crazy, I ran the statement in SQL Developer to make sure it works properly. Here is part of my DAO code:
public void updateObjectInMyTable(SomeClassA objectOfSomeClassA) {
Session session = getCurrentSession();
String sql = "UPDATE SCHEMA_NAME.TABLE_XYZ SET FIRST_NAME=:firstName, LAST_NAME=:lastName, ADDRESS=:address, CITY=:city, ZIPCODE=:zipcode WHERE ID_NUMBER = :idNumber";
SQLQuery query = session.createSQLQuery(sql);
query.setParameter("firstName", objectOfSomeClassA.getFirstName());
query.setParameter("lastName", objectOfSomeClassA.getLastName());
query.setParameter("address", objectOfSomeClassA.getAddress());
query.setParameter("city", objectOfSomeClassA.getCity());
query.setParameter("zipcode", objectOfSomeClassA.getZipcode());
query.setParameter("idNumber", objectOfSomeClassA.getIdNumber());
query.executeUpdate();
}
(Excuse the poor variables names used for substitutions of the real ones.) I did debug on the server and I do not see any errors with query.executeUpdate() It gets to that line, and doesn't pass on to the next statement I have in my service layer.
Anything I'm doing wrong?

Where's your transaction ?!
Use :
session.beginTransaction().commit();
add this in the end line of your code.
I hope this helps you.

Related

How to batch execute SQL query using Hibernate session

I am using the below set of code for an update:
private void updateAvatarPath(Integer param1, String param2, String param3, boolean param4){
Transaction avatarUpdatePathTransaction = session.beginTransaction();
String updateQuery = "query goes here with param";
Query query = session.createSQLQuery(updateQuery);
query.executeUpdate();
avatarUpdatePathTransaction.commit();
session.flush();
}
This function is being called from a loop. So this takes time to update since for each loop it's hitting the DB. Instead of hitting DB every time, to increase the performance I am planning to execute it as batches. But have no idea how to do it.
session.doWork() is one of the solutions which I got. I want to know any other option available to do it.
You should move Transaction avatarUpdatePathTransaction = session.beginTransaction(); before the start of your loop and avatarUpdatePathTransaction.commit(); after the end of your loop.
The recommended pattern is to have one session per "unit of work", in your case this seems to be modifying multiple entities in a single session/transaction.
The session.flush(); is not necessary I think, committing the transaction should flush the session

Java Statement.executeUpdate(sql) not working when executeQuery(sql) works

I have a wierd behavior in a Java application.
It issues simple queries and modifications to a remote MySQL database. I found that queries, run by executeQuery() work just fine, but inserts or delete to the database run through executeUpdate() will fail.
Ruling out the first thing that comes to mind: the user the app connects with has correct privilledges set up, as the same INSERT run from the same machine, but in DBeaver, will produce the desired modification.
Some code:
Connection creation
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(url, user, pass);
Problematic part:
Statement parentIdStatement = connection.createStatement();
String parentQuery = String.format(ProcessDAO.GET_PARENT_ID, parentName);
if (DEBUG_SQL) {
plugin.getLogger().log(Level.INFO, parentQuery);
}
ResultSet result = parentIdStatement.executeQuery(parentQuery);
result.first();
parentId = result.getInt(1);
if (DEBUG_SQL) {
plugin.getLogger().log(Level.INFO, parentId.toString()); // works, expected value
}
Statement createContainerStatement = connection.createStatement();
String containerQuery = String.format(ContainerDAO.CREATE_CONTAINER, parentId, myName);
if (DEBUG_SQL) {
plugin.getLogger().log(Level.INFO, containerQuery); // works when issued through DBeaver
}
createContainerStatement.executeUpdate(containerQuery); // does nothing
"DAOs":
ProcessDAO.GET_PARENT_ID = "SELECT id FROM mon_process WHERE proc_name = '%1$s'";
ContainerDAO.CREATE_CONTAINER = "INSERT INTO mon_container (cont_name, proc_id, cont_expiry, cont_size) VALUES ('%2$s', %1$d, CURRENT_TIMESTAMP(), NULL)";
I suspect this might have to do with my usage of Statement and Connection.
This being a lightweight lightly-used app, I went to simplicity, so no framework, and no specific isntructions regarding transactions or commits.
So, in the end, this code was just fine. It worked today.
To answer the question: where to look first in a similar case (SELECT works but UPDATE / INSERT / DELETE does not)
If rights are not the problem, then there is probably a lock on the table you try to modify. In my case, someone left with an uncommited transaction open.
Proper SQL exceptions logging (which was suboptimal in my case) will help you figure it out.

Insert Sql query not working with HQL

I am trying to make a simple insert into a DB with HQlL by using native SQL code.
It doesn't give any error, it just doesn't work. Any help is appreciated.
Thanks.
public void AddMedicament(Medicament medicament) {
System.out.println(medicament.getName());
// open a database connection
Session session = FarmacieHibernateUtil.getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();
// prepare SQL insert command
session.createSQLQuery("insert into Medicament(name) values('test')");
// close the database connection
session.close();
}
You need to call
session.executeUpdate()
transaction.commit();
before closing session.
I am not familar with Hibernate, but i dont see you sre running your command. You just create query and close session
I think you need some statement to execute it.
If you use createSQLQuery this throw a native sql instruction
Your object table name is Medicament too?
session.saveOrUpdate(medicament);
tx.commit();
then it will insert if u r not setting the Primarykey, if u r setting the PK in the domain object then it will be updated.
no need to executeQuery in hibernate if you are using the Spring ORM.

Hibernate multiple native SQL statements

I want to run a native SQL from a file using Hibernate. The SQL can contain several statements creating the database structure (i.e. tables, constraints but no insert/update/delete statements).
Example, very simple query is below (which contains the following two SQL statements)
CREATE DATABASE test;
CREATE TABLE test.testtbl( id int(5));
I am using MySQL db, and when I run the above query I am gettng syntax error returned. When I run them one by one, its ok.
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near
'CREATE TABLE test.testtbl( id int(5))' at line 1
The code to run the query is below (above statement is assigned to 'sql' variable):
session = sf.openSession();
session.beginTransaction();
Query qry = session.createSQLQuery(sql);
qry.executeUpdate();
session.getTransaction().commit();
Any help would be appreciated.
As others have explained
You must run these queries one by one.
The hibernate code gets translated into running one update statement on JDBC.
But you provided two update statements.
In addition,
I personally prefer to have the code that creates tables outside of the Java application, in some DB scripts.
The parameters of the method createSQLQuery is t-sql code;
t-sql code to ensure that in the mysql interface analyzer correctly.
You can try changed the sql :'CREATE TABLE testtbl(id int(5));'
by the way you can use JDBC Connection api (Don't recommend to do so)
Such as:
java.sql.Connection conn=session.connection();

Created a Java Web app/MySql app

Started coming up with a java web app for online user interaction. Decided to use a MySql DB for data storage. I have already created the tables with the proper/expected data types. My question is I always thought the next step would be to creat stored procedures like Search/Add/Delete/etc.. that the user could envoke from the page. So in my java code I could just call the procedure ex:
CallableStatement cs;
Try
{
String outParam = cs.getString(1); // OUT parameter
// Call a procedure with one in and out parameter
cs = connection.prepareCall("{call SearchIt(?)}");
cs.registerOutParameter(1, Types.VARCHAR);
cs.setString(1, "a string");
cs.execute();
outParam = cs.getString(1);
}
catch (SQLException e) {
}
but if my application was not in the need for stored procedures because the user actions would be simple enough to execute simple tedious queries. How could I set up my Java and Sql code to handle that. Could I just have the "Select" or "Update" statements in my code to manipulate the data in my MySQL DB. If so how would that syntax look like?
This URL has documentation on using prepared statements which is what you want to use to avoid security flaws (SQL Injection and such).
http://download.oracle.com/javase/tutorial/jdbc/basics/prepared.html
here's an example from that page
PreparedStatement updateSales = connection.prepareStatement(
"UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? ");
updateSales.setInt(1, 75);
updateSales.setString(2, "Colombian");
updateSales.executeUpdate():
Just use Statement, or PreparedStatement.
http://download.oracle.com/javase/1.4.2/docs/api/java/sql/Statement.html
In a similar way to what you did, just call :
Statement stm = Connection.createStatement();
then execute your SQL :
stm.execute("SELECT * FROM MYTABLE");
grab the resultset and check out the results.
Beware though - this is bad bad as far as security goes - as others have mentioned, PreparedStatements are a bit more secure, but still not 100%.
To be honest, although basic JDBC is pretty simple, I really hate all the SQL strings littered around your code. If you want something a bit more elegant have a quick look at hibernate - it hides all the hackiness from you, and is also pretty easy to setup.

Categories