I can sense your frustration that your question was not answered in the time frame you had hoped.
the answer would be "no" this is neither normal or acceptable. I believe there was some work done to support subclassing across tables, and I will look into that. You could use a "fast" mapping that just brings the name into the object world vs a big complex object. A custom rowreader could probably also do this. there is no way you can put both the person and contact mapped to one table? I know that works nicely and is quick. cheers, Matthew -----Original Message----- From: Ebersole, Steven [mailto:[EMAIL PROTECTED] Sent: Wednesday, March 19, 2003 10:52 AM To: 'OJB Users List' Subject: RE: performance So would over 2 minutes be considered acceptable/normal for OJB then? |-----Original Message----- |From: Ebersole, Steven [mailto:[EMAIL PROTECTED] |Sent: Tuesday, March 18, 2003 10:28 AM |To: 'OJB Users List' |Subject: RE: performance | | |I did I little more troubleshooting (hacking) and found |that, at least in |part, the problem is caused by the Contact's reference to |the Person class |and Company class. If I proxy those references or remove |them, the load |time goes from 2 minutes 5 seconds down to 30 seconds for |the company with |1524 employees. | |The problem with proxying the Person reference is that |there is never a time |when I would need the Contact without their name, which is |kept on the |PERSON table mapping to the Person class. | |Basically the concept I am trying to model here is a |person's relationship |to a company. Ideally, the Contact class would simply be |a sub-class of |Person with the company relation information on that |Contact concrete |subclass. Yet from what I have read OJB does not support |subclassing across |tables, aside from indirectly as I have modeled it. Is |there a better way |to map this relationship using OJB? Or maybe a way to |force OJB to perform |an outer join here since it is a single association going |from the Contact |to the Person? Maybe a custom RowReader impl? | |I also verified (as I think Cristian was trying to imply) |that the queries |themselves are pretty quick, at least through Oracle's sqlplus. | | |Anyway, any help would be great. | | | |-----Original Message----- |From: Malinescu, Cristian [mailto:[EMAIL PROTECTED] |Sent: Tuesday, March 18, 2003 8:43 AM |To: 'OJB Users List' |Subject: RE: performance | | |Hi, surprising how much similarity, we are doing also some CRM |and we used some commercial appsrv( like "t3://myserver:7001" ;-) ) |till we become very piss off because of entity ejb performance |and now we will migrate to tomcat and ojb ( currently |4.1.18/1.0rc1 ) |and our performance test are till now very satisfactory ... |Regards, |Cristian | |-----Original Message----- |From: Ebersole, Steven [mailto:[EMAIL PROTECTED] |Sent: Dienstag, 18. März 2003 15:30 |To: 'OJB Users List' |Subject: RE: performance | | |Thanks for the response. | |First the database schema is completely normalized. And |unfortunately I |cant work with just 15 tables; this is the begining of a |CRM app and phase |one alone has over 300 tables. All PK and FK are also set |up as indexes. |Not that it (should) matter much, but we also use Oracle 8i. | |As for the source code, this is just a simple test class |(code below) and as |such, there is only one PB instance. This is not yet even |incurring the |overhead of the EJB calls. | | |public class TestCompanyMappings |{ | private static final Logger log = Logger.getRootLogger(); | | public TestCompanyMappings() | { | System.setProperty( "OJB.properties", |"properties/OJB.properties" |); | System.setProperty( Context.PROVIDER_URL, |"t3://myserver:7001" ); | System.setProperty( Context.INITIAL_CONTEXT_FACTORY, |"weblogic.jndi.WLInitialContextFactory" ); | } | | public static void main( String[] args ) | { | TestCompanyMappings me = new TestCompanyMappings(); | me.execute(); | } | | private void execute() | { | PersistenceBroker broker = null; | Criteria crit = null; | crit = new Criteria(); | crit.addEqualTo( "id", new Integer(1) ); | Query query = new QueryByCriteria( Company.class, crit ); | | try | { | broker = |PersistenceBrokerFactory.defaultPersistenceBroker(); | log.debug( "Starting query" ); | java.util.Collection extent = |broker.getCollectionByQuery( query |); | log.debug( "Done query; iterating" ); | java.util.Iterator iter = extent.iterator(); | while (iter.hasNext()) | { | display( (Company)iter.next() ); | } | log.debug( "Done iterating" ); | } | catch( Throwable t ) | { | log.error( "Error occurred", t ); | } | finally | { | if (broker != null) | { | try | { | broker.close(); | } | catch( Throwable t ) | {} | } | } | } | private void display( Company company ) | { | System.out.println( |"***********************************************" ); | System.out.println( " ID : " + |company.getId() ); | System.out.println( " Name : " + |company.getName() ); | System.out.println( |"***********************************************" ); | | log.debug( "Forcing load of employees" ); | System.out.println( " First contact last-name : " + |((Contact)company.getEmployees().iterator().next()).getPers |on().getLastName( |) ); | log.debug( "Employees loaded" ); | } |} | | | |-----Original Message----- |From: Malinescu, Cristian [mailto:[EMAIL PROTECTED] |Sent: Tuesday, March 18, 2003 8:18 AM |To: 'OJB Users List' |Subject: RE: performance | | |Hi |My opinion is basically to take a look at your sourcecode first and |don't forget to index your tables. |For me, for my typical situation/project I can tell next details : |My Oracle 8 database schema for test contains ~ 15 tables |with more than |300 total defined columns, minimum indexed, with 1:n and |n:m relations |using indirection tables, and a total of more than 200.000 |entries and a |complete test suite where full schema is parsed takes |under 20 seconds. |Some development advice is to take care to create in your |source code |one PBKey/PersistenceBroker instance and to cache this for |later usage. |Regards, |Cristian | | |-----Original Message----- |From: Ebersole, Steven [mailto:[EMAIL PROTECTED] |Sent: Dienstag, 18. März 2003 15:03 |To: OJB Users List (E-mail) |Subject: performance | | |I am running into a huge performance issue and was hoping |to get some |guidance on where to start looking for a problem. Then |mapping portion |causing the problem deals with employees for a company. I |currently have |this modeled as a bi-directional 1:n mapping (Company has |a collection of |employees and Employee has a reference to its Company). |Both sides of the |association are set to be proxies (collection-proxy and |reference-proxy). | |I then tested by loading 2 companies, one with 175 |employees and another |with 1524 (the results were pretty much the same querying |the Employee |object by its company). Accessing the employee collection |on the first |company took 1.5 secs to load. Accessing the employee |collection on the |second took 2 minutes and 5 secs to load. | |Thats not even close to linear, so I am thinking I must be |doing something |wrong. Any help troubleshooting this would be greatly |appreciated. Below |are the mappings for both classes. I am using the |PersistentFieldMaxPerformanceImpl for the |PersistenceFieldClass and a JNDI |Datasource. | | | | | |<!-- |########################################################### |################# |### |## Company entity type mapping |########################################################### |################# |### |--> | <class-descriptor | |class="com.vignette.it.apps.server.domain.entities.Company" | table="COMPANY" | > | <field-descriptor | name="id" | column="COMP_ID" | jdbc-type="INTEGER" | primarykey="true" | autoincrement="true" | /> | | <field-descriptor | name="parentId" | column="PRNT_COMP_ID" | jdbc-type="INTEGER" | /> | | <field-descriptor | name="pending" | column="PENDING_APPRVL_FLG" | jdbc-type="INTEGER" | |conversion="org.apache.ojb.broker.accesslayer.conversions.B |oolean2IntFieldCo |nversion" | /> | | <field-descriptor | name="name" | column="NAME" | jdbc-type="VARCHAR" | /> | | <field-descriptor | name="aliases" | column="ALIASES" | jdbc-type="VARCHAR" | /> | | <field-descriptor | name="numberOfVignetteSites" | column="NUM_OF_VIGN_SITES" | jdbc-type="INTEGER" | /> | | <field-descriptor | name="annualRevenueAmount" | column="ANNUAL_REV" | jdbc-type="DOUBLE" | /> | | <field-descriptor | name="annualRevenueCurrencyId" | column="ANNUAL_REV_CURR_ID" | jdbc-type="INTEGER" | /> | | <field-descriptor | name="potentialOpportunityAmount" | column="POTNL_OPP" | jdbc-type="DOUBLE" | /> | | <field-descriptor | name="potentialOpportunityCurrencyId" | column="POTNL_OPP_CURR_ID" | jdbc-type="INTEGER" | /> | | <field-descriptor | name="fortuneListId" | column="FORT_LIST_ID" | jdbc-type="INTEGER" | /> | | <field-descriptor | name="geographyId" | column="GEO_ID" | jdbc-type="INTEGER" | /> | | <field-descriptor | name="customerStatusId" | column="CUST_PROD_STAT_ID" | jdbc-type="INTEGER" | /> | | <field-descriptor | name="createdBy" | column="CRTD_BY" | jdbc-type="VARCHAR" | /> | | <field-descriptor | name="createdDate" | column="CRTD_DT" | jdbc-type="TIMESTAMP" | |conversion="org.apache.ojb.broker.accesslayer.conversions.J |avaDate2SqlTimest |ampFieldConversion" | /> | | <field-descriptor | name="modifiedBy" | column="CHGD_BY" | jdbc-type="VARCHAR" | /> | | <field-descriptor | name="modifiedDate" | column="CHGD_DT" | jdbc-type="TIMESTAMP" | |conversion="org.apache.ojb.broker.accesslayer.conversions.J |avaDate2SqlTimest |ampFieldConversion" | /> | | <reference-descriptor | name="parent" | |class-ref="com.vignette.it.apps.server.domain.entities.Company" | proxy="true" | > | <foreignkey field-ref="parentId"/> | </reference-descriptor> | | <reference-descriptor | name="annualRevenueCurrency" | |class-ref="com.vignette.it.apps.server.domain.entities.Currency" | proxy="true" | > | <foreignkey field-ref="annualRevenueCurrencyId"/> | </reference-descriptor> | | <reference-descriptor | name="potentialOpportunityCurrency" | |class-ref="com.vignette.it.apps.server.domain.entities.Currency" | proxy="true" | > | <foreignkey |field-ref="potentialOpportunityCurrencyId"/> | </reference-descriptor> | | <reference-descriptor | name="fortuneList" | |class-ref="com.vignette.it.apps.server.domain.entities.FortuneList" | proxy="true" | > | <foreignkey field-ref="fortuneListId"/> | </reference-descriptor> | | <reference-descriptor | name="geography" | |class-ref="com.vignette.it.apps.server.domain.entities.Geography" | proxy="true" | > | <foreignkey field-ref="geographyId"/> | </reference-descriptor> | | <reference-descriptor | name="customerStatus" | |class-ref="com.vignette.it.apps.server.domain.entities.Cust |omerStatus" | proxy="true" | > | <foreignkey field-ref="customerStatusId"/> | </reference-descriptor> | | <collection-descriptor | name="addresses" | |element-class-ref="com.vignette.it.apps.server.domain.entit |ies.CompanyAddres |s" | orderby="hqAddress" | sort="DESC" | proxy="true" | > | <inverse-foreignkey field-ref="companyId"/> | </collection-descriptor> | | <collection-descriptor | name="phones" | |element-class-ref="com.vignette.it.apps.server.domain.entit |ies.PhoneNumber" | proxy="true" | indirection-table="COMP_PHONE_NUM_JT" | > | <fk-pointing-to-this-class column="COMP_ID"/> | <fk-pointing-to-element-class column="PHONE_NUM_ID"/> | </collection-descriptor> | | <collection-descriptor | name="vignRelationships" | |element-class-ref="com.vignette.it.apps.server.domain.entit |ies.CompanyRelati |onship" | proxy="true" | indirection-table="COMP_COMP_TYPE_JT" | > | <fk-pointing-to-this-class column="COMP_ID"/> | <fk-pointing-to-element-class column="COMP_TYPE_ID"/> | </collection-descriptor> | | <collection-descriptor | name="industries" | |element-class-ref="com.vignette.it.apps.server.domain.entit |ies.Industry" | proxy="true" | indirection-table="COMP_IND_JT" | > | <fk-pointing-to-this-class column="COMP_ID"/> | <fk-pointing-to-element-class column="IND_ID"/> | </collection-descriptor> | | <collection-descriptor | name="employees" | |element-class-ref="com.vignette.it.apps.server.domain.entit |ies.Contact" | proxy="true" | > | <inverse-foreignkey field-ref="companyId"/> | </collection-descriptor> | | </class-descriptor> | | | | | | | | |<!-- |########################################################### |################# |### |## Contact entity type mapping |########################################################### |################# |### |--> | <class-descriptor | |class="com.vignette.it.apps.server.domain.entities.Contact" | table="COMP_PERS_JT" | > | <field-descriptor | name="id" | column="COMP_PERS_ID" | jdbc-type="INTEGER" | primarykey="true" | autoincrement="true" | /> | | <field-descriptor | name="companyId" | column="COMP_ID" | jdbc-type="INTEGER" | /> | | <field-descriptor | name="personId" | column="PERS_ID" | jdbc-type="INTEGER" | /> | | <field-descriptor | name="managerId" | column="MGR_COMP_PERS_ID" | jdbc-type="INTEGER" | /> | | <field-descriptor | name="title" | column="TITLE_1" | jdbc-type="VARCHAR" | /> | | <field-descriptor | name="title2" | column="TITLE_2" | jdbc-type="VARCHAR" | /> | | <field-descriptor | name="primary" | column="PRIMARY_FLG" | jdbc-type="INTEGER" | |conversion="org.apache.ojb.broker.accesslayer.conversions.B |oolean2IntFieldCo |nversion" | /> | | <field-descriptor | name="active" | column="ACTIVE_FLG" | jdbc-type="INTEGER" | |conversion="org.apache.ojb.broker.accesslayer.conversions.B |oolean2IntFieldCo |nversion" | /> | | <field-descriptor | name="createdBy" | column="CRTD_BY" | jdbc-type="VARCHAR" | /> | | <field-descriptor | name="createdDate" | column="CRTD_DT" | jdbc-type="TIMESTAMP" | |conversion="org.apache.ojb.broker.accesslayer.conversions.J |avaDate2SqlTimest |ampFieldConversion" | /> | | <field-descriptor | name="modifiedBy" | column="CHGD_BY" | jdbc-type="VARCHAR" | /> | | <field-descriptor | name="modifiedDate" | column="CHGD_DT" | jdbc-type="TIMESTAMP" | |conversion="org.apache.ojb.broker.accesslayer.conversions.J |avaDate2SqlTimest |ampFieldConversion" | /> | | <reference-descriptor | name="company" | |class-ref="com.vignette.it.apps.server.domain.entities.Company" | proxy="false" | > | <foreignkey field-ref="companyId"/> | </reference-descriptor> | | <reference-descriptor | name="person" | |class-ref="com.vignette.it.apps.server.domain.entities.Person" | proxy="false" | > | <foreignkey field-ref="personId"/> | </reference-descriptor> | | <reference-descriptor | name="manager" | |class-ref="com.vignette.it.apps.server.domain.entities.Contact" | proxy="true" | > | <foreignkey field-ref="managerId"/> | </reference-descriptor> | | <collection-descriptor | name="addresses" | |element-class-ref="com.vignette.it.apps.server.domain.entit |ies.Address" | proxy="true" | indirection-table="COMP_PERS_ADDR_JT" | > | <fk-pointing-to-this-class column="COMP_PERS_ID"/> | <fk-pointing-to-element-class column="ADDR_ID"/> | </collection-descriptor> | | <collection-descriptor | name="phones" | |element-class-ref="com.vignette.it.apps.server.domain.entit |ies.PhoneNumber" | proxy="true" | indirection-table="COMP_PERS_PHONE_NUM_JT" | > | <fk-pointing-to-this-class column="COMP_PERS_ID"/> | <fk-pointing-to-element-class column="PHONE_NUM_ID"/> | </collection-descriptor> | | </class-descriptor> | | |----------------------------------------------------------- |---------- |To unsubscribe, e-mail: [EMAIL PROTECTED] |For additional commands, e-mail: [EMAIL PROTECTED] | |----------------------------------------------------------- |---------- |To unsubscribe, e-mail: [EMAIL PROTECTED] |For additional commands, e-mail: [EMAIL PROTECTED] | |----------------------------------------------------------- |---------- |To unsubscribe, e-mail: [EMAIL PROTECTED] |For additional commands, e-mail: [EMAIL PROTECTED] | |----------------------------------------------------------- |---------- |To unsubscribe, e-mail: [EMAIL PROTECTED] |For additional commands, e-mail: [EMAIL PROTECTED] | |----------------------------------------------------------- |---------- |To unsubscribe, e-mail: [EMAIL PROTECTED] |For additional commands, e-mail: [EMAIL PROTECTED] | --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]