CMP JDBC2 PM ignores read-ahead strategy = none
jason1 Mar 1, 2006 4:47 PMWhy does the CMP JDBC2 ignore my declared-sql's read-ahead strategy of 'none' ?
JBoss 4.0.2
JDK 1.4.2
Windows
Oracle DB
EJB2.1
I am having a problem with migrating to the cmp2.x jdbc2.x pm configuration for my read-only entity beans with cache invalidation. Let me begin with my original setup to express the problem.
For all read-only EJBs, I found that ejb finders would perform SQL to make sure all the rows were returned should new or old beans exist that were not cached. However, this SQL loaded all attributes of the bean, only to find them on the cached anyway which IMO was loading way more columns than required. All that was required was the primary key, so the rest of the attributes were loaded from the cache. To prevent loading more columns than necessary, I created JBoss QL overrides that only fetched PKs for each custom finder. JBoss QL override look like this:
<query> <description> Loads PKs only. Entity data should already be cached. </description> <query-method> <method-name>findByDeviceId</method-name> <method-params> <method-param>java.math.BigDecimal</method-param> </method-params> </query-method> <declared-sql> <where><![CDATA[ DEVICE_ID = {0} ]]></where> </declared-sql> <read-ahead> <strategy>none</strategy> </read-ahead> </query>
Once I moved from Instance per txn container to a cmp2.x jdbc2 pm-based container (see below), it fails with this error:
2006-03-01 14:17:15,515 DEBUG [cdot.ctms.layer.services.comm.test.TestDeviceExtService] [1] testFindByDeviceId: Checking findByDeviceId FK... 2006-03-01 14:17:15,515 DEBUG [org.jboss.ejb.plugins.cmp.jdbc2.DeclaredSQLQueryCommand.DeviceExtRO#findByDeviceId] executing: SELECT DEVICE_EXT_ID FROM DEVICE_EXT WHERE DEVICE_ID = ? 2006-03-01 14:17:15,515 TRACE [org.jboss.ejb.plugins.cmp.jdbc2.DeclaredSQLQueryCommand.DeviceExtRO#findByDeviceId] param: i=1, type=DECIMAL, value=1 2006-03-01 14:17:15,515 TRACE [org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCCMPFieldBridge2.DeviceExtRO#deviceExtId] result: i=1, type=java.math.BigDecimal, value=1295 2006-03-01 14:17:15,515 TRACE [org.jboss.ejb.plugins.cmp.jdbc2.schema.EntityTable.DEVICE_EXT] reading result set: pk=1295 2006-03-01 14:17:15,515 TRACE [org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCCMPFieldBridge2.DeviceExtRO#deviceExtId] result: i=1, type=java.math.BigDecimal, value=1295 2006-03-01 14:17:15,578 ERROR [org.jboss.ejb.plugins.cmp.jdbc2.DeclaredSQLQueryCommand.DeviceExtRO#findByDeviceId] Finder failed: Internal error getting results for field member nameTxt; CausedByException is: Invalid column index javax.ejb.EJBException: Internal error getting results for field member nameTxt; CausedByException is: Invalid column index at org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCCMPFieldBridge2.loadArgumentResults(JDBCCMPFieldBridge2.java:227) at org.jboss.ejb.plugins.cmp.jdbc2.schema.EntityTable$View.loadRow(EntityTable.java:968) at org.jboss.ejb.plugins.cmp.jdbc2.schema.EntityTable.loadRow(EntityTable.java:422) at org.jboss.ejb.plugins.cmp.jdbc2.AbstractQueryCommand$EntityReader.readRow(AbstractQueryCommand.java:284) at org.jboss.ejb.plugins.cmp.jdbc2.AbstractQueryCommand$EagerCollectionStrategy.readResultSet(AbstractQueryCommand.java:340) at org.jboss.ejb.plugins.cmp.jdbc2.AbstractQueryCommand.fetchCollection(AbstractQueryCommand.java:161) at org.jboss.ejb.plugins.cmp.jdbc2.JDBCStoreManager2.findEntities(JDBCStoreManager2.java:349) at org.jboss.ejb.plugins.CMPPersistenceManager.findEntities(CMPPersistenceManager.java:322) at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.findEntities(CachedConnectionInterceptor.java:321)
New Container configuration that fails:
<container-configuration> <!-- | This is like standard IPT but with global (cross-transactional) row cache behind, | i.e. no locking in EJB layer + global persistence data cache --> <container-name>cmp2.x jdbc2 pm with Cache Invalidation</container-name> <call-logging>false</call-logging> <invoker-proxy-binding-name>entity-rmi-invoker</invoker-proxy-binding-name> <sync-on-commit-only>false</sync-on-commit-only> <insert-after-ejb-post-create>true</insert-after-ejb-post-create> <call-ejb-store-on-clean>true</call-ejb-store-on-clean> <container-interceptors> <interceptor>org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor</interceptor> <interceptor>org.jboss.ejb.plugins.LogInterceptor</interceptor> <interceptor>org.jboss.ejb.plugins.SecurityInterceptor</interceptor> <interceptor>org.jboss.ejb.plugins.TxInterceptorCMT</interceptor> <interceptor>org.jboss.ejb.plugins.EntityCreationInterceptor</interceptor> <interceptor>org.jboss.ejb.plugins.EntityInstanceInterceptor</interceptor> <interceptor>org.jboss.ejb.plugins.EntityReentranceInterceptor</interceptor> <interceptor>org.jboss.resource.connectionmanager.CachedConnectionInterceptor</interceptor> <interceptor>org.jboss.ejb.plugins.EntitySynchronizationInterceptor</interceptor> <interceptor>org.jboss.cache.invalidation.triggers.EntityBeanCacheBatchInvalidatorInterceptor</interceptor> <interceptor>org.jboss.ejb.plugins.cmp.jdbc2.RelationInterceptor</interceptor> </container-interceptors> <instance-pool>org.jboss.ejb.plugins.EntityInstancePool</instance-pool> <instance-cache>org.jboss.ejb.plugins.PerTxEntityInstanceCache</instance-cache> <persistence-manager>org.jboss.ejb.plugins.cmp.jdbc2.JDBCStoreManager2</persistence-manager> <locking-policy>org.jboss.ejb.plugins.lock.NoLock</locking-policy> <container-cache-conf> <cache-policy-conf> <min-capacity>500</min-capacity> <max-capacity>10000</max-capacity> </cache-policy-conf> <cache-policy-conf-other> <partitions>10</partitions> <!-- uncomment to use JDBC java.sql.Statement.executeBatch() <batch-commit-strategy/> --> <invalidable/> </cache-policy-conf-other> </container-cache-conf> <container-pool-conf> <MaximumSize>100</MaximumSize> </container-pool-conf> <commit-option>C</commit-option> <!-- don't change, irrelevant, use container-cache-conf --> </container-configuration>