Exception : using inner joins in hibernate - mysql

I have a sql query like below,
SELECT patient.*,
contact.telephone
from patient
INNER JOIN contact ON patient.`idPatient` = contact.`idPatient`
These are my works,
Patient.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Sep 8, 2016 1:55:08 PM by Hibernate Tools 4.3.1 -->
<hibernate-mapping>
<class name="db.Patient" table="patient" catalog="example_hibernate" optimistic-lock="version">
<id name="idPatient" type="java.lang.Integer">
<column name="idPatient" />
<generator class="identity" />
</id>
<property name="title" type="string">
<column name="title" length="45" />
</property>
<property name="firstName" type="string">
<column name="firstName" length="45" />
</property>
<property name="lastName" type="string">
<column name="lastName" length="45" />
</property>
<property name="middleName" type="string">
<column name="middleName" length="45" />
</property>
<property name="dob" type="date">
<column name="dob" length="10" />
</property>
<property name="martitalStatus" type="java.lang.Boolean">
<column name="martitalStatus" />
</property>
<property name="gender" type="string">
<column name="gender" length="45" />
</property>
<property name="nic" type="string">
<column name="nic" length="45" />
</property>
<property name="dateCreated" type="timestamp">
<column name="dateCreated" length="19" />
</property>
<property name="lastUpdated" type="timestamp">
<column name="lastUpdated" length="19" not-null="true" />
</property>
<set name="contacts" table="contact" inverse="true" lazy="true" fetch="select">
<key>
<column name="idPatient" not-null="true" />
</key>
<one-to-many class="db.Contact" />
</set>
</class>
</hibernate-mapping>
Contact.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Sep 8, 2016 1:55:08 PM by Hibernate Tools 4.3.1 -->
<hibernate-mapping>
<class name="db.Contact" table="contact" catalog="example_hibernate" optimistic-lock="version">
<id name="idContact" type="java.lang.Integer">
<column name="idContact" />
<generator class="identity" />
</id>
<many-to-one name="patient" class="db.Patient" fetch="select">
<column name="idPatient" not-null="true" />
</many-to-one>
<property name="telephone" type="string">
<column name="telephone" length="45" />
</property>
<property name="address" type="string">
<column name="address" length="45" />
</property>
</class>
</hibernate-mapping>
Then I used above sql like below,
SessionFactory sessionFactory = new HibernateUtil().getSessionFactory();
Session session = sessionFactory.openSession();
List<Object[]> africanContinents = session.createQuery(
"SELECT patient.*,\n"
+ "contact.telephone\n"
+ "from patient\n"
+ "INNER JOIN contact ON patient.`idPatient` = contact.`idPatient`")
.list();
HibernateUtil.shutdown();
But this bought me following exception
org.hibernate.QueryException: unexpected char: '`' [SELECT patient.*,
contact.telephone
from patient
INNER JOIN contact ON patient.`idPatient` = contact.`idPatient`]
I have no idea about how to handle this exception . Because this sql query is correct.
Have any ideas about this exception ?

The query in createQuery should be written in HQL or JPQL.
So you could rewrite your query in HQL (something 'like select p,c.telephone from patient inner join contact') see documentation here
Or you could use your SQL query by calling session.createSQLQuery instead of session.createQuery
Hope this helps.
Sebastien

Related

org.hibernate.MappingException: Association references unmapped class: empresa.Empleados

I have a configuration of hibernate with two tables in Mysql and the files of configuration of Pojo are the following:
<hibernate-mapping>
<class name="empresa.Departamentos" table="departamentos" catalog="empresa2" optimistic-lock="version">
<id name="deptno" type="int">
<column name="deptno" />
<generator class="assigned" />
</id>
<property name="dnombre" type="string">
<column name="dnombre" length="15" />
</property>
<property name="loc" type="string">
<column name="loc" length="15" />
</property>
<set name="empleadoses" table="empleados" inverse="true" lazy="true" fetch="select">
<key>
<column name="deptno" not-null="true" />
</key>
<one-to-many class="empresa.Empleados" />
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="empresa.Empleados" table="empleados" catalog="empresa2" optimistic-lock="version">
<id name="empno" type="short">
<column name="empno" />
<generator class="assigned" />
</id>
<many-to-one name="departamentos" class="empresa.Departamentos" fetch="select">
<column name="deptno" not-null="true" />
</many-to-one>
<property name="apellido" type="string">
<column name="apellido" length="10" />
</property>
<property name="oficio" type="string">
<column name="oficio" length="10" />
</property>
<property name="dir" type="java.lang.Short">
<column name="dir" />
</property>
<property name="fechaalt" type="date">
<column name="fechaalt" length="10" />
</property>
<property name="salario" type="java.lang.Float">
<column name="salario" precision="6" />
</property>
<property name="comision" type="java.lang.Float">
<column name="comision" precision="6" />
</property>
</class>
</hibernate-mapping>
Next, when I execute the following sentence in hql:
select e from Empleados e where e.departamentos.deptno in (select d.deptno from Departamentos d where d.loc='London')
It gives me the following error:
org.hibernate.MappingException: Association references unmapped class: empresa.Empleados
at org.hibernate.cfg.HbmBinder.bindCollectionSecondPass(HbmBinder.java:2557)
at org.hibernate.cfg.HbmBinder$CollectionSecondPass.secondPass(HbmBinder.java:2808)
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:70)
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1695)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1424)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928)
Regards,
Javier
The solution is:
select e.apellido
from Empleados e
where e.departamentos.deptno in
(select d.deptno
from Departamentos d
where d.loc='Sevilla')

Hibernate Exception: While migrating from mysql to oracle 11g db

I am trying to change my application database from mysql to oracle 11g. I am using hibernate in this application but hibernate is throwing:
org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.loader.Loader.doList(Loader.java:2231)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2125)
at org.hibernate.loader.Loader.list(Loader.java:2120)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:312)
at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1722)
at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:165)
at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:175)
Below is my hibernate.cfg.xml file:
*<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<!-- <property name="hibernate.default_schema">wind</property> -->
<property name="show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">validate</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.cache.use_query_cache">false</property>
<!-- <property name="connection.autoReconnect">true</property> -->
<!-- <property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">100</property>-->
<property name="hibernate.c3p0.timeout">25200</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>*
I am using one config file for database url and id password.
DATABASE_URL=jdbc:oracle:thin:#localhost:1521/wind
DATABASE_USERNAME=appuser
DATABASE_PASSWORD=appuser
DATABASE_CONN_POOL_MIN=5
DATABASE_CONN_POOL_MAX=50
Mapping file:
<hibernate-mapping>
<class name="com.nsn.abc.entity.UserInfo" table="user_info" >
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="assigned" />
</id>
<property name="username" type="string">
<column name="username" length="30" not-null="true" unique="true" />
</property>
<property name="firstName" type="string">
<column name="first_name" length="30" not-null="true" />
</property>
<property name="lastname" type="string">
<column name="lastname" length="30" />
</property>
<property name="email" type="string">
<column name="email" length="50" />
</property>
<property name="password" type="string">
<column name="password" length="30" not-null="true" />
</property>
<property name="phoneNumber" type="string">
<column name="phone_number" length="30" />
</property>
<property name="rights" type="string">
<column name="rights" length="30" not-null="true" />
</property>
<property name="counter" type="int">
<column name="counter" not-null="true" />
</property>
<property name="role" type="string">
<column name="role" length="20" />
</property>
<property name="activeFlag" type="boolean">
<column name="active_flag" not-null="true" />
</property>
<property name="info" type="string">
<column name="info" length="45" />
</property>
<set name="massProvisioningHistories" table="mass_provisioning_history" inverse="true" lazy="true" fetch="select">
<key>
<column name="user_ref" not-null="true" />
</key>
<one-to-many class="com.nsn.abc.entity.MassProvisioningHistory" />
</set>
</class>
</hibernate-mapping>
I have checked all the configuration and other details but still no progress.
Its throwing SQL Error: 923, SQLState: 42000. with ORA-00923: FROM keyword not found where expected
In the logs its genrating below query:
Hibernate: select userinfo0_.id as id25_, userinfo0_.username as username25_, userinfo0_.first_name as first3_25_, userinfo0_.lastname as lastname25_, userinfo0_.email as email25_, userinfo0_.password as password25_, userinfo0_.phone_number as phone7_25_, userinfo0_.rights as rights25_, userinfo0_.counter as counter25_, userinfo0_.role as role25_, userinfo0_.active_flag as active11_25_, userinfo0_.info as info25_ from user_info userinfo0_ where userinfo0_.username=?
Please suggest.
regards,
skr
In the application, we were using the SELECT 1 for checking the hibernate connection.
MySql supports "SELECT 1" but in oracle we need to mention "SELECT 1 from dual".
Now its working fine.
thanks for help.

Hibernate join of two tables with foreign keys

I am trying to learn how to use hibernate and have run into a problem I have been stuck on for a while.
I am trying to join two tables together and display the values in a GUI form. I have tried researching for an answer but my case seems to be different then others listed. It seems to be a problem with the relationship between the ids of each table.
Here is the only statement I can get to display any results but it basically displays the same GameTemplates table twice.
Close as I can get:
from GameTemplates gt join gt.id.partNum Tickets
Desired SQL:
select * from Game_Templates
inner join Tickets
where
Game_Templates.part_Num = Tickets.game_Templates_Part_Num
GameTemplates.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Sep 8, 2015 7:01:43 PM by Hibernate Tools 4.3.1 -->
<hibernate-mapping>
<class name="entity.GameTemplates" table="game_templates" catalog="fire_tickets">
<composite-id name="id" class="entity.GameTemplatesId">
<key-property name="partNum" type="string">
<column name="part_num" length="12" />
</key-property>
<key-property name="distsIdDistId" type="int">
<column name="dists_id_dist_id" />
</key-property>
<key-property name="mfgIdMfgId" type="int">
<column name="mfg_id_mfg_id" />
</key-property>
</composite-id>
<many-to-one name="distsId" class="entity.DistsId" update="false" insert="false" fetch="select">
<column name="dists_id_dist_id" not-null="true" />
</many-to-one>
<many-to-one name="mfgId" class="entity.MfgId" update="false" insert="false" fetch="select">
<column name="mfg_id_mfg_id" not-null="true" />
</many-to-one>
<property name="gameName" type="string">
<column name="game_name" length="20" />
</property>
<property name="gameCost" type="java.lang.Double">
<column name="game_cost" precision="22" scale="0" />
</property>
<property name="ticketCost" type="java.lang.Double">
<column name="ticket_cost" precision="22" scale="0" />
</property>
<property name="numTickets" type="java.lang.Integer">
<column name="num_tickets" />
</property>
<property name="ideaGross" type="java.lang.Integer">
<column name="idea_gross" />
</property>
<property name="ideaPrizes" type="java.lang.Integer">
<column name="idea_prizes" />
</property>
<property name="ideaNet" type="java.lang.Integer">
<column name="idea_net" />
</property>
<property name="lastSale" type="java.lang.Integer">
<column name="Last_sale" />
</property>
<property name="lastSaleAllow" type="java.lang.Integer">
<column name="Last_sale_allow" />
</property>
<property name="prizeAmt1" type="java.lang.Integer">
<column name="Prize_amt1" />
</property>
<property name="prizeAmt2" type="java.lang.Integer">
<column name="Prize_amt2" />
</property>
<property name="prizeAmt3" type="java.lang.Integer">
<column name="Prize_amt3" />
</property>
<property name="prizeAmt4" type="java.lang.Integer">
<column name="Prize_amt4" />
</property>
<property name="prizeAmt5" type="java.lang.Integer">
<column name="Prize_amt5" />
</property>
<property name="prizeAmt6" type="java.lang.Integer">
<column name="Prize_amt6" />
</property>
<property name="prizeAmt7" type="java.lang.Integer">
<column name="Prize_amt7" />
</property>
<property name="prizeAmt8" type="java.lang.Integer">
<column name="Prize_amt8" />
</property>
<property name="prizeAmt9" type="java.lang.Integer">
<column name="Prize_amt9" />
</property>
<property name="prizeAmt10" type="java.lang.Integer">
<column name="Prize_amt10" />
</property>
<property name="prizeAmt11" type="java.lang.Integer">
<column name="Prize_amt11" />
</property>
<property name="prizeAmt12" type="java.lang.Integer">
<column name="Prize_amt12" />
</property>
<property name="prizeAmt13" type="java.lang.Integer">
<column name="Prize_amt13" />
</property>
<property name="prizeAmt14" type="java.lang.Integer">
<column name="Prize_amt14" />
</property>
<property name="prizeAmt15" type="java.lang.Integer">
<column name="Prize_amt15" />
</property>
<property name="prizeAll1" type="java.lang.Integer">
<column name="Prize_all1" />
</property>
<property name="prizeAll2" type="java.lang.Integer">
<column name="Prize_all2" />
</property>
<property name="prizeAll3" type="java.lang.Integer">
<column name="Prize_all3" />
</property>
<property name="prizeAll4" type="java.lang.Integer">
<column name="Prize_all4" />
</property>
<property name="prizeAll5" type="java.lang.Integer">
<column name="Prize_all5" />
</property>
<property name="prizeAll6" type="java.lang.Integer">
<column name="Prize_all6" />
</property>
<property name="prizeAll7" type="java.lang.Integer">
<column name="Prize_all7" />
</property>
<property name="prizeAll8" type="java.lang.Integer">
<column name="Prize_all8" />
</property>
<property name="prizeAll9" type="java.lang.Integer">
<column name="Prize_all9" />
</property>
<property name="prizeAll10" type="java.lang.Integer">
<column name="Prize_all10" />
</property>
<property name="prizeAll11" type="java.lang.Integer">
<column name="Prize_all11" />
</property>
<property name="prizeAll12" type="java.lang.Integer">
<column name="Prize_all12" />
</property>
<property name="prizeAll13" type="java.lang.Integer">
<column name="Prize_all13" />
</property>
<property name="prizeAll14" type="java.lang.Integer">
<column name="Prize_all14" />
</property>
<property name="prizeAll15" type="java.lang.Integer">
<column name="Prize_all15" />
</property>
</class>
</hibernate-mapping>
Tickets.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Sep 8, 2015 7:01:43 PM by Hibernate Tools 4.3.1 -->
<hibernate-mapping>
<class name="entity.Tickets" table="tickets" catalog="fire_tickets">
<composite-id name="id" class="entity.TicketsId">
<key-property name="serial" type="string">
<column name="Serial" length="12" />
</key-property>
<key-property name="gameTemplatesPartNum" type="string">
<column name="game_templates_part_num" length="12" />
</key-property>
</composite-id>
<property name="datePlaced" type="date">
<column name="Date_placed" length="10" />
</property>
<property name="dateRemoved" type="date">
<column name="Date_removed" length="10" />
</property>
<property name="unsoldAmt" type="java.lang.Integer">
<column name="Unsold_amt" />
</property>
<property name="actualGross" type="java.lang.Integer">
<column name="Actual_gross" />
</property>
<property name="actualPrizes" type="java.lang.Integer">
<column name="Actual_prizes" />
</property>
<property name="actualNet" type="java.lang.Integer">
<column name="Actual_net" />
</property>
<property name="bin" type="java.lang.Integer">
<column name="Bin" />
</property>
<property name="inplay" type="java.lang.Boolean">
<column name="Inplay" />
</property>
<property name="closed" type="java.lang.Integer">
<column name="Closed" />
</property>
<property name="unsoldTickets" type="java.lang.Integer">
<column name="Unsold_tickets" />
</property>
<property name="lastSaleRem" type="java.lang.Byte">
<column name="Last_sale_rem" />
</property>
<property name="prizeRem1" type="java.lang.Integer">
<column name="Prize_rem1" />
</property>
<property name="prizeRem2" type="java.lang.Integer">
<column name="Prize_rem2" />
</property>
<property name="prizeRem3" type="java.lang.Integer">
<column name="Prize_rem3" />
</property>
<property name="prizeRem4" type="java.lang.Integer">
<column name="Prize_rem4" />
</property>
<property name="prizeRem5" type="java.lang.Integer">
<column name="Prize_rem5" />
</property>
<property name="prizeRem6" type="java.lang.Integer">
<column name="Prize_rem6" />
</property>
<property name="prizeRem7" type="java.lang.Integer">
<column name="Prize_rem7" />
</property>
<property name="prizeRem8" type="java.lang.Integer">
<column name="Prize_rem8" />
</property>
<property name="prizeRem9" type="java.lang.Integer">
<column name="Prize_rem9" />
</property>
<property name="prizeRem10" type="java.lang.Integer">
<column name="Prize_rem10" />
</property>
<property name="prizeRem11" type="java.lang.Integer">
<column name="Prize_rem11" />
</property>
<property name="prizeRem12" type="java.lang.Integer">
<column name="Prize_rem12" />
</property>
<property name="prizeRem13" type="java.lang.Integer">
<column name="Prize_rem13" />
</property>
<property name="prizeRem14" type="java.lang.Integer">
<column name="Prize_rem14" />
</property>
<property name="prizeRem15" type="java.lang.Integer">
<column name="Prize_rem15" />
</property>
<property name="datePurch" type="date">
<column name="date_purch" length="10" />
</property>
<property name="invoiceNum" type="string">
<column name="invoice_num" length="10" />
</property>
</class>
</hibernate-mapping>
Try this:
from GameTemplates gt, Tickets t where gt.id.partNum = t.id.gameTemplatesPartNum

Calling stored procedure from Hibernate / MySQL: Parameter index out of range (3 > number of parameters, which is 2)

I receive the following error when calling insert stored procedure in Hibernate while working with MySQL db:
Hibernate:
{ call InsertPayment(?, ?) }
sie 28, 2013 10:17:19 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 0, SQLState: S1009
sie 28, 2013 10:17:19 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Parameter index out of range (3 > number of parameters, which is 2).
Exception in thread "main" org.hibernate.exception.GenericJDBCException: could not insert: [model_mapping_xml.TPayment]
Stored procedure definition in MySQL db:
CREATE PROCEDURE InsertPayment(
IN pIdAnother INT,
IN pAmount DECIMAL(19,4)
)
BEGIN
...
END
TPayment.hbm.xml file contains:
<sql-insert callable="true" check="none">
{ call InsertPayment(?, ?) }
</sql-insert>
Implicit call of the stored procedure:
// calling the stored procedure to add payment
TPayment newp = new TPayment();
newp.setAnother((TAnother) session.load(TAnother.class, 1));
newp.setAmount(BigDecimal.valueOf(20));
session.save(newp);
Why does it say "3 > number of parameters" where everywhere there are 2 parameters for this procedure?
(I can call deletePayment and modifyPayment stored procedures in similar way and they work fine...).
TPayment mapping:
<hibernate-mapping>
<class name="model_mapping_xml.TPayment" table="TPayment" catalog="DB">
<id name="idPayment" type="java.lang.Integer">
<column name="IdPayment" />
<generator class="identity" />
</id>
<version name="rowvers" type="timestamp" generated="always">
<column name="Rowvers" length="19" not-null="true" />
</version>
<many-to-one name="another" class="model_mapping_xml.TAnother" fetch="select">
<column name="IdAnother" not-null="true" />
</many-to-one>
<property name="amount" type="big_decimal">
<column name="Amount" scale="4" not-null="true" />
</property>
<property name="date1" type="timestamp">
<column name="Date1" length="19" not-null="false" />
</property>
<sql-insert callable="true" check="none">
{ call InsertPayment(?, ?) }
</sql-insert>
<sql-update callable="true" check="none">
{ call ModifyPayment(?, ?, ?, ?, ?) }
</sql-update>
<sql-delete callable="true" check="none">
{ call DeletePayment(?, ?) }
</sql-delete>
</class>
</hibernate-mapping>
TAnother mapping:
<hibernate-mapping>
<class name="model_mapping_xml.TAnother" table="TAnother" catalog="DB">
<id name="idAnother" type="java.lang.Integer">
<column name="IdAnother" />
<generator class="identity" />
</id>
<property name="dateBegin" type="date">
<column name="DateBegin" length="10" not-null="true" />
</property>
<property name="dateEnd" type="date">
<column name="DateEnd" length="10" />
</property>
<property name="rowvers" type="timestamp">
<column name="Rowvers" length="19" not-null="true" />
</property>
<set name="payment" table="TPayment"
inverse="true" lazy="true" fetch="select">
<key>
<column name="IdAnother" not-null="true" />
</key>
<one-to-many class="model_mapping_xml.TPayment" />
</set>
</class>
</hibernate-mapping>

Webservice with Hibernate+MySql performance [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I have Java (Axis2) webservice with Hibernate as DAL.
Using InnoDB as the MySql engine.
I have few questions ergarding the performance:
1. usually the fetching is fast, but the time takes may vary, sometimes it takes too much time to query?
What usually takes time to query is the following query:
1 Webservice request to get user info - we do it on users table, doing search - "where name like .
1 Webservice request to get user recipes (query recipe, where r.user.userId == userId, userId is given in the webservice)
2. How to configure c3p0 connection pool to get best performance?
This taken from hibernate.cfg
<property name="connection.autoReconnect">true</property>
<property name="connection.autoReconnectForPools">true</property>
<property name="connection.is-connection-validation-required">true</property>
<property name="hibernate.connection.zeroDateTimeBehavior">convertToNull</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.show_sql">false</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>
<property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.min_size">3</property>
<property name="hibernate.c3p0.max_size">50</property>
<property name="hibernate.c3p0.timeout">280</property>
<property name="hibernate.c3p0.max_statements">50</property>
<!-- this property forces the revalidation of a connection after the given amount of time (in secs) -->
<!-- it must be set to LESS than the wait_timout setting for the mysql server (this setting defaults to 28800 secs (8 hours)) -->
<property name="hibernate.c3p0.idle_test_period">300</property>
Following are the hbm.xml files used when calling the 2 methods...
This is user.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 21:48:14 27/03/2012 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.icdb.data.User" table="user" catalog="yoavDB">
<id name="userid" type="java.lang.Integer">
<column name="userid" />
<generator class="identity" />
</id>
<property name="birthdate" type="string">
<column name="birthdate" length="50" not-null="true" />
</property>
<property name="password" type="string">
<column name="password" length="100" not-null="true" />
</property>
<property name="firstname" type="string">
<column name="firstname" length="50" not-null="true" />
</property>
<property name="lastname" type="string">
<column name="lastname" length="50" not-null="true" />
</property>
<property name="country" type="string">
<column name="country" length="100" not-null="true" />
</property>
<property name="email" type="string">
<column name="email" length="100" not-null="true" />
</property>
<property name="numOfRecipes" type="int">
<column name="numOfRecipes" not-null="true" />
</property>
<property name="picUrl" type="string">
<column name="picUrl" length="200" />
</property>
<property name="rate" type="float">
<column name="rate" precision="12" scale="0" not-null="true" />
</property>
<property name="fewWords" type="string">
<column name="fewWords" length="200" not-null="true" />
</property>
<property name="whatscooking" type="string">
<column name="whatscooking" length="45" not-null="true" />
</property>
<set name="usermessagesesForSenderUserId" table="usermessages" inverse="true" lazy="true" fetch="select">
<key>
<column name="senderUserId" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Usermessages" />
</set>
<set name="usermessagesesForUserId" table="usermessages" inverse="true" lazy="true" fetch="select">
<key>
<column name="userId" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Usermessages" />
</set>
<set name="timelines" table="timeline" inverse="true" lazy="true" fetch="select">
<key>
<column name="userId" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Timeline" />
</set>
<set name="generaltipses" table="generaltips" inverse="true" lazy="true" fetch="select">
<key>
<column name="authorid" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Generaltips" />
</set>
<set name="userlastvisitsForVisitedUserId" table="userlastvisit" inverse="true" lazy="true" fetch="select">
<key>
<column name="visitedUserId" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Userlastvisit" />
</set>
<set name="recipes" table="recipe" inverse="true" lazy="true" fetch="select">
<key>
<column name="ownerid" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Recipe" />
</set>
<set name="userlikeses" table="userlikes" inverse="true" lazy="true" fetch="select">
<key>
<column name="userId" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Userlikes" />
</set>
<set name="friendshiptablesForUserBId" table="friendshiptable" inverse="true" lazy="true" fetch="select">
<key>
<column name="userB_Id" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Friendshiptable" />
</set>
<set name="usersForFavUserId" table="userfavchefsync" inverse="true" lazy="true" fetch="select">
<key>
<column name="userId" not-null="true" />
</key>
<many-to-many entity-name="com.icdb.data.User">
<column name="favUserId" not-null="true" />
</many-to-many>
</set>
<set name="friendshiptablesForUserAId" table="friendshiptable" inverse="true" lazy="true" fetch="select">
<key>
<column name="userA_Id" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Friendshiptable" />
</set>
<set name="usersForUserId" table="userfavchefsync" inverse="true" lazy="true" fetch="select">
<key>
<column name="favUserId" not-null="true" />
</key>
<many-to-many entity-name="com.icdb.data.User">
<column name="userId" not-null="true" />
</many-to-many>
</set>
<set name="activitylogsForObjectUserId" table="activitylog" inverse="true" lazy="true" fetch="select">
<key>
<column name="objectUserId" />
</key>
<one-to-many class="com.icdb.data.Activitylog" />
</set>
<set name="userlastvisitsForGuestUserId" table="userlastvisit" inverse="true" lazy="true" fetch="select">
<key>
<column name="guestUserId" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Userlastvisit" />
</set>
<set name="userrecipessyncs" table="userrecipessync" inverse="true" lazy="true" fetch="select">
<key>
<column name="userId" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Userrecipessync" />
</set>
<set name="activitylogsForUserId" table="activitylog" inverse="true" lazy="true" fetch="select">
<key>
<column name="userId" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Activitylog" />
</set>
<set name="recipereviews" table="recipereview" inverse="true" lazy="true" fetch="select">
<key>
<column name="reviewerid" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Recipereview" />
</set>
</class>
</hibernate-mapping>
This is recipe.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 21:48:14 27/03/2012 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.icdb.data.Recipe" table="recipe" catalog="yoavDB">
<id name="recipeid" type="java.lang.Integer">
<column name="recipeid" />
<generator class="identity" />
</id>
<many-to-one name="user" class="com.icdb.data.User" fetch="select">
<column name="ownerid" not-null="true" />
</many-to-one>
<property name="releasedate" type="timestamp">
<column name="releasedate" length="19" not-null="true" />
</property>
<property name="preparationtime" type="int">
<column name="preparationtime" not-null="true" />
</property>
<property name="recipedifficulty" type="int">
<column name="recipedifficulty" not-null="true" />
</property>
<property name="name" type="string">
<column name="name" length="50" not-null="true" unique="true" />
</property>
<property name="description" type="string">
<column name="description" length="200" />
</property>
<property name="lastupdated" type="timestamp">
<column name="lastupdated" length="19" not-null="true" />
</property>
<property name="servecount" type="java.lang.Integer">
<column name="servecount" />
</property>
<property name="complete" type="boolean">
<column name="complete" not-null="true" />
</property>
<property name="category" type="int">
<column name="category" not-null="true" />
</property>
<property name="numOfViews" type="int">
<column name="numOfViews" not-null="true" />
</property>
<property name="indexOfRecipeOfUser" type="int">
<column name="indexOfRecipeOfUser" not-null="true" />
</property>
<property name="picUrl" type="string">
<column name="picUrl" length="200" />
</property>
<property name="numOfLikes" type="int">
<column name="numOfLikes" not-null="true" />
</property>
<property name="calculatedRate" type="float">
<column name="calculatedRate" precision="12" scale="0" not-null="true" />
</property>
<set name="userlastvisits" table="userlastvisit" inverse="true" lazy="true" fetch="select">
<key>
<column name="lastViewedRecipeId" />
</key>
<one-to-many class="com.icdb.data.Userlastvisit" />
</set>
<set name="recipeingredients" table="recipeingredient" inverse="true" lazy="true" fetch="select">
<key>
<column name="recipeid" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Recipeingredient" />
</set>
<set name="recipereviews" table="recipereview" inverse="true" lazy="true" fetch="select">
<key>
<column name="recipeid" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Recipereview" />
</set>
<set name="userlikeses" table="userlikes" inverse="true" lazy="true" fetch="select">
<key>
<column name="recipeId" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Userlikes" />
</set>
<set name="activitylogs" table="activitylog" inverse="true" lazy="true" fetch="select">
<key>
<column name="objectRecipeId" />
</key>
<one-to-many class="com.icdb.data.Activitylog" />
</set>
<set name="userrecipessyncs" table="userrecipessync" inverse="true" lazy="true" fetch="select">
<key>
<column name="recipeId" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Userrecipessync" />
</set>
<set name="recipeinstructions" table="recipeinstruction" inverse="true" lazy="true" fetch="select">
<key>
<column name="recipeid" not-null="true" />
</key>
<one-to-many class="com.icdb.data.Recipeinstruction" />
</set>
</class>
</hibernate-mapping>
friendship table:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 21:48:14 27/03/2012 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.icdb.data.Friendshiptable" table="friendshiptable" catalog="yoavDB">
<composite-id name="id" class="com.icdb.data.FriendshiptableId">
<key-property name="userAId" type="int">
<column name="userA_Id" />
</key-property>
<key-property name="userBId" type="int">
<column name="userB_Id" />
</key-property>
</composite-id>
<many-to-one name="userByUserAId" class="com.icdb.data.User" update="false" insert="false" fetch="select">
<column name="userA_Id" not-null="true" />
</many-to-one>
<many-to-one name="userByUserBId" class="com.icdb.data.User" update="false" insert="false" fetch="select">
<column name="userB_Id" not-null="true" />
</many-to-one>
<property name="status" type="short">
<column name="status" not-null="true" />
</property>
<property name="statusLastChangedDate" type="date">
<column name="statusLastChangedDate" length="10" not-null="true" />
</property>
</class>
</hibernate-mapping>
LastVisit:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 21:48:14 27/03/2012 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.icdb.data.Userlastvisit" table="userlastvisit" catalog="yoavDB">
<composite-id name="id" class="com.icdb.data.UserlastvisitId">
<key-property name="guestUserId" type="int">
<column name="guestUserId" />
</key-property>
<key-property name="visitedUserId" type="int">
<column name="visitedUserId" />
</key-property>
</composite-id>
<many-to-one name="userByVisitedUserId" class="com.icdb.data.User" update="false" insert="false" fetch="select">
<column name="visitedUserId" not-null="true" />
</many-to-one>
<many-to-one name="userByGuestUserId" class="com.icdb.data.User" update="false" insert="false" fetch="select">
<column name="guestUserId" not-null="true" />
</many-to-one>
<many-to-one name="recipe" class="com.icdb.data.Recipe" fetch="select">
<column name="lastViewedRecipeId" />
</many-to-one>
<property name="lastVisitTimeStamp" type="timestamp">
<column name="lastVisitTimeStamp" length="19" not-null="true" />
</property>
</class>
</hibernate-mapping>
Java code to fetch userInfo:
public String[] getUserInfo( int visitingUserId,
int visitedUserId )
{
Session session = ICDBHibernateUtil.getSessionFactory().getCurrentSession();
try
{
session.beginTransaction();
User user = (User) session.get(User.class, visitedUserId);
ArrayList<String> ret = new ArrayList<String>();
// Username
ret.add( user.getFirstname() + " " + user.getLastname() );
// Few words
ret.add( user.getFewWords() );
// Num of recipes
ret.add( Integer.toString( user.getNumOfRecipes() ) );
// Calculated Rank
ret.add( Float.toString( user.getRate() ) );
// Pic url
ret.add( user.getPicUrl() );
FriendshiptableId id = new FriendshiptableId( visitingUserId, visitedUserId );
Friendshiptable ft = (Friendshiptable)session.get( Friendshiptable.class, id );
if( ft == null )
{
id = new FriendshiptableId( visitedUserId, visitingUserId );
ft = (Friendshiptable)session.get( Friendshiptable.class, id );
if( ft == null )
{
ret.add( "none" );
}
else
{
FriendshipRequestStatusEnum status = FriendshipRequestStatusEnum.values()[ ft.getStatus() ];
switch( status )
{
case PENDING:
ret.add( "pending" );
break;
case ACCEPTED:
ret.add( "accepted" );
break;
case DECLINED:
ret.add( "declined" );
break;
}
}
}
else
{
FriendshipRequestStatusEnum status = FriendshipRequestStatusEnum.values()[ ft.getStatus() ];
switch( status )
{
case PENDING:
ret.add( "pending" );
break;
case ACCEPTED:
ret.add( "accepted" );
break;
case DECLINED:
ret.add( "declined" );
break;
}
}
if( visitingUserId != -1 )
{
// Has new stuff....
UserlastvisitId ulvId = new UserlastvisitId( visitingUserId, visitedUserId );
Userlastvisit ulv = (Userlastvisit) session.get( Userlastvisit.class, ulvId );
if( ulv == null )
{
// Lets add a new entry
User visitingUser = (User) session.load( User.class, visitingUserId );
User visitedUser = (User) session.load( User.class, visitedUserId );
ulv = new Userlastvisit( ulvId,
visitingUser,
visitedUser,
new Date() );
session.save( ulv );
ret.add( "true" );
}
else
{
List<?> loginResult= session.createQuery("from Recipe r where r.lastupdated >= :lastVisited" )
.setDate( "lastVisited", ulv.getLastVisitTimeStamp() )
.list();
if( loginResult.size() > 0 )
{
ret.add( "true" );
}
else
{
ret.add( "false" );
}
// We need to update the last visit time...
ulv.setLastVisitTimeStamp( new Date() );
session.save( ulv );
}
}
session.getTransaction().commit();
String[] retStr = new String[ret.size()];
ret.toArray( retStr );
return retStr;
}
catch( RuntimeException e )
{
ICDBHibernateUtil.getSessionFactory().getCurrentSession().getTransaction().rollback();
throw e;
}
}
getuserRecipes method:
public String[] getUserRecipesNew( int visitingUserId,
int userId,
int pageNumber )
{
final int PAGE_SIZE = 20;
Session session = ICDBHibernateUtil.getSessionFactory().getCurrentSession();
try
{
session.beginTransaction();
String hql = "from Recipe r where r.user.userid= :userid";
Query query = session.createQuery( hql )
.setInteger( "userid", userId );
query = query.setFirstResult( PAGE_SIZE * (pageNumber - 1) );
query.setMaxResults( PAGE_SIZE );
List<?> recipes = query.list();
ArrayList<String> ret = new ArrayList<String>();
if( recipes.size() == PAGE_SIZE )
{
// Indicates that might be more results
ret.add( "true" );
}
else
{
// No more results
ret.add( "false" );
}
DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
// Format the Recipes into string
for( int i = 0; i < recipes.size(); i++ )
{
UserlikesId userLikeId = new UserlikesId( userId, ((Recipe)recipes.get(i)).getRecipeid() );
Userlikes userLike = (Userlikes) session.get( Userlikes.class, userLikeId );
ret.add( Integer.toString( ((Recipe)recipes.get(i)).getRecipeid() ) );
ret.add( ((Recipe)recipes.get(i)).getName() );
ret.add( ((Recipe)recipes.get(i)).getDescription() );
ret.add( ((Recipe)recipes.get(i)).getUser().getFirstname() + ((Recipe)recipes.get(i)).getUser().getLastname() );
ret.add( Integer.toString( ((Recipe)recipes.get(i)).getRecipedifficulty() ) );
ret.add( Integer.toString( ((Recipe)recipes.get(i)).getServecount() ) );
ret.add( Integer.toString( ((Recipe)recipes.get(i)).getPreparationtime() ) );
ret.add( Integer.toString( ((Recipe)recipes.get(i)).getUser().getUserid() ) );
ret.add( Integer.toString( ((Recipe)recipes.get(i)).getNumOfViews() ) );
ret.add( df.format( ((Recipe)recipes.get(i)).getReleasedate() ) );
ret.add( (((Recipe)recipes.get(i)).getPicUrl() == null) ? "" : ((Recipe)recipes.get(i)).getPicUrl() );
ret.add( Integer.toString( ((Recipe)recipes.get(i)).getCategory() ) );
ret.add( (userLike==null)?"0":(userLike.isIsLike()?"1":"0") );
ret.add( Integer.toString( ((Recipe)recipes.get(i)).getNumOfLikes() ) );
}
session.getTransaction().commit();
String[] retStr = new String[ret.size()];
ret.toArray( retStr );
return retStr;
}
catch( RuntimeException e )
{
ICDBHibernateUtil.getSessionFactory().getCurrentSession().getTransaction().rollback();
throw e;
}
}
Is everything written OK?
How should tune it to better performance?
Start by measuring what takes time. Then try to optimize where needed.
If your pool is too small, and you have more concurrent requests than the pool has connections, there will obviously be delays. The nest probable culprit is the query:
turn SQL logging on and see if all the SQL queries are necessary (no unnecessary eager fetching)
examine the execution plan of these queries in MySQL, and see if no index is missing.
Reading your code quickly, you're doing a manual N + 1 query:
query for recipes
for each recipe, find a Userlikes
You should use a single query to load all the needed data in one single query. Or at the very least, you should do a single query to load all the Userlikes at once, by using a where id in (:setOfUserLikesIds) clause.