-
1. Re: JBoss portal performance: (Portal)templatePortal.copy(da
vivek_saini07 Aug 18, 2009 1:43 AM (in response to vineet_tripathi)This is a performance issue with JBP. This particular method gets called when dashboard gets created first time for user.
If we have 20K users for JBP, 20k select queries gets fired every time a new dashboard gets created. So it appears complete show stopper. Even second level caching does not help in this scenario.
Following is the way to recreate the scenario.
1) check out code from SVN (JBoss_Portal_Branch_2_7).
2) put the SOP's around this method in CustomizationManagerService.if (dashboardPortal == null) { Portal templatePortal = (Portal)portalObjectContainer.getObject(TEMPLATE_ID); // Copy the template portal System.out.println("templatePortal.copy(dashboardContext, userId, false); =======>start"); dashboardPortal = (Portal)templatePortal.copy(dashboardContext, userId, false); System.out.println("templatePortal.copy(dashboardContext, userId, false); =======>end"); copy(templatePortal, dashboardContext.getChild(userId)); }
3) compile & deploy and run it. Create some 8-10 users from admin-portlet.
4) restart the server then login with new users and access the dashboard.
you will notice so many select queries within those SOP's. N0umber of these select statements are equal to number of dashboard already created in JBP. Following is the output with 3 users.
templatePortal.copy(dashboardContext, userId, false); =======>start 10:32:03,547 INFO [STDOUT] Hibernate: select displaynam0_.INSTANCE_PK as INSTANCE1_0_, displaynam0_.TEXT as TEXT0_, displaynam0_.LOCALE as LOCALE0_ from JBP_PORTAL_OBJECT_DNAMES displaynam0_ where displaynam0_.INSTANCE_PK=? 10:32:03,548 INFO [STDOUT] Hibernate: select children0_.PARENT_KEY as PARENT4_1_, children0_.PK as PK1_, children0_.NAME as NAME1_, children0_.PK as PK9_0_, children0_."PATH" as PATH2_9_0_, children0_.NAME as NAME9_0_, children0_.PARENT_KEY as PARENT4_9_0_ from JBP_OBJECT_NODE children0_ where children0_.PARENT_KEY=? 10:32:03,550 INFO [STDOUT] Hibernate: select portalobje0_.PK as PK10_0_, portalobje0_.LISTENER as LISTENER10_0_, portalobje0_4_.INSTANCE_REF as INSTANCE2_18_0_, case when portalobje0_1_.PK is not null then 1 when portalobje0_2_.PK is not null then 2 when portalobje0_3_.PK is not null then 3 when portalobje0_4_.PK is not null then 4 when portalobje0_.PK is not null then 0 end as clazz_0_, declaredpr1_.OBJECT_KEY as OBJECT1_2_, declaredpr1_.jbp_VALUE as jbp2_2_, declaredpr1_.NAME as NAME2_, modes2_.PK as PK3_, modes2_.name as name3_, windowstat3_.PK as PK4_, windowstat3_.name as name4_ from JBP_PORTAL_OBJECT portalobje0_ left outer join JBP_CONTEXT portalobje0_1_ on portalobje0_.PK=portalobje0_1_.PK left outer join JBP_PORTAL portalobje0_2_ on portalobje0_.PK=portalobje0_2_.PK left outer join JBP_PAGE portalobje0_3_ on portalobje0_.PK=portalobje0_3_.PK left outer join JBP_WINDOW portalobje0_4_ on portalobje0_.PK=portalobje0_4_.PK left outer join JBP_PORTAL_OBJECT_PROPS declaredpr1_ on portalobje0_.PK=declaredpr1_.OBJECT_KEY left outer join JBP_PORTAL_MODE modes2_ on portalobje0_.PK=modes2_.PK left outer join JBP_PORTAL_WINDOW_STATE windowstat3_ on portalobje0_.PK=windowstat3_.PK where portalobje0_.PK=? 10:32:03,557 INFO [STDOUT] Hibernate: select portalobje0_.PK as PK10_0_, portalobje0_.LISTENER as LISTENER10_0_, portalobje0_4_.INSTANCE_REF as INSTANCE2_18_0_, case when portalobje0_1_.PK is not null then 1 when portalobje0_2_.PK is not null then 2 when portalobje0_3_.PK is not null then 3 when portalobje0_4_.PK is not null then 4 when portalobje0_.PK is not null then 0 end as clazz_0_, declaredpr1_.OBJECT_KEY as OBJECT1_2_, declaredpr1_.jbp_VALUE as jbp2_2_, declaredpr1_.NAME as NAME2_, modes2_.PK as PK3_, modes2_.name as name3_, windowstat3_.PK as PK4_, windowstat3_.name as name4_ from JBP_PORTAL_OBJECT portalobje0_ left outer join JBP_CONTEXT portalobje0_1_ on portalobje0_.PK=portalobje0_1_.PK left outer join JBP_PORTAL portalobje0_2_ on portalobje0_.PK=portalobje0_2_.PK left outer join JBP_PAGE portalobje0_3_ on portalobje0_.PK=portalobje0_3_.PK left outer join JBP_WINDOW portalobje0_4_ on portalobje0_.PK=portalobje0_4_.PK left outer join JBP_PORTAL_OBJECT_PROPS declaredpr1_ on portalobje0_.PK=declaredpr1_.OBJECT_KEY left outer join JBP_PORTAL_MODE modes2_ on portalobje0_.PK=modes2_.PK left outer join JBP_PORTAL_WINDOW_STATE windowstat3_ on portalobje0_.PK=windowstat3_.PK where portalobje0_.PK=? 10:32:03,564 INFO [STDOUT] Hibernate: select portalobje0_.PK as PK10_0_, portalobje0_.LISTENER as LISTENER10_0_, portalobje0_4_.INSTANCE_REF as INSTANCE2_18_0_, case when portalobje0_1_.PK is not null then 1 when portalobje0_2_.PK is not null then 2 when portalobje0_3_.PK is not null then 3 when portalobje0_4_.PK is not null then 4 when portalobje0_.PK is not null then 0 end as clazz_0_, declaredpr1_.OBJECT_KEY as OBJECT1_2_, declaredpr1_.jbp_VALUE as jbp2_2_, declaredpr1_.NAME as NAME2_, modes2_.PK as PK3_, modes2_.name as name3_, windowstat3_.PK as PK4_, windowstat3_.name as name4_ from JBP_PORTAL_OBJECT portalobje0_ left outer join JBP_CONTEXT portalobje0_1_ on portalobje0_.PK=portalobje0_1_.PK left outer join JBP_PORTAL portalobje0_2_ on portalobje0_.PK=portalobje0_2_.PK left outer join JBP_PAGE portalobje0_3_ on portalobje0_.PK=portalobje0_3_.PK left outer join JBP_WINDOW portalobje0_4_ on portalobje0_.PK=portalobje0_4_.PK left outer join JBP_PORTAL_OBJECT_PROPS declaredpr1_ on portalobje0_.PK=declaredpr1_.OBJECT_KEY left outer join JBP_PORTAL_MODE modes2_ on portalobje0_.PK=modes2_.PK left outer join JBP_PORTAL_WINDOW_STATE windowstat3_ on portalobje0_.PK=windowstat3_.PK where portalobje0_.PK=? 10:32:03,571 INFO [STDOUT] Hibernate: insert into JBP_OBJECT_NODE (PK, "PATH", NAME, PARENT_KEY) values (null, ?, ?, ?) 10:32:03,572 INFO [STDOUT] Hibernate: call identity() 10:32:03,576 INFO [STDOUT] Hibernate: insert into JBP_PORTAL_OBJECT (LISTENER, PK) values (?, ?) 10:32:03,576 INFO [STDOUT] Hibernate: insert into JBP_PORTAL (PK) values (?) 10:32:03,577 INFO [STDOUT] Hibernate: insert into JBP_PORTAL_MODE (PK, name) values (?, ?) 10:32:03,577 INFO [STDOUT] Hibernate: insert into JBP_PORTAL_MODE (PK, name) values (?, ?) 10:32:03,577 INFO [STDOUT] Hibernate: insert into JBP_PORTAL_MODE (PK, name) values (?, ?) 10:32:03,577 INFO [STDOUT] Hibernate: insert into JBP_PORTAL_MODE (PK, name) values (?, ?) 10:32:03,577 INFO [STDOUT] Hibernate: insert into JBP_PORTAL_MODE (PK, name) values (?, ?) 10:32:03,578 INFO [STDOUT] Hibernate: insert into JBP_PORTAL_WINDOW_STATE (PK, name) values (?, ?) 10:32:03,578 INFO [STDOUT] Hibernate: insert into JBP_PORTAL_WINDOW_STATE (PK, name) values (?, ?) 10:32:03,584 INFO [STDOUT] Hibernate: insert into JBP_PORTAL_WINDOW_STATE (PK, name) values (?, ?) 10:32:03,584 INFO [STDOUT] templatePortal.copy(dashboardContext, userId, false); =======>end
So following query gets fired multiple times.select portalobje0_.PK as PK10_0_, portalobje0_.LISTENER as LISTENER10_0_, portalobje0_4_.INSTANCE_REF as INSTANCE2_18_0_, case when portalobje0_1_.PK is not null then 1 when portalobje0_2_.PK is not null then 2 when portalobje0_3_.PK is not null then 3 when portalobje0_4_.PK is not null then 4 when portalobje0_.PK is not null then 0 end as clazz_0_, declaredpr1_.OBJECT_KEY as OBJECT1_2_, declaredpr1_.jbp_VALUE as jbp2_2_, declaredpr1_.NAME as NAME2_, modes2_.PK as PK3_, modes2_.name as name3_, windowstat3_.PK as PK4_, windowstat3_.name as name4_ from JBP_PORTAL_OBJECT portalobje0_ left outer join JBP_CONTEXT portalobje0_1_ on portalobje0_.PK=portalobje0_1_.PK left outer join JBP_PORTAL portalobje0_2_ on portalobje0_.PK=portalobje0_2_.PK left outer join JBP_PAGE portalobje0_3_ on portalobje0_.PK=portalobje0_3_.PK left outer join JBP_WINDOW portalobje0_4_ on portalobje0_.PK=portalobje0_4_.PK left outer join JBP_PORTAL_OBJECT_PROPS declaredpr1_ on portalobje0_.PK=declaredpr1_.OBJECT_KEY left outer join JBP_PORTAL_MODE modes2_ on portalobje0_.PK=modes2_.PK left outer join JBP_PORTAL_WINDOW_STATE windowstat3_ on portalobje0_.PK=windowstat3_.PK where portalobje0_.PK=?
Any idea/help/thought towards resolving it would be greatly appreciated. -
2. Re: JBoss portal performance: (Portal)templatePortal.copy(da
vivek_saini07 Aug 18, 2009 3:54 PM (in response to vineet_tripathi)Request you to please let us know if it is really a bug. If it is, then we would like to open a JIRA and work upon it.
-
3. Re: JBoss portal performance: (Portal)templatePortal.copy(da
vivek_saini07 Aug 26, 2009 1:42 AM (in response to vineet_tripathi)We have found a work around for this.
Problem further drilled down to following calls of ObjectNode domain object(void addChild(String name, PortalObjectImpl childObject) of org.jboss.portal.core.impl.model.portal.ObjectNode).children.containsKey(name)
Here children is a MAP(One-to-Many association) that is being loaded lazily. Because of this lazy loading, initially it is loaded as a proxy and whenever any operation performed on it, entire map gets loaded that in-turn fires those multiple select queries.
Proposed Solution
Solution lies in making this collection lazy="extra" instead of lazy="true" in core/src/resources/portal-core-sar/conf/hibernate/portal/domain.hbm.xml
From:<class name="org.jboss.portal.core.impl.model.portal.ObjectNode" table="JBP_OBJECT_NODE"> ..... <map name="children" inverse="true" cascade="none" fetch="select" lazy="true"> <cache usage="@portal.hibernate.cache.usage@"/> <key column="PARENT_KEY"/> <map-key type="org.jboss.portal.jems.hibernate.MagicString" column="NAME"/> <one-to-many class="org.jboss.portal.core.impl.model.portal.ObjectNode"/> </map>
To:
<map name="children" inverse="true" cascade="none" fetch="select" lazy="extra"> <cache usage="@portal.hibernate.cache.usage@"/> <key column="PARENT_KEY"/> <map-key type="org.jboss.portal.jems.hibernate.MagicString" column="NAME"/> <one-to-many class="org.jboss.portal.core.impl.model.portal.ObjectNode"/> </map>
The advantage gained by making lazy="extra" to lazy="true", according to hibernate docs,HERE https://hibernate.bluemars.net/315.html."...The collection wrapper is now smarter than before. The collection is no longer initialized if you call size(), contains(), or isEmpty()—the database is queried to retrieve the necessary information. If it’s a Map or a List, the operations containsKey() and get() also query the database directly..."
After doing this only one query in being fired instead of plethora of queries.