Store Hibernate Query in variable - java

we are using hibernate to Insert/Update/Delete data in mysql db.
whenever the hibernate query is fired it is shown on console.
But my requirement is to store the query in db for audit purpose. hence i would require to store the query in a string variable so that i can further save it in db.
public int updatebarePumpData(Tbl13BarePumpData barePumpData)
{
if (log.isInfoEnabled())
log.info("start--BarePumpGADaoImpl---updatebarePumpData");
int ans = 0;
session = HibernateUtil.getSessionFactory().getCurrentSession();
try
{
tx = session.beginTransaction();
Tbl13BarePumpData barepumpObj = (Tbl13BarePumpData) session.load(Tbl13BarePumpData.class, barePumpData.getBarePumpdataId());
barepumpObj.getBarePumpdataId();
barepumpObj.setParameter(barePumpData.getParameter());
barepumpObj.setValue(barePumpData.getValue());
barepumpObj.setModifiedBy(barePumpData.getModifiedBy());
barepumpObj.setModifiedDate(barePumpData.getModifiedDate());
session.save(barepumpObj);
tx.commit();
ans = barepumpObj.getBarePumpdataId();
}
catch (Exception e)
{
if (tx != null && tx.isActive())
tx.rollback();
log.error(e.getMessage(), e);
}
if (log.isInfoEnabled())
log.info("end--BarePumpGADaoImpl---updatebarePumpData");
return ans;
}
The console output is
Hibernate: update pumpManagement_mp.dbo.tbl_13_barePump_data set barepumpga_id=?, parameter=?, value=?, createdBy=?, createdDate=?, modifiedBy=?, modifiedDate=?, company=? where barePumpdata_id=?
I would like to have the same Output in a variable
String qry=hibernate show query
Any help would be appreciated
Thanks & Regards,
Pranav C Lunavat

Following code help you how to get sql query of Criteria.
Criteria criteria = session.createCriteria(User.class);
CriteriaImpl c = (CriteriaImpl)criteria;
SessionImpl s = (SessionImpl)c.getSession();
SessionFactoryImplementor factory = (SessionFactoryImplementor)s.getSessionFactory();
String[] implementors = factory.getImplementors( c.getEntityOrClassName() );
CriteriaLoader loader = new CriteriaLoader((OuterJoinLoadable)factory.getEntityPersister(implementors[0]),
factory, c, implementors[0], s.getEnabledFilters());
Field f = OuterJoinLoader.class.getDeclaredField("sql");
f.setAccessible(true);
String sql = (String)f.get(loader);
I hope this will help you.

There is this way of using a JDBCAppender of log4j, and then use log4j configuration as below. How much of unwanted logs, because of the nature of Hibernate, is something which you will have to try and find out.
Log4j DB Logging
Something like this will be your final configuration.
log4j.rootLogger = DEBUG, DB
log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DB.URL=jdbc:mysql://localhost/DBNAME
log4j.appender.DB.driver=com.mysql.jdbc.Driver
log4j.appender.DB.user=user_name log4j.appender.DB.password=password
log4j.appender.DB.sql=INSERT INTO LOGS VALUES('%x','%d','%C','%p','%m')
log4j.appender.DB.layout=org.apache.log4j.PatternLayout

Related

Hibernate for simple query

I am a newbie in hibernate and started working on it . I am trying to use hibernate for one of my project which contains a simple Login page .
Someone (senior) told me why to use hibernate for such a simple query, it will have a performance issue and I should use simple JDBC for that page.
Can anyone advice me for what type of queries I can use in hibernate ?
Thanks
The question of performance is everywhere and not unique to hibernate so it all depends on how you structure your Project because even in JDBC for example there is a strong argument of using PreparedStatement in place of Statement. In Hibernate you can use HSQL or opt for the more cool Criteria API. I actually prefer the Criteria API because I do not have to write any query, I leave that to the Hibernate engine.
So assuming you have a table called Users in your database and it contains the username and password for login in users, a simple boolean method like this will serve you very well and as you can notice, you will not need to write any query. This actually makes your application more independent in regards to databases because it works with most databases with minimal changes.
public static boolean userExists(String userName, String userPassword) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = null;
long count = 0;
try {
tx = session.beginTransaction();
Criteria cr = session.createCriteria(Users.class);//Users.class is the mapping class for your database Objects.
cr.add(Restrictions.eq("userName", userName));
cr.add(Restrictions.eq("userPassword", userPassword));
count = (Long) cr.setProjection(Projections.rowCount()).uniqueResult();
tx.commit();
} catch (Exception asd) {
System.out.println(asd.getMessage());
if (tx != null) {
tx.rollback();
}
} finally {
session.close();
}
return count > 0;
}
So when you pass username and password parameters if a user and password matches, the boolean will return true otherwise it will return false.
In the background the engine will generate this query:
select count(*) from Users where user_name = ? and user_password = ?
There is a nice tutorial here where you can refer.

Changing MySQL login credentials with Hibernate

I've seen a bunch of links about changing the credentials that hibernate uses to connect to a database, but nothing about whether or not you can use hibernate to execute something like SET PASSWORD FOR 'username'= PASSWORD('password'). I'd also like to be able to grand users privileges, display all the databases and create new users as well. Basically can I do anything other than table operations with Hibernate?
For example I've tried the following to create a user:
SessionFactory factory = new Configuration.configuration().buildSessionFactory();
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
String query = "CREATE USER 'testUser' IDENTIFIED BY 'password'";
SQLQuery query = session.createSQLQuery(query);
tx.commit();
}catch(HibernateException e){
if(tx != null){
tx.rollback();
}
e.printStackTrace();
}finally{
session.close();
}
factory.close();
I know it runs everything correctly, but no user is created.
You need to call executeUpdate() on your SQLQuery instance - query.executeUpdate() - this will issue your CREATE USER statement to the database. Currently you're creating the query instance and doing nothing with it.

how to update the table in java using hibernate without using hql and sql

I have tried a lot to update my table using hql but i didn't find the solution , i have searched on internet too, I am new in java and hibernate please help me to find the solution.
my code is written below.
session.getTransaction().begin();
Query query = session.createQuery("update DocDetail set DocName = :docname" +
" where Id = :docId");
query.setParameter("docname", "Jack");
query.setParameter("docId", 3);
int result = query.executeUpdate();
session.getTransaction().commit();
but I got the following error.
Exception in thread "AWT-EventQueue-0" org.hibernate.QueryException: query must begin with SELECT or FROM: update [update clinic.entity.DocDetail set DocName = :studentName where Id = :studentId]
at org.hibernate.hql.classic.ClauseParser.token(ClauseParser.java:106)
at org.hibernate.hql.classic.PreprocessingParser.token(PreprocessingParser.java:131)
at org.hibernate.hql.classic.ParserHelper.parse(ParserHelper.java:51)
If you are using hibernate, you should try to access entities not tables.
The biggest advantage of hibernate is that it provides you ORM (object relational mapping).
Here is the example how to update an entity with hibernate
(of course corresponding table is also updated).
/* Method to UPDATE salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
You are creating a Native(SQL) query using createQuery() method instead of createSQLQuery() method so just change your code as follows
session.getTransaction().begin();
Query query = session.createSQLQuery(
"update DocDetail set DocName = :docname" + " where Id = :docId");
query.setParameter("docname", "Jack");
query.setParameter("docId", 3);
int result = query.executeUpdate();
session.getTransaction().commit();
read about about this in detail:
Different ways to create query
Difference between createQuery and createSQLQuery
hope this will solve your problem
To update object without SQL or HQL you can use next code snippet.
Session sess = factory.openSession();
Transaction tx;
try {
tx = sess.beginTransaction();
sess.update(yourObject);
tx.commit();
}
catch (Exception e) {
if (tx!=null) tx.rollback();
throw e;
}
finally {
sess.close();
}
Read documentation about update - possible you have to use merge or saveOrUpdate.
Here a way of updating data into table using hibernate hql:
Configuration cfg = new Configuration();
cfg.configure("HibernateService/hibernate.cfg.xml");
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Transaction t = session.beginTransaction();
String hql = "UPDATE Userreg SET uname = :uname, uemail = :uemail, uphone = :uphone WHERE uemail = :uemail";
Query query = session.createQuery(hql);
query.setParameter("uname", uname);
query.setParameter("uemail", uemail);
query.setParameter("uphone", uphone);
int rr = query.executeUpdate();
t.commit();
if (rr != 0) {
return true;
} else {
return true;
}
you can use hibernate session's merge.
such as
User user = session.find("1");
//get Persistence entity``String userName = user.getUserName(); // userName = "enzo"
//user.setUserName("leo");
session.merge(user);
// Test entity user's useName
String userNameNew = session.find("1").getUserName; // now userName is "leo"
I hope can help you;

Hibernate's Criteria query makes Tomcat become not responive after a few request services

I am running a Spring + Hibernate web application on Tomcat 7.0.35 (Spring 3.1, Hibernate 3.6.1, JPA 2.0).
This app has a page that gets data from the database via Hibernate's Criteria (I know I dont have to). The service tier simply calls the data tier. Here is the code:
Criteria criteria = sessionFactory.openSession().createCriteria(Article.class);
criteria.addOrder(Order.desc("updatedTime"));
criteria.add(Restrictions.eq("account", acc));
criteria.add(Restrictions.eq("draft", true));
criteria.setMaxResults(1);
Article s = (Article) criteria.uniqueResult();
return s;
Tomcat can only serve a few requests from this page, and then it becomes non-responsive. I can see the browser keeps waiting for server response (Firefox status bar shows "waiting for host".)
I am not seeing any error message such as OutOfMemory, etc. It appears that the browser waits forever.
If I change it to JPA as follows:
#NamedQuery(name = "Article.getMostRecentDraftArticle", query = "select x from Article x where x.account = :account and x.draft = 1 order by x.updatedTime desc"),
.....
Query q = getSession().getNamedQuery("Article.getMostRecentDraftArticle");
q.setParameter("account", acc);
q.setMaxResults(1);
List list = q.list();
if (list.size() == 0)
return null;
else
return (Article) list.get(0);
Then everything works right.
What could go wrong with my use of Hibernate's Criteria API?
Thanks for any input!
Cheers.
You haven't closed the session. See this answer: https://stackoverflow.com/a/4049758/116509
and read the javadoc of org.hibernate.session:
A typical transaction should use the following idiom:
Session sess = factory.openSession();
Transaction tx;
try {
tx = sess.beginTransaction();
//do some work
...
tx.commit();
}
catch (Exception e) {
if (tx!=null) tx.rollback();
throw e;
}
finally {
sess.close();
}
Can you see the hibernate logs? does it generate the query?
Anyway, you can try to put a sessionFactory.getCurrentSession().flush(); below Article s = (Article) criteria.uniqueResult();

Best way to get Session and Release session in HIbernate/SQL

Consider the below two codes.
Session session = null;
query = "update Employee set EMPLOYEE_NAME = 'Jay' where EMPLOYEE_ID = 1";
try {
session = getSession();
Query query = session.createSQLQuery(dlquery);
query.executeUpdate();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if(session != null) {
releaseSession(session);
}
}
And....
Session session = getSession();
query = "update Employee set EMPLOYEE_NAME = 'Jay' where EMPLOYEE_ID = 1";
try {
Query query = session.createSQLQuery(dlquery);
query.executeUpdate();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if(session != null) {
releaseSession(session);
}
}
Which among the two is better to use? Or is there a better way? What wrong I might be doing here?
Also should we do a null check before calling releaseSession(session) in finally?
Truly, the best way is to leverage Spring and its JPA/Hibernate support.... You'll never have to deal with it in your code.
To be honest, I'd say there wasn't much difference at all in the two, but you should always check if the session is null, just so you don't cause another NullReferenceException.
Unfortunately this is probably the cleanest way to do this in Java, as there is no such thing as the "using" statement as there is in C#, which allows you to dispose the object after the using block has finished executing.
I would suggest using a transaction. If tomorrow you change your code to add another update for instance, you won't have to worry about any consistency problem in case something happens while executing an update. Aside from that, I would suggest using parameters in your query rather than hard-coding the values. This way you could reuse the query.
If getSession() throws an Exception for some reason, would not it be problem in second solution?
Use the below syntax to get and release session.
session = getSession();
Query query = session.createSQLQuery(dlquery);
query.executeUpdate();
session.close();

Categories