gdamour 2005/10/01 04:44:09
Modified: modules/openejb-builder/src/java/org/openejb/deployment
AbstractContainerBuilder.java
CMPContainerBuilder.java OpenEJBModuleBuilder.java
SchemataBuilder.java
Log:
GERONIMO-188 Entity instance caching
Add support for caching of CMP entities across Tx.
An entity cache is defined for each CMP. It is queried and updated each
time that a CMP or CMR field is accessed or updated respectively. Also, this
cache is queried when a CMP is faulted if not already associated to the
transactional cache.
An isolation level is defined by an entity cache. Two isolation levels are
currently supported, namely read-uncommitted and read-committed.
read-committed has not yet been tested.
Revision Changes Path
1.16 +9 -6
openejb/modules/openejb-builder/src/java/org/openejb/deployment/AbstractContainerBuilder.java
Index: AbstractContainerBuilder.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/openejb-builder/src/java/org/openejb/deployment/AbstractContainerBuilder.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- AbstractContainerBuilder.java 10 Aug 2005 02:24:56 -0000 1.15
+++ AbstractContainerBuilder.java 1 Oct 2005 08:44:09 -0000 1.16
@@ -96,7 +96,7 @@
private String serviceEndpointName;
private String primaryKeyClassName;
private DefaultPrincipal defaultPrincipal;
- private Subject runAs;
+ protected Subject runAs;
private boolean doAsCurrentCaller = false;
private boolean securityEnabled = false;
private boolean useContextHandler = false;
@@ -399,7 +399,7 @@
return policies;
}
- private Serializable getHomeTxPolicyConfig() throws
ClassNotFoundException {
+ protected Serializable getHomeTxPolicyConfig() throws
ClassNotFoundException {
if (transactionImportPolicyBuilder == null) {
return null;
}
@@ -413,7 +413,7 @@
}
}
- private Serializable getRemoteTxPolicyConfig() throws
ClassNotFoundException {
+ protected Serializable getRemoteTxPolicyConfig() throws
ClassNotFoundException {
if (transactionImportPolicyBuilder == null) {
return null;
}
@@ -486,14 +486,17 @@
Thread.currentThread().getContextClassLoader());
}
-
+ protected GBeanData buildGBeanData() {
+ return new GBeanData(GenericEJBContainer.GBEAN_INFO);
+ }
+
protected GBeanData createConfiguration(ClassLoader cl,
InterfaceMethodSignature[] signatures,
InstanceContextFactory
contextFactory,
InterceptorBuilder
interceptorBuilder,
InstancePool pool,
ObjectName timerName) throws
Exception {
- GBeanData gbean = new GBeanData(GenericEJBContainer.GBEAN_INFO);
+ GBeanData gbean = buildGBeanData();
gbean.setAttribute("containerID", getContainerId());
gbean.setAttribute("ejbName", getEJBName());
gbean.setAttribute("proxyInfo", createProxyInfo());
1.29 +76 -5
openejb/modules/openejb-builder/src/java/org/openejb/deployment/CMPContainerBuilder.java
Index: CMPContainerBuilder.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/openejb-builder/src/java/org/openejb/deployment/CMPContainerBuilder.java,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- CMPContainerBuilder.java 20 Aug 2005 07:53:01 -0000 1.28
+++ CMPContainerBuilder.java 1 Oct 2005 08:44:09 -0000 1.29
@@ -58,7 +58,10 @@
import javax.management.ObjectName;
import org.apache.geronimo.common.DeploymentException;
+import org.apache.geronimo.gbean.GBeanData;
import org.openejb.EJBComponentType;
+import org.openejb.EJBContainer;
+import org.openejb.GenericEJBContainer;
import org.openejb.InstanceContextFactory;
import org.openejb.InterceptorBuilder;
import org.openejb.cache.InstancePool;
@@ -72,6 +75,7 @@
import org.openejb.entity.HomeMethod;
import org.openejb.entity.cmp.CMP1Bridge;
import org.openejb.entity.cmp.CMPCreateMethod;
+import org.openejb.entity.cmp.CMPEJBContainer;
import org.openejb.entity.cmp.CMPEntityInterceptorBuilder;
import org.openejb.entity.cmp.CMPGetter;
import org.openejb.entity.cmp.CMPInstanceContextFactory;
@@ -98,6 +102,10 @@
import org.tranql.cache.FaultHandler;
import org.tranql.cache.GlobalSchema;
import org.tranql.cache.QueryFaultHandler;
+import org.tranql.cache.cache.CacheFactory;
+import org.tranql.cache.cache.CacheFaultHandler;
+import org.tranql.cache.cache.CacheFieldFaultTransform;
+import org.tranql.cache.cache.FrontEndCacheDelegate;
import org.tranql.ejb.CMPFieldAccessor;
import org.tranql.ejb.CMPFieldFaultTransform;
import org.tranql.ejb.CMPFieldIdentityExtractorAccessor;
@@ -154,8 +162,10 @@
private GlobalSchema globalSchema;
private EJB ejb;
private TransactionManagerDelegate tm;
+ private FrontEndCacheDelegate cache;
+ private CacheFactory factory;
private boolean reentrant;
-
+
public boolean isCMP2() {
return cmp2;
}
@@ -211,15 +221,20 @@
protected InterceptorBuilder
initializeInterceptorBuilder(CMPEntityInterceptorBuilder interceptorBuilder,
InterfaceMethodSignature[] signatures, VirtualOperation[] vtable) {
super.initializeInterceptorBuilder(interceptorBuilder, signatures,
vtable);
interceptorBuilder.setCacheFlushStrategyFactory(globalSchema.getCacheFlushStrategyFactorr());
+ interceptorBuilder.setFrontEndCache(cache);
interceptorBuilder.setReentrant(reentrant);
return interceptorBuilder;
}
protected void initialize() throws Exception {
- ejb = ejbSchema.getEJB(getEJBName());
+ String name = getEJBName();
+ ejb = ejbSchema.getEJB(name);
if (ejb == null) {
- throw new DeploymentException("Schema does not contain EJB: " +
getEJBName());
+ throw new DeploymentException("Schema does not contain EJB: " +
name);
}
+ cache = new FrontEndCacheDelegate();
+ CacheTable cacheTable = globalSchema.getCacheTable(name);
+ factory = cacheTable.getCacheFactory();
}
protected Object buildIt(boolean buildContainer) throws Exception {
@@ -245,13 +260,16 @@
List pkAttributes = ejb.getPrimaryKeyFields();
EmptySlotLoader[] slotLoaders = new
EmptySlotLoader[pkAttributes.size()];
String[] attributeNames = new String[pkAttributes.size()];
+ int[] indexes = new int[pkAttributes.size()];
for (int i = 0; i < pkAttributes.size(); i++) {
Attribute attr = (Attribute) pkAttributes.get(i);
attributeNames[i] = attr.getName();
+ indexes[i] = attributes.indexOf(attr);
slotLoaders[i] = new EmptySlotLoader(attributes.indexOf(attr),
new FieldAccessor(i, attr.getType()));
}
QueryCommand loadCommand =
queryBuilder.buildLoadEntity(getEJBName(), attributeNames);
FaultHandler faultHandler = new QueryFaultHandler(loadCommand,
identityDefiner, slotLoaders);
+ faultHandler = new CacheFaultHandler(cache, faultHandler, indexes);
// EJB QL queries
Map finders = queryBuilder.buildFinders(ejb.getName());
@@ -370,7 +388,9 @@
FieldTransform attAccessor =
command.getQuery().getResultAccessors()[0];
EmptySlotLoader[] loaders = new EmptySlotLoader[] {new
EmptySlotLoader(i, attAccessor)};
FaultHandler faultHandler = new QueryFaultHandler(command,
identityDefiner, loaders);
+ faultHandler = new CacheFaultHandler(cache, faultHandler,
new int[] {i});
accessor = new CMPFieldFaultTransform(accessor,
faultHandler, new int[]{i});
+ accessor = new CacheFieldFaultTransform(cache, accessor, i);
}
// TODO: this breaks the CMP1 bridge.
// if (attribute.isIdentity()) {
@@ -402,6 +422,7 @@
CMPFieldTransform accessor = new CMPFieldAccessor(new
CacheRowAccessor(i, null), name);
FaultHandler faultHandler = buildFaultHandler(queryBuilder, ejb,
field, i, prefetch);
+ faultHandler = new CacheFaultHandler(cache, faultHandler, new
int[] {i});
accessor = new CMPFieldFaultTransform(accessor, faultHandler,
new int[]{i});
int relatedIndex = relatedEJB.getAttributes().size() +
relatedEJB.getAssociationEnds().indexOf(relatedField);
@@ -423,7 +444,8 @@
boolean isRight =
association.getRightJoinDefinition().getPKEntity() == ejb;
accessor = new ManyToManyCMR(accessor, relatedAccessor,
relatedIdentityDefiner, mtm, isRight);
}
-
+ accessor = new CacheFieldFaultTransform(cache, accessor, i);
+
cmrFaultAccessors.put(name, accessor);
IdentityTransform relatedIdentityTransform =
identityDefinerBuilder.getPrimaryKeyTransform(relatedEJB);
@@ -698,5 +720,54 @@
}
return vopMap;
+ }
+
+ protected GBeanData buildGBeanData() {
+ return new GBeanData(CMPEJBContainer.GBEAN_INFO);
+ }
+
+ protected EJBContainer createContainer(InterfaceMethodSignature[]
signatures,
+ InstanceContextFactory contextFactory,
+ InterceptorBuilder interceptorBuilder,
+ InstancePool pool) throws Exception {
+
+ return new CMPEJBContainer(
+ getContainerId(),
+ getEJBName(),
+ createProxyInfo(),
+ signatures,
+ contextFactory,
+ interceptorBuilder,
+ pool,
+ getComponentContext(),
+ getUserTransaction(),
+ getJndiNames(),
+ getLocalJndiNames(),
+ getTransactionContextManager(),
+ getTrackedConnectionAssociator(),
+ null, // timer
+ null, // objectname
+ null, // kernel
+ getDefaultPrincipal(),
+ runAs,
+ null,
+ getHomeTxPolicyConfig(),
+ getRemoteTxPolicyConfig(),
+ Thread.currentThread().getContextClassLoader(),
+ cache,
+ factory);
+ }
+
+ protected GBeanData createConfiguration(ClassLoader cl,
InterfaceMethodSignature[] signatures,
+ InstanceContextFactory contextFactory,
+ InterceptorBuilder interceptorBuilder,
+ InstancePool pool,
+ ObjectName timerName) throws Exception {
+ GBeanData gbean = super.createConfiguration(cl, signatures,
contextFactory, interceptorBuilder, pool, timerName);
+
+ gbean.setAttribute("frontEndCacheDelegate", cache);
+ gbean.setAttribute("cacheFactory", factory);
+
+ return gbean;
}
}
1.58 +2 -4
openejb/modules/openejb-builder/src/java/org/openejb/deployment/OpenEJBModuleBuilder.java
Index: OpenEJBModuleBuilder.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/openejb-builder/src/java/org/openejb/deployment/OpenEJBModuleBuilder.java,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -r1.57 -r1.58
--- OpenEJBModuleBuilder.java 28 Sep 2005 22:14:25 -0000 1.57
+++ OpenEJBModuleBuilder.java 1 Oct 2005 08:44:09 -0000 1.58
@@ -50,20 +50,19 @@
import java.io.File;
import java.io.IOException;
-import java.lang.reflect.Constructor;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.Permissions;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.Arrays;
import java.util.jar.JarFile;
import javax.management.MalformedObjectNameException;
@@ -76,7 +75,6 @@
import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
import org.apache.geronimo.deployment.xbeans.DependencyType;
import org.apache.geronimo.deployment.xbeans.GbeanType;
-import org.apache.geronimo.deployment.DeploymentContext;
import org.apache.geronimo.gbean.GBeanData;
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.GBeanInfoBuilder;
1.2 +32 -2
openejb/modules/openejb-builder/src/java/org/openejb/deployment/SchemataBuilder.java
Index: SchemataBuilder.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/openejb-builder/src/java/org/openejb/deployment/SchemataBuilder.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SchemataBuilder.java 10 Sep 2005 14:49:07 -0000 1.1
+++ SchemataBuilder.java 1 Oct 2005 08:44:09 -0000 1.2
@@ -76,15 +76,20 @@
import org.openejb.xbeans.ejbjar.OpenejbGroupType;
import org.openejb.xbeans.ejbjar.OpenejbOpenejbJarType;
import org.openejb.xbeans.ejbjar.OpenejbQueryType;
+import org.openejb.xbeans.ejbjar.OpenejbEntityBeanType.Cache;
import org.openejb.xbeans.ejbjar.OpenejbEntityBeanType.CmpFieldMapping;
import org.openejb.xbeans.ejbjar.OpenejbEntityBeanType.PrefetchGroup;
import org.openejb.xbeans.ejbjar.OpenejbGroupType.CmrField;
import org.openejb.xbeans.pkgen.EjbKeyGeneratorType;
import org.tranql.cache.CacheFlushStrategyFactory;
+import org.tranql.cache.CacheTable;
import org.tranql.cache.EnforceRelationshipsFlushStrategyFactory;
import org.tranql.cache.GlobalSchema;
import org.tranql.cache.GlobalSchemaLoader;
import org.tranql.cache.SimpleFlushStrategyFactory;
+import org.tranql.cache.cache.CacheFactory;
+import org.tranql.cache.cache.ReadCommittedCacheFactory;
+import org.tranql.cache.cache.ReadUncommittedCacheFactory;
import org.tranql.ejb.CMPField;
import org.tranql.ejb.CMRField;
import org.tranql.ejb.EJB;
@@ -172,11 +177,36 @@
processRelationships(ejbJar, openejbEjbJar);
processGroups(openejbEjbJar);
GlobalSchemaLoader.populateGlobalSchema(globalSchema, ejbSchema,
sqlSchema);
+ processEnterpriseBeanCaches(openejbEjbJar);
} catch (Exception e) {
throw new DeploymentException("Could not deploy module", e);
}
return new Schemata(ejbSchema, sqlSchema, globalSchema);
+ }
+
+ private void processEnterpriseBeanCaches(OpenejbOpenejbJarType
openejbEjbJar) {
+ OpenejbEntityBeanType[] openEJBEntities =
openejbEjbJar.getEnterpriseBeans().getEntityArray();
+ for (int i = 0; i < openEJBEntities.length; i++) {
+ String ejbName = openEJBEntities[i].getEjbName();
+ if (false == openEJBEntities[i].isSetCache()) {
+ continue;
+ }
+
+ CacheFactory factory;
+ Cache cache = openEJBEntities[i].getCache();
+ int size = cache.getSize();
+ if (Cache.IsolationLevel.READ_COMMITTED ==
cache.getIsolationLevel()) {
+ factory = new ReadCommittedCacheFactory(size);
+ } else if (Cache.IsolationLevel.READ_UNCOMMITTED ==
cache.getIsolationLevel()) {
+ factory = new ReadUncommittedCacheFactory(size);
+ } else {
+ throw new AssertionError();
+ }
+
+ CacheTable cacheTable = globalSchema.getCacheTable(ejbName);
+ cacheTable.setCacheFactory(factory);
+ }
}
private void processGroups(OpenejbOpenejbJarType openejbEjbJar)