Hi,
We hit some database performance problem in one of our test environment. Turning on hibernate sql logging, I noticed there are lot of "update" statements going on even though there is no changes in our POJO. Here is a stripped down version of the problem. Notice between the "before store" and "after store" line, we just reattach the POJO graph and do an saveOrUpdate(). No changes are made to the detached POJO, but when saveOrUpdate() is issued, the whole POJO graph is written to the database (as indicated in the show_sql output), which makes it a very expensive operation when the object graph is huge.
My understanding is hibernate is smart enough to update only those "dirty" objects, but in this case the whole object graph is updated even though there is nothing changed there. Is there a way to "fine tune" this behavior?
Thanks,
--Jiunjiun
P.S. Never mind why our POJO class is named "*JDO", it's due to some legacy reason.
Read the rules before posting!
http://www.hibernate.org/ForumMailingli ... AskForHelp
[b]Hibernate version:[/b]
2.1.7 and 2.1.8
[b]Mapping documents:[/b]
<hibernate-mapping
package="com.sun.hss.services.security.autho.jdo">
<class name="AuthorizationManagerJDO" table="hd_authorization_manager" >
<id name="id" column="object_id" type="long" access="field">
<generator class="sequence">
<param name="sequence">seq_hd_autho_manager_object_id</param>
</generator>
</id>
<property name="name" column="name" type="string" access="field"/>
<map name="myUsers" table="hd_manager_user" cascade="all-delete-orphan" access="field">
<key column="manager_object_id"/>
<index column="user_id" type="string"/>
<many-to-many column="user_object_id" class="HssUser"/>
</map>
<map name="myRoles" table="hd_manager_role" cascade="all-delete-orphan" access="field">
<key column="manager_object_id"/>
<index column="role_name" type="string"/>
<many-to-many column="role_object_id" class="HssRole"/>
</map>
<map name="myActivities" table="hd_manager_activity" cascade="all-delete-orphan" access="field">
<key column="manager_object_id"/>
<index column="activity_name" type="string"/>
<many-to-many column="activity_object_id" class="HssActivity"/>
</map>
</class>
<class name="HssUser" table="hd_user">
<id name="id" column="object_id" type="long" access="field">
<generator class="sequence">
<param name="sequence">seq_hd_user_object_id</param>
</generator>
</id>
<property name="myID" column="user_id" type="string" access="field"/>
<property name="myName" column="user_name" type="string" access="field"/>
<property name="myDefaultRole" column="default_role" type="string" access="field"/>
<map name="myRoles" table="hd_user_role" cascade="save-update" access="field">
<key column="user_object_id"/>
<index column="role_name" type="string"/>
<many-to-many column="role_object_id" class="HssRole"/>
</map>
</class>
<class name="HssRole" table="hd_role">
<id name="id" column="object_id" type="long" access="field">
<generator class="sequence">
<param name="sequence">seq_hd_role_object_id</param>
</generator>
</id>
<property name="myName" column="role_name" type="string" access="field"/>
<property name="myShortDesc" column="short_desc" type="string" access="field"/>
<property name="myLongDesc" column="long_desc" type="string" access="field"/>
<map name="myActivities" table="hd_role_activity" cascade="save-update" access="field">
<key column="role_object_id"/>
<index column="activity_name" type="string"/>
<many-to-many column="activity_object_id" class="HssActivity"/>
</map>
</class>
<class name="HssActivity" table="hd_activity">
<id name="id" column="object_id" type="long" access="field">
<generator class="sequence">
<param name="sequence">seq_hd_activity_object_id</param>
</generator>
</id>
<property name="myName" column="activity_name" type="string" access="field"/>
<property name="myDefaultTask" column="default_task" type="string" access="field"/>
<property name="myShortDesc" column="short_desc" type="string" access="field"/>
<property name="myLongDesc" column="long_desc" type="string" access="field"/>
<map name="myResources" table="hd_activity_resource" cascade="all" access="field">
<key column="activity_object_id"/>
<index column="key" type="string"/>
<element column="value" type="string"/>
</map>
<map name="myActions" table="hd_activity_action" cascade="all" access="field">
<key column="activity_object_id"/>
<index column="key" type="string"/>
<element column="value" type="string"/>
</map>
</class>
</hibernate-mapping>
[b]Code between sessionFactory.openSession() and session.close():[/b]
tx = session.beginTransaction();
HssUser user = new HssUser("12345", "name");
HssRole role = new HssRole("role");
HssActivity activity = new HssActivity("activity");
HssActivity activity1 = new HssActivity("activity1");
user.addHssRole(role);
role.addHssActivity(activity);
role.addHssActivity(activity1);
AuthorizationManagerJDO manager =
new AuthorizationManagerJDO(managerName);
manager.getUsers().put(user.getID(), user);
manager.getRoles().put(role.getName(), role);
manager.getActivities().put(activity.getName(), activity);
manager.getActivities().put(activity1.getName(), activity1);
session.save(manager);
tx.commit();
AuthorizationManagerMBeanSupport support = new
AuthorizationManagerMBeanSupport(managerName);
support.load(); // run a query to load data
detachedManager = support.getDataObject();
System.out.println("before store");
support.store(); // store does a saveOrUpdate()
System.out.println("after store");
// ... others ignored
public Object load(Class cls, Map keyValues)
throws PersistenceOperationException {
Session session = null;
Transaction transaction = null;
Object dataObject = null;
try {
session = getSession();
transaction = session.beginTransaction();
dataObject = queryDataObject(session, cls, keyValues);
transaction.commit();
} catch (HibernateException exception) {
try {
if (transaction != null) { transaction.rollback(); }
} catch (HibernateException e) {
// ignore nested exception
}
PersistenceOperationException newException =
new PersistenceOperationException(exception.getMessage(),exception);
throw newException;
} finally {
try {
if (session != null) { session.close(); }
} catch (HibernateException e) {
// ignore exception
}
}
return dataObject;
}
public Object store(Object object, Class cls, Map keyValues)
throws PersistenceOperationException {
Session session = null;
Transaction transaction = null;
Object[] keys = getKeyObjects(keyValues);
Object[] values = getValueObjects(keyValues);
String deleteQueryString = getQueryString(cls, keys, values);
Type[] types = getQueryObjectTypes(values);
try {
session = getSession();
transaction = session.beginTransaction();
if (object == null) {
session.delete(deleteQueryString, values, types);
} else {
if (isTransient(session, object)) {
session.delete(deleteQueryString, values, types);
}
session.saveOrUpdate(object);
}
transaction.commit();
} catch (Exception exception) {
try {
if (transaction != null) { transaction.rollback(); }
} catch (HibernateException e) {
// ignore nested exception
}
PersistenceOperationException newException =
new PersistenceOperationException(exception.getMessage(),exception);
throw newException;
} finally {
try {
if (session != null) { session.close(); }
} catch (HibernateException e) {
// ignore exception
}
}
return object;
}
[b]Full stack trace of any exception that occurs:[/b]
[b]Name and version of the database you are using:[/b]
postgres 7.2.x
[b]The generated SQL (show_sql=true):[/b]
Hibernate: select nextval ('seq_hd_autho_manager_object_id')
Hibernate: select nextval ('seq_hd_user_object_id')
Hibernate: select nextval ('seq_hd_role_object_id')
Hibernate: select nextval ('seq_hd_activity_object_id')
Hibernate: select nextval ('seq_hd_activity_object_id')
Hibernate: insert into hd_authorization_manager (name, object_id) values (?, ?)
Hibernate: insert into hd_user (user_id, user_name, default_role, object_id) values (?, ?, ?, ?)
Hibernate: insert into hd_role (role_name, short_desc, long_desc, object_id) values (?, ?, ?, ?)
Hibernate: insert into hd_activity (activity_name, default_task, short_desc, long_desc, object_id) values (?, ?, ?, ?, ?)
Hibernate: insert into hd_activity (activity_name, default_task, short_desc, long_desc, object_id) values (?, ?, ?, ?, ?)
Hibernate: insert into hd_manager_user (manager_object_id, user_id, user_object_id) values (?, ?, ?)
Hibernate: insert into hd_manager_role (manager_object_id, role_name, role_object_id) values (?, ?, ?)
Hibernate: insert into hd_manager_activity (manager_object_id, activity_name, activity_object_id) values (?, ?, ?)
Hibernate: insert into hd_manager_activity (manager_object_id, activity_name, activity_object_id) values (?, ?, ?)
Hibernate: insert into hd_user_role (user_object_id, role_name, role_object_id) values (?, ?, ?)
Hibernate: insert into hd_role_activity (role_object_id, activity_name, activity_object_id) values (?, ?, ?)
Hibernate: insert into hd_role_activity (role_object_id, activity_name, activity_object_id) values (?, ?, ?)
Hibernate: select this.object_id as object_id0_, this.name as name0_ from hd_authorization_manager this where (this.name=?)
Hibernate: select myactiviti0_.manager_object_id as manager_1___, myactiviti0_.activity_object_id as activity2___, myactiviti0_.activity_name as activity3___, hssactivit1_.object_id as object_id0_, hssactivit1_.activity_name as activity2_0_, hssactivit1_.default_task as default_3_0_, hssactivit1_.short_desc as short_desc0_, hssactivit1_.long_desc as long_desc0_ from hd_manager_activity myactiviti0_ inner join hd_activity hssactivit1_ on myactiviti0_.activity_object_id=hssactivit1_.object_id where myactiviti0_.manager_object_id=?
Hibernate: select myactions0_.activity_object_id as activity1___, myactions0_.value as value__, myactions0_.key as key__ from hd_activity_action myactions0_ where myactions0_.activity_object_id=?
Hibernate: select myresource0_.activity_object_id as activity1___, myresource0_.value as value__, myresource0_.key as key__ from hd_activity_resource myresource0_ where myresource0_.activity_object_id=?
Hibernate: select myactions0_.activity_object_id as activity1___, myactions0_.value as value__, myactions0_.key as key__ from hd_activity_action myactions0_ where myactions0_.activity_object_id=?
Hibernate: select myresource0_.activity_object_id as activity1___, myresource0_.value as value__, myresource0_.key as key__ from hd_activity_resource myresource0_ where myresource0_.activity_object_id=?
Hibernate: select myroles0_.manager_object_id as manager_1___, myroles0_.role_object_id as role_obj2___, myroles0_.role_name as role_name__, hssrole1_.object_id as object_id0_, hssrole1_.role_name as role_name0_, hssrole1_.short_desc as short_desc0_, hssrole1_.long_desc as long_desc0_ from hd_manager_role myroles0_ inner join hd_role hssrole1_ on myroles0_.role_object_id=hssrole1_.object_id where myroles0_.manager_object_id=?
Hibernate: select myactiviti0_.role_object_id as role_obj1___, myactiviti0_.activity_object_id as activity2___, myactiviti0_.activity_name as activity3___, hssactivit1_.object_id as object_id0_, hssactivit1_.activity_name as activity2_0_, hssactivit1_.default_task as default_3_0_, hssactivit1_.short_desc as short_desc0_, hssactivit1_.long_desc as long_desc0_ from hd_role_activity myactiviti0_ inner join hd_activity hssactivit1_ on myactiviti0_.activity_object_id=hssactivit1_.object_id where myactiviti0_.role_object_id=?
Hibernate: select myactions0_.activity_object_id as activity1___, myactions0_.value as value__, myactions0_.key as key__ from hd_activity_action myactions0_ where myactions0_.activity_object_id=?
Hibernate: select myresource0_.activity_object_id as activity1___, myresource0_.value as value__, myresource0_.key as key__ from hd_activity_resource myresource0_ where myresource0_.activity_object_id=?
Hibernate: select myactions0_.activity_object_id as activity1___, myactions0_.value as value__, myactions0_.key as key__ from hd_activity_action myactions0_ where myactions0_.activity_object_id=?
Hibernate: select myresource0_.activity_object_id as activity1___, myresource0_.value as value__, myresource0_.key as key__ from hd_activity_resource myresource0_ where myresource0_.activity_object_id=?
Hibernate: select myroles0_.manager_object_id as manager_1___, myroles0_.role_object_id as role_obj2___, myroles0_.role_name as role_name__, hssrole1_.object_id as object_id0_, hssrole1_.role_name as role_name0_, hssrole1_.short_desc as short_desc0_, hssrole1_.long_desc as long_desc0_ from hd_manager_role myroles0_ inner join hd_role hssrole1_ on myroles0_.role_object_id=hssrole1_.object_id where myroles0_.manager_object_id=?
Hibernate: select myactiviti0_.role_object_id as role_obj1___, myactiviti0_.activity_object_id as activity2___, myactiviti0_.activity_name as activity3___, hssactivit1_.object_id as object_id0_, hssactivit1_.activity_name as activity2_0_, hssactivit1_.default_task as default_3_0_, hssactivit1_.short_desc as short_desc0_, hssactivit1_.long_desc as long_desc0_ from hd_role_activity myactiviti0_ inner join hd_activity hssactivit1_ on myactiviti0_.activity_object_id=hssactivit1_.object_id where myactiviti0_.role_object_id=?
Hibernate: select myusers0_.manager_object_id as manager_1___, myusers0_.user_object_id as user_obj2___, myusers0_.user_id as user_id__, hssuser1_.object_id as object_id0_, hssuser1_.user_id as user_id0_, hssuser1_.user_name as user_name0_, hssuser1_.default_role as default_4_0_ from hd_manager_user myusers0_ inner join hd_user hssuser1_ on myusers0_.user_object_id=hssuser1_.object_id where myusers0_.manager_object_id=?
Hibernate: select myroles0_.user_object_id as user_obj1___, myroles0_.role_object_id as role_obj2___, myroles0_.role_name as role_name__, hssrole1_.object_id as object_id0_, hssrole1_.role_name as role_name0_, hssrole1_.short_desc as short_desc0_, hssrole1_.long_desc as long_desc0_ from hd_user_role myroles0_ inner join hd_role hssrole1_ on myroles0_.role_object_id=hssrole1_.object_id where myroles0_.user_object_id=?
before store
Hibernate: update hd_authorization_manager set name=? where object_id=?
Hibernate: update hd_user set user_id=?, user_name=?, default_role=? where object_id=?
Hibernate: update hd_role set role_name=?, short_desc=?, long_desc=? where object_id=?
Hibernate: update hd_activity set activity_name=?, default_task=?, short_desc=?, long_desc=? where object_id=?
Hibernate: update hd_activity set activity_name=?, default_task=?, short_desc=?, long_desc=? where object_id=?
after store
[b]Debug level Hibernate log excerpt:[/b]