Constructing a SQL save, update, remove query from hibernate entities? - java

Is it possible to create native SQL-queries for saving, updating or removing certain entities from the database via hibernate ?
What i am searching for is pretty much this...
String sqlQuery = session.save(listOfEntities);
session.execute(sqlQuery);
sqlQuery : "insert into players(id,...) values((10,...),(11,...))"

Why would you need the statements? Just doing session.persist(entity) will execute the statement for you already.

Related

sql query very slow in Hibernate, fast on mysql

I have a really simple query to select all rows from a table. In hibernate it always takes about 17-18 seconds. I specified, show_sql to be true. I copied the sql command directly to mysql and it took 0.00022 seconds...
this is the query:
SELECT
organizati0_.id AS id1_5_,
organizati0_.adminList AS adminLis2_5_,
organizati0_.demoAccount AS demoAcco3_5_,
organizati0_.disabled AS disabled4_5_,
organizati0_.enduserCredits AS enduserC5_5_,
organizati0_.name AS name6_5_,
organizati0_.pushNotificationRoom AS pushNoti7_5_,
organizati0_.totalLicenses AS totalLic8_5_,
organizati0_.usedLicenses AS usedLice9_5_
FROM
organization organizati0_
this is the code for the query:
Session session = ThreadSessionHolder.getThreadSession();
Query query = session.createQuery("from Organization ");
List list = query.list();
return list;
any ideas? this is driving me nuts
I found the issue.
I was performing an initialization operation in the constructor which shouldn't be done when selecting all

Criteria Query returnig all records

SQL :
String hql1 = "SELECT /* PARALLEL(MVR,16) PARALLEL(MVRS,16)*/ * FROM
ICM MINUS SELECT I1.* FROM ICM I1 , C1_ICM_STATIC I2 WHERE
I1.METRIC_DIRECTION=I2.METRIC_DIRECTION AND
I1.METRIC_NAME=I2.METRIC_NAME AND I1.METRIC_UNIT=I2.METRIC_UNIT AND
I1.TERMINATION_POINT_ID=I2.TERMINATION_POINT_ID AND
I1.TERMINATION_POINT_NAME=I2.TERMINATION_POINT_NAME AND
I1.TERMINATION_POINT_TYPE=I2.TERMINATION_POINT_TYPE";
Criteria Query
icms1 = (List<ICM>) session.createCriteria(ICM.class, hql1).list();
I have executed hql1 using SQL Developer then I got only one result, but when I have integrated SQL Query with Criteria it returning me all records in ICM table.
If SQL query returning only one result in SQL Developer, Why criteria API returning all records in ICM table?
Why criteria API returning all records in ICM table?
Technically you are not using criteria api for associations.
Try something like this.
Refer.
return criteria.createCriteria(A.class)
.createCriteria("b", "join_between_a_b")
.createCriteria("c", "join_between_b_c")
.createCriteria("d", "join_between_c_d")
.add(Restrictions.eq("some_field_of_D", someValue));
You should learn to read API documentation.
The second Session.createCriteria() argument is the alias that you want to assign to the root entity. It's not a HQL query. HQL queries are not executed using Session.createCriteria(). They're executed using Session.createQuery().
BTW, your query is not a HQL query at all. It's a SQL query. SQL and HQL are 2 different languages. To execute a SQL query, you need createSQLQuery().

Slow performance on Hibernate + Java but fast when I use TOAD with the same native Oracle query

I've detected a performance problem with hibernate and native queries on Oracle. When I execute a complex SQL query with several parameters on TOAD I get the result in miliseconds. However, when I execute the same query using Hibernate this time is incremented hugely (up to four seconds or even more).
My SQL query is rather complex, return an unique value (so, the problem is not related with the time necessary to instation classes) and it contains several parameters with the the format ':nameParameter'. This query is stored in a String. For example,
String myNamedNativeQuery = "select count(*) from tables "+
"where column1 = :nameParameter1 "+
"and column2 = :nameParameter2";
//actually my sentence is much more complex!!
When I execute the sentence on TOAD it is resolved in few miliseconds. But using this sentence with Hibernate
SQLQuery query = session.createSQLQuery("myNamedNativeQuery");
query.setParameter(nameParameter1, value1);
query.setParameter(nameParameter2, value2);
query.uniqueResult();
are necessary several seconds to get the same result.
I realized if I replaced the parameters directly on the native query and then I execute the sentence using Hibernate the time decreases drastically. It would be something like that:
String strQuery = session.getNamedQuery("myNamedNativeQuery").getQueryString();
myNamedNativeQuery = myNamedNativeQuery.replace("nameParameter1", value1);
myNamedNativeQuery = myNamedNativeQuery.replace("nameParameter2", value2);
SQLQuery query = session.createSQLQuery("myNamedNativeQuery");
query.uniqueResult();
Anybody knows what's happening??
Thanks in advance.
PS: The Oracle version is 9i and Hibernate 3.2
I think what's happening with this code :
SQLQuery query = session.createSQLQuery("myNamedNativeQuery");
query.setParameter(nameParameter1, value1);
query.setParameter(nameParameter2, value2);
query.uniqueResult();
is this:
at line 1 : a query plan is created based on some expected values for your named parameters.
at line 4 : the query is executed with value1 and value2, but those values are not "good values" for the query plan that was elaborate at line 1 and so, the database is executing a very inappropriate plan for the actual values and it takes a lot of time.
Why ?
Looking at the source code of HibernateSessionImpl.createSQLQuery(...) I found this line of code:
SQLQueryImpl query = new SQLQueryImpl(
sql,
this,
factory.getQueryPlanCache().getSQLParameterMetadata( sql )
);
which is calling getQueryPlanCache() with some parameterMetaData. I assume that this metadata is not good enough.
My answer to you is:
Remove all bind parameters and use StatelessSession instead of Session
Use SQLQuery instead of query with full SQL including parameter values
StatelessSession session = sessionFactory.openStatelessSession();
I had similar problem and till I get better solution,this is what I managed to make it work.
See Hibernate parameterized sql query slow and active oracle sessions
<property name = "hibernate.temp.use_jdbc_metadata_defaults">false</property>
Add this to your hibernate.cfg.xml or update your application properties file.

how to execute the stored procedure in hibernate 3

I am new in hibernate. I am using hibernate 3 in my application using hibernate annotations , I am developing application in struts 1.3.
My question is :
I have googled a lot but could not understand how to call a stored procedure in hibernate using annotations , I have a simple scenario : suppose I have 2 fields in my jsp say 1) code 2) name , I have created a stored procedure in database for inserting those records into table. Now my problem is that how to execute it
List<MyBean> list = sessionFactory.getCurrentSession()
.getNamedQuery("mySp")
.setParameter("code", code)
.setParameter("name", name)
I don't know the exact code how to do this. But I guess something like that actually I come from jdbc background therefore have no idea how to do this and same thing I want when selecting the data from database using stored procedure.
Hibernate provides many simple ways to call a SP like
Native SQL
Named Query in native SQL as Annotation/XML mapping file
Following link shows how each of above can be implemented
http://www.mkyong.com/hibernate/how-to-call-store-procedure-in-hibernate/
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querysql.html#sp_query
Sample to run native SQL query using hibernate:
Session session = getSession();
SQLQuery sqlQuery = session.createSQLQuery("SELECT COUNT(id) FROM tableName WHERE external_id = :external_id");
sqlQuery.setParameter("external_id", idValue);
int count = ((BigInteger) sqlQuery.uniqueResult()).intValue();
releaseSession(session);
You can execute your stored procedure using Hibernate's SQLQuery with the same SQL as when you call it against the database. For example, in postgreSQL:
String query = "select schema.procedure_name(:param1)";
SQLQuery sqlquery = sessionFactory.getCurrentSession().createSQLQuery(query);
sqlquery.setInteger("param1", "this is first parameter");
sqlQuery.list();
Hope it helps.

convert sql to hql

I am performing this via sql but i want to do this in hql, select statement in from ( select count(*)...) not works in hql, any sugestion and optimization would be appreciated
SELECT u.username,u.device_tocken,sr.count
from users u,
(select count(*) as count ,ssr.recepient as res from survey_recipient ssr where
(ssr.is_read is false and ssr.recepient in ('abc','xyz'))group by ssr.recepient ) sr
where
(u.username = sr.res and u.device_tocken is not null)
Hibernate does not support subselects in from clouse.
i tried many things and gave up when i found this jira issue.
see here https://hibernate.onjira.com/browse/HHH-3356
But if you have to use subselect you can create database views and use them in your sql as normal tables.

Categories

Resources