Hibernate Loader slowing Hibernate SqlQuery - java

I have a poor time performance in a SqlQuery under Hibernate 3.6.9 Final with a DB2 database. The sql is made quickly from the SQL Client (Squirrel):
Query 1 of 1, Rows read: 175, Elapsed time (seconds) - Total: 0.527, SQL query: 0.233, Reading results: 0.29
I'm using a ResultTransformer of my own, but it works fine and quickly (I have measured times).
I have been looking the times all around and I found that all the time (about 12 seconds!!!) is lost when the org.hibernate.loader.Loader is making some calls to its methods:
11:21:17,026 DEBUG 127.0.0.1 - MYAPPWEB/api/requests/search - org.hibernate.jdbc.AbstractBatcher[426] - about to open ResultSet (open ResultSets: 0, globally: 0)
11:21:17,205 DEBUG 127.0.0.1 - MYAPPWEB/api/requests/search - org.hibernate.loader.Loader[1322] - result row:
11:21:17,272 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.loader.Loader[1322] - result row:
...175 rows all the same...
11:21:27,978 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.loader.Loader[1322] - result row:
11:21:28,037 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.loader.Loader[1322] - result row:
11:21:28,096 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.jdbc.AbstractBatcher[433] - about to close ResultSet (open ResultSets: 1, globally: 1)
11:21:28,097 DEBUG 127.0.0.1 - /MYAPPWEB/api/requests/search - org.hibernate.jdbc.AbstractBatcher[418] - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
As you can see here at the logs on the left, about 11 seconds are spent. I googled on this Hibernate Class and found the source code here: http://goo.gl/6oAXLT and came to the conclussion that the getRow() method from the Loader is making 1 query per row (total: 175 times) for cheking the ids and so on, but I don't know how to disable this behaviour or which is the configuration I should modify for avoiding this delay.
My mappings are:
Main object (Request):
<?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">
<hibernate-mapping>
<class name="com.enterprise.myappweb.model.requests.request.Request"
table="REQUEST" schema="${db2.app.schema}">
<id name="id" type="java.lang.Long" access="field">
<column name="REQUEST_ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" not-null="true" />
</property>
<property name="description" type="java.lang.String">
<column name="DESCRIPTION" not-null="true" />
</property>
<property name="improvement" type="java.lang.String">
<column name="BENEFIT" not-null="true" />
</property>
<property name="startScheduledDate" type="java.util.Date">
<column name="START_SCHEDULED_DATE" not-null="false" />
</property>
<property name="createTimestamp" type="java.sql.Timestamp">
<column name="CREATE_DATE" not-null="true" />
</property>
<property name="createUser" type="java.lang.String">
<column name="CREATE_USER" not-null="true" />
</property>
</class>
<!-- I omit the named SQL queries here -->
</hibernate-mapping>
Lac:
<?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">
<hibernate-mapping>
<class name="com.enterprise.myappweb.model.requests.lac.Lac"
table="REQUEST_ENTERPRISE_AREA" schema="${db2.app.schema}">
<composite-id name="id"
class="com.enterprise.myappweb.model.requests.lac.LacId">
<key-property name="requestId" type="java.lang.Long">
<column name="REQUEST_ID" not-null="true" />
</key-property>
<key-property name="lacId" type="java.lang.Integer">
<column name="ENTERPRISE_AREA_ID" not-null="true" />
</key-property>
</composite-id>
<property name="order" type="java.lang.Integer">
<column name="ORDER" not-null="true" />
</property>
<property name="startScheduledDate" type="java.util.Date">
<column name="START_SCHEDULED_DATE" not-null="false" />
</property>
<property name="finalScheduledDate" type="java.util.Date">
<column name="END_SCHEDULED_DATE" not-null="false" />
</property>
</class>
<!-- I omit the named SQL queries here -->
</hibernate-mapping>
PriorityType:
<?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">
<hibernate-mapping>
<class name="com.enterprise.myappweb.model.requests.type.PriorityType"
table="PRIORITY_TYPE_REQUEST" schema="${db2.app.schema}">
<id name="id" type="java.lang.Short" access="field">
<column name="PRIORITY_TYPE_REQUEST_ID" />
<generator class="native" />
</id>
<property name="description" type="java.lang.String">
<column name="DESCRIPTION" not-null="true" />
</property>
</class>
<!-- I omit the named SQL queries here -->
</hibernate-mapping>
Status:
<?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">
<hibernate-mapping>
<class name="com.enterprise.myappweb.model.requests.type.Status"
table="REQUEST_STATUS" schema="${db2.app.schema}">
<id name="id" type="java.lang.Short" access="field">
<column name="REQUEST_STATUS_ID" />
<generator class="native" />
</id>
<property name="description" type="java.lang.String">
<column name="DESCRIPTION" not-null="true" />
</property>
</class>
<!-- I omit the named SQL queries here -->
</hibernate-mapping>
RequestType:
<?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">
<hibernate-mapping>
<class name="com.enterprise.myappweb.model.requests.type.RequestType"
table="REQUEST_TYPE_REQUEST" schema="${db2.app.schema}">
<id name="id" type="java.lang.Short" access="field">
<column name="REQUEST_TYPE_REQUEST_ID" />
<generator class="native" />
</id>
<property name="description" type="java.lang.String">
<column name="DESCRIPTION" not-null="true" />
</property>
</class>
<!-- I omit the named SQL queries here -->
</hibernate-mapping>
Java code:
#Repository("requestDao")
public class RequestDaoHibernate extends AbstractReadWriteDao<Request, Long> implements RequestDao {
#Override
public List<Request> findRequests(final RequestSearchDto requestSearchDto, final Boolean isWarehouseUser) {
queryString = "SELECT .... FROM ...."; // Long string
List<Request> result = this.listSQLQuery(queryString.toString(), new SQLQueryCallback() {
#Override
public void doWithQuery(final SQLQuery query) {
// Recuperamos idiomas (del usuario y por defecto) a través de spring
String idiom = LocaleContextHolder.getLocale().getLanguage().toUpperCase();
query.setParameter("isoCodeLanguageId", 3);
query.setParameter("defaultLanguageId", 1);
for(Entry<String, Object> e : dictionary.entrySet()) {
if(e.getKey().endsWith("List")) {
query.setParameterList(e.getKey(), (Collection)e.getValue());
} else {
query.setParameter(e.getKey(), e.getValue());
}
}
RequestSearchRT rt = new RequestSearchRT();
query.setResultTransformer(rt);
}});
return result;
}
}
SuppressWarnings({"unchecked"})
public <S> List<S> listSQLQuery(final String sqlQuery,
final SQLQueryCallback callback) {
if (LOG.isDebugEnabled()) {
LOG.debug("Listing elements with SQL query: {}", sqlQuery);
}
return (List<S>) getHibernateTemplate().execute(new HibernateCallback() {
#Override
public List<S> doInHibernate(final Session session) throws SQLException {
SQLQuery query = session.createSQLQuery(sqlQuery);
callback.doWithQuery(query);
return query.list();
}
});
}
}
I will update the post with configuration settings as people ask me, because I think all the config is in several files and are big.
Thanks in advance.

Related

Hibernate xml set mapping problems

I just learn Hibernate, and have some problems with xml mapping.Error code:
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute statement
Part of database which i want to map looks like this
part of db
In java application i have two entity class, for each of this tables. I donot insert getters setter and constructor here for better readability.
public class OccupiedBedsEntity {
private int id;
private Timestamp since;
private Timestamp to;
private int id_room;
}
public class RoomEntity {
private int id;
private int roomNumber;
private Integer numberOfBeds;
private int id_department;
private int idResponsibleDoctor;
private Set beds;
}
Xml mapping looks like this.
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-cascade="all">
<class name="entity.RoomEntity" table="room" schema="" catalog="medicine">
<id name="id">
<column name="id" sql-type="int unsigned" not-null="true"/>
<generator class="native"/>
</id>
<property name="roomNumber">
<column name="room_number" sql-type="int unsigned" not-null="true"/>
</property>
<property name="numberOfBeds">
<column name="number_of_beds" sql-type="int unsigned"/>
</property>
<property name="idResponsibleDoctor">
<column name="id_responsible_doctor" sql-type="int unsigned" not-null="true"/>
</property>
<property name="id_department">
<column name="id_department" sql-type="int unsigned" not-null="true"/>
</property>
<set name="beds">
<key column="id_room"></key>
<one-to-many class="entity.OccupiedBedsEntity"/>
</set>
</class>
</hibernate-mapping>
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" enter code here"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping default-cascade="all">
<class name="entity.OccupiedBedsEntity" table="occupied_beds" schema="medicine" catalog="medicine">
<id name="id">
<column name="id" sql-type="int unsigned" not-null="true"/>
<generator class="native"/>
</id>
<property name="since">
<column name="since_" sql-type="datetime" not-null="true"/>
</property>
<property name="to">
<column name="to_" sql-type="datetime" not-null="true"/>
</property>
<property name="id_room">
<column name="id_room" sql-type="int unsigned" not-null="true"></column>
</property>
</class>
</hibernate-mapping>
Maybe i have to change something not in xml, but in java classes?
Error was in this line in occupiesBebsEntity xml mapper.
<class name="entity.OccupiedBedsEntity" table="occupied_beds" schema="medicine" catalog="medicine">
Code should looks like this.
<class name="entity.OccupiedBedsEntity" table="occupied_beds" schema="" catalog="medicine">

Repeated column in mapping for entity, oneToMany relationship

I am trying to do a one-to-many relationship between two tables. I have a table called users that has many user_history entries. I defined these tables in mysql and I generated the entities with intellij hibrernate support. The problem is that when i want to insert something in the databse I am receiving the following error Repeated column in mapping for entity: com.UserHistoryEntity
User:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.UsersEntity" table="users" schema="" catalog="protein_tracker">
<id name="id">
<column name="id" sql-type="int" not-null="true"/>
</id>
<property name="name">
<column name="name" sql-type="varchar" length="45" not-null="true"/>
</property>
<property name="total">
<column name="total" sql-type="int" not-null="true"/>
</property>
<property name="goal">
<column name="goal" sql-type="int" not-null="true"/>
</property>
<set name="userHistoriesById" inverse="true">
<key>
<column name="id_user" not-null="true"/>
</key>
<one-to-many not-found="ignore" class="com.UserHistoryEntity"/>
</set>
</class>
</hibernate-mapping>
UserHistory:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.UserHistoryEntity" table="user_history" schema="" catalog="protein_tracker">
<id name="id">
<column name="id" sql-type="int" not-null="true"/>
</id>
<property name="entryDate">
<column name="entry_date" sql-type="datetime" not-null="true"/>
</property>
<property name="entry">
<column name="entry" sql-type="varchar" length="45" not-null="true"/>
</property>
<property name="idUser">
<column name="id_user" sql-type="int" not-null="true"/>
</property>
<many-to-one name="usersByIdUser" class="com.UsersEntity">
<column name="id_user" not-null="true"/>
</many-to-one>
</class>
</hibernate-mapping>
How can I fix this issue?
Mark your Many-To-One mapping for usersByIdUser to insertable = false and updatable = false. This allows the relationship to only be managed by a single property, idUser that you have mapped.

How do I cascade saves through a many to many relationship with hibernate?

I have a many to many (with a join table) relationship in my database that I need to model in hibernate.
I have POJO classes for all three tables in the database as the join table contains more than just the mapping information.
My problem occurs on save() of class A where class A is told to cascade to class AB (the join table) which is told to cascade to class B, but when it gets to the point where it is saving AB the foriegn key reference to table A is null.
At the end of the day I want to be able to call save() on an instance of the TableA class and have it save all three tables.
Table Diagram
TABLE A Mapping
<?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 Aug 27, 2012 2:16:37 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.example.dbtables.TableA" table="Table A">
<id name="id" type="int">
<column name="id" />
<generator class="sequence">
<param name="sequence">table_a_seq</param>
</generator>
</id>
<natural-id>
<property name="data1" type="int">
<column name="DATA1" not-null="true" />
</property>
<property name="data2" type="string">
<column name="DATA2" length="16" not-null="true" />
</property>
</natural-id>
<set name="tableAB" cascade="save-update" table="TableAB" inverse="true" lazy="true" fetch="select">
<key>
<column name="Table_AB_ID" not-null="true" />
</key>
<one-to-many class="com.example.dbtables.TableAB" />
</set>
</class>
</hibernate-mapping>
TABLE AB Mapping
<?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 Aug 27, 2012 2:16:37 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.example.dbtables.TableAB" table="Table AB">
<id name="id" type="int">
<column name="id" />
<generator class="sequence">
<param name="sequence">table_ab_seq</param>
</generator>
</id>
<natural-id>
<many-to-one name="tableA" class="com.example.dbtables.TableA" fetch="select">
<column name="Table_A_ID" not-null="true" />
</many-to-one>
<many-to-one name="tableB" cascade="save-update" class="com.example.dbtables.TableB" fetch="select">
<column name="Table_B_ID" not-null="true" />
</many-to-one>
<property name="data1" type="int">
<column name="DATA1" not-null="true" />
</property>
<property name="data2" type="int">
<column name="DATA2" not-null="true" />
</property>
</natural-id>
</class>
</hibernate-mapping>
TABLE B Mapping
<?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 Aug 27, 2012 2:16:37 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.examples.dbtables.TableB" table="Table B">
<id name="id" type="int">
<column name="id" />
<generator class="sequence">
<param name="sequence">table_b_seq</param>
</generator>
</id>
<natural-id>
<property name="data1" type="string">
<column name="DATA1" length="16" />
</property>
<property name="data2" type="java.lang.Integer">
<column name="DATA2" />
</property>
</natural-id>
<set name="TableAB" table="Table AB" inverse="true" lazy="true" fetch="select">
<key>
<column name="Table_AB_ID" not-null="true" />
</key>
<one-to-many class="com.example.dbtables.TableAB" />
</set>
</class>
</hibernate-mapping>
Thanks for any help you can give. Let me know if you need clarification or anymore information.
EDIT: My problem was that the references from AB -> to A were not getting correctly populated. This issue has been resolved thanks to everyone who helped.
A a = new A();
B b = new B();
AB ab = new AB();
ab.setA(a);
ab.setB(b);
a.setAB(ab);
b.setAB(ab);
save(a);
This example not working? Did you get some exception?
EDIT
Look into this Hibernate doc Chapter 5. Basic O/R Mapping to chapter 5.1.4.1. Generator
PostgreSQL doesn't support identity generation type.
Use sequence generation instead of identity, or something else
The problem was that the back references between AB -> A were not getting correctly populated in my code. Thanks to Ilya for the help.

Unable to use inheritence in Hibernate

Please have a look at the following
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.att_marks.students.Attendance_Btech">
<id name="id" type="integer" column="id" >
<generator class="increment"/>
</id>
<property name="year">
<column name="Year" />
</property>
<property name="semister">
<column name="Semister"/>
</property>
<property name="section">
<column name="Section"/>
</property>
<property name="period">
<column name="Period"/>
</property>
<property name="subjectCode">
<column name="Subject_Code"/>
</property>
<property name="date">
<column name="Date"/>
</property>
<property name="status">
<column name="Status"/>
</property>
<union-subclass name="com.att_marks.students.Attendance_Btech_ECE" table="attendance_btech_ece">
</union-subclass>
</class>
</hibernate-mapping>
I have tables named attendance_btech_ece, attendance_btech_cse, attendance_btech_it, and so on. All these tables use the same schema as mentioned above for the Attendance_Btech class. I thought this should work but it isn't.
If the Attendance_Btech_ECE is subclass of Attendance_Btech then should work.

Hibernate Loading not loading the whole tree

I am trying to make hibernate load my whole tree with no success.
I have a schema like this
A Category can have many attribute and an attribute can have many options
Category
--->Attribute1
--->AttributeOption1
--->AttributeOption3
--->Attribute2
--->AttributeOption1
--->AttributeOption1
but when I am using hibernate, it is not loading the whole tree:
my mapping file are:
Attribute Mapping FIle:
<?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 Dec 16, 2010 5:25:09 AM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
<class name="com.BiddingSystem.Models.Attribute" table="ATTRIBUTE">
<id name="AttributeId" type="long">
<column name="ATTRIBUTEID" />
<generator class="native" />
</id>
<property name="AttributeName" type="java.lang.String">
<column name="ATTRIBUTENAME" />
</property>
<set name="Options" table="ATTRIBUTEOPTION" inverse="false" cascade="all" lazy="true">
<key>
<column name="ATTRIBUTEID" />
</key>
<one-to-many class="com.BiddingSystem.Models.AttributeOption" />
</set>
</class>
</hibernate-mapping>
Attribute Option Mapping File:
<?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 Dec 16, 2010 5:25:09 AM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
<class name="com.BiddingSystem.Models.AttributeOption" table="ATTRIBUTEOPTION">
<id name="AttributeOptionId" type="long">
<column name="ATTRIBUTEOPTIONID" />
<generator class="native" />
</id>
<property name="Option" type="java.lang.String">
<column name="OPTION" />
</property>
<property name="SQLValue" type="java.lang.String">
<column name="SQLVALUE" />
</property>
</class>
</hibernate-mapping>
Category Mapping File:
<?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 Dec 16, 2010 8:37:02 AM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
<class name="com.BiddingSystem.Models.Category" table="CATEGORY">
<id name="CategoryId" type="long">
<column name="CATEGORYID" />
<generator class="native" />
</id>
<property name="CategoryName" type="java.lang.String">
<column name="CATEGORYNAME" />
</property>
<many-to-one name="ParentCategory" class="com.BiddingSystem.Models.Category">
<column name="PARENT_CATEGORY_ID" />
</many-to-one>
<set name="SubCategory" lazy="true" cascade="all-delete-orphan" inverse="true">
<key>
<column name="PARENT_CATEGORY_ID" />
</key>
<one-to-many class="com.BiddingSystem.Models.Category" />
</set>
<set name="AllAttributes" table="ATTRIBUTE" inverse="false" lazy="true" cascade="all">
<key>
<column name="CATEGORYID" />
</key>
<one-to-many class="com.BiddingSystem.Models.Attribute" />
</set>
</class>
</hibernate-mapping>
The function that loads the parent category are:
public List <Category> getCategory(long CategoryId)
{
Session session = gileadHibernateUtil.getSessionFactory().openSession();
List <Category> AllCategory= new LinkedList<Category> ();
String SQL="from Category where parent_category_id is NULL";
Query query = session.createQuery(SQL);
return query.list();
}
Make all your associations lazy=false; by default the lazy = true
I believe there is an other mistake:
String SQL="from Category where parent_category_id is NULL";
Query query = session.createQuery(SQL);
org.hibernate.Session.createQuery(String queryString) requires a HQL Query String, but not a SQL query! And from Category where parent_category_id is NULL seems to be a SQL query, because parent_category_id is a column name but not a property / field name.

Categories

Resources