diff --git a/pom.xml b/pom.xml
index b39a81bf7..a3ed6d149 100644
--- a/pom.xml
+++ b/pom.xml
@@ -117,7 +117,7 @@
io.ebeanebean-annotation
- 4.7
+ 4.8
diff --git a/src/main/java/io/ebean/cache/ServerCacheManager.java b/src/main/java/io/ebean/cache/ServerCacheManager.java
index 38de72fc6..a81fe9a52 100644
--- a/src/main/java/io/ebean/cache/ServerCacheManager.java
+++ b/src/main/java/io/ebean/cache/ServerCacheManager.java
@@ -1,5 +1,7 @@
package io.ebean.cache;
+import java.util.List;
+
/**
* The cache service for server side caching of beans and query results.
*/
@@ -14,6 +16,31 @@ public interface ServerCacheManager {
*/
boolean isLocalL2Caching();
+ /**
+ * Return all the cache regions.
+ */
+ List allRegions();
+
+ /**
+ * Set the regions that are enabled.
+ *
+ * Typically this is set on startup and at runtime (via dynamic configuration).
+ *
+ *
+ * @param regions A region name or comma delimited list of region names.
+ */
+ void setEnabledRegions(String regions);
+
+ /**
+ * Enable or disable all the cache regions.
+ */
+ void setAllRegionsEnabled(boolean enabled);
+
+ /**
+ * Return the cache region by name. Typically to enable or disable the region.
+ */
+ ServerCacheRegion getRegion(String name);
+
/**
* Return the cache for mapping natural keys to id values.
*/
@@ -46,7 +73,7 @@ public interface ServerCacheManager {
/**
* Clear all the local caches.
- *
+ *
* This is used when the L2 Cache is based on clustered near-caches (Like Ebean-K8s-L2Cache).
* It is not used when the L2 cache is a distributed cache such as HazelCast or Ignite etc.
*/
@@ -54,7 +81,7 @@ public interface ServerCacheManager {
/**
* Clear the local caches for this bean type.
- *
+ *
* This is used when the L2 Cache is based on clustered near-caches (Like Ebean-K8s-L2Cache).
* It is not used when the L2 cache is a distributed cache such as HazelCast or Ignite etc.
*/
diff --git a/src/main/java/io/ebean/cache/ServerCacheRegion.java b/src/main/java/io/ebean/cache/ServerCacheRegion.java
new file mode 100644
index 000000000..b63668d91
--- /dev/null
+++ b/src/main/java/io/ebean/cache/ServerCacheRegion.java
@@ -0,0 +1,23 @@
+package io.ebean.cache;
+
+/**
+ * Cache region can be enabled independently.
+ */
+public interface ServerCacheRegion {
+
+ /**
+ * Return the region name.
+ */
+ String getName();
+
+ /**
+ * Return true if the cache region is enabled.
+ */
+ boolean isEnabled();
+
+ /**
+ * Set to true to enable the cache region.
+ */
+ void setEnabled(boolean enabled);
+
+}
diff --git a/src/main/java/io/ebeaninternal/api/SpiCacheControl.java b/src/main/java/io/ebeaninternal/api/SpiCacheControl.java
new file mode 100644
index 000000000..17e2fbe17
--- /dev/null
+++ b/src/main/java/io/ebeaninternal/api/SpiCacheControl.java
@@ -0,0 +1,25 @@
+package io.ebeaninternal.api;
+
+public interface SpiCacheControl {
+
+ /**
+ * Return true if bean caching or query caching.
+ */
+ boolean isCaching();
+
+ /**
+ * Return true if bean caching.
+ */
+ boolean isBeanCaching();
+
+ /**
+ * Return true if natural key caching.
+ */
+ boolean isNaturalKeyCaching();
+
+ /**
+ * Return true if query caching.
+ */
+ boolean isQueryCaching();
+
+}
diff --git a/src/main/java/io/ebeaninternal/api/SpiCacheRegion.java b/src/main/java/io/ebeaninternal/api/SpiCacheRegion.java
new file mode 100644
index 000000000..78595b110
--- /dev/null
+++ b/src/main/java/io/ebeaninternal/api/SpiCacheRegion.java
@@ -0,0 +1,10 @@
+package io.ebeaninternal.api;
+
+import io.ebean.cache.ServerCacheRegion;
+
+/**
+ * Cache region can be enabled independently.
+ */
+public interface SpiCacheRegion extends ServerCacheRegion {
+
+}
diff --git a/src/main/java/io/ebeaninternal/server/cache/DefaultCacheAdapter.java b/src/main/java/io/ebeaninternal/server/cache/DefaultCacheAdapter.java
index 0c3cfa9e5..37e89b864 100644
--- a/src/main/java/io/ebeaninternal/server/cache/DefaultCacheAdapter.java
+++ b/src/main/java/io/ebeaninternal/server/cache/DefaultCacheAdapter.java
@@ -2,6 +2,9 @@ package io.ebeaninternal.server.cache;
import io.ebean.cache.ServerCache;
import io.ebean.cache.ServerCacheManager;
+import io.ebean.cache.ServerCacheRegion;
+
+import java.util.List;
/**
* Adapts SpiCacheManager to ServerCacheManager.
@@ -22,6 +25,26 @@ public class DefaultCacheAdapter implements ServerCacheManager {
return cacheManager.isLocalL2Caching();
}
+ @Override
+ public List allRegions() {
+ return cacheManager.allRegions();
+ }
+
+ @Override
+ public void setEnabledRegions(String regions) {
+ cacheManager.setEnabledRegions(regions);
+ }
+
+ @Override
+ public ServerCacheRegion getRegion(String region) {
+ return cacheManager.getRegion(region);
+ }
+
+ @Override
+ public void setAllRegionsEnabled(boolean enabled) {
+ cacheManager.setAllRegionsEnabled(enabled);
+ }
+
@Override
public ServerCache getNaturalKeyCache(Class> beanType) {
return cacheManager.getNaturalKeyCache(beanType);
diff --git a/src/main/java/io/ebeaninternal/server/cache/DefaultServerCacheManager.java b/src/main/java/io/ebeaninternal/server/cache/DefaultServerCacheManager.java
index bdb10d453..bf4fadac6 100644
--- a/src/main/java/io/ebeaninternal/server/cache/DefaultServerCacheManager.java
+++ b/src/main/java/io/ebeaninternal/server/cache/DefaultServerCacheManager.java
@@ -1,14 +1,29 @@
package io.ebeaninternal.server.cache;
import io.ebean.cache.ServerCache;
+import io.ebean.cache.ServerCacheRegion;
import io.ebean.cache.ServerCacheType;
+import io.ebeaninternal.api.SpiCacheRegion;
import io.ebeaninternal.server.cluster.ClusterManager;
+import io.ebeaninternal.server.deploy.DCacheRegion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* Manages the bean and query caches.
*/
public class DefaultServerCacheManager implements SpiCacheManager {
+ private static final Logger log = LoggerFactory.getLogger("io.ebean.cache.REGION");
+
+ private final Map regionMap = new HashMap<>();
+
private final ClusterManager clusterManager;
private final DefaultCacheHolder cacheHolder;
@@ -39,6 +54,47 @@ public class DefaultServerCacheManager implements SpiCacheManager {
return localL2Caching;
}
+ @Override
+ public List allRegions() {
+ return new ArrayList<>(regionMap.values());
+ }
+
+ @Override
+ public void setEnabledRegions(String regions) {
+
+ List enabledRegions = Arrays.asList(regions.split(","));
+ List disabledRegions = new ArrayList<>();
+
+ for (SpiCacheRegion region : regionMap.values()) {
+ if (enabledRegions.contains(region.getName())) {
+ if (!region.isEnabled()) {
+ region.setEnabled(true);
+ log.debug("Cache region[{}] enabled", region.getName());
+ }
+ } else {
+ disabledRegions.add(region.getName());
+ if (region.isEnabled()) {
+ region.setEnabled(false);
+ log.debug("Cache region[{}] disabled", region.getName());
+ }
+ }
+ }
+ log.info("Cache regions enabled:{} disabled:{}", enabledRegions, disabledRegions);
+ }
+
+ @Override
+ public void setAllRegionsEnabled(boolean enabled) {
+ log.debug("All cache regions enabled[{}]", enabled);
+ for (SpiCacheRegion region : regionMap.values()) {
+ region.setEnabled(enabled);
+ }
+ }
+
+ @Override
+ public SpiCacheRegion getRegion(String region) {
+ return regionMap.computeIfAbsent(region, DCacheRegion::new);
+ }
+
/**
* Clear all caches.
*/
diff --git a/src/main/java/io/ebeaninternal/server/cache/SpiCacheManager.java b/src/main/java/io/ebeaninternal/server/cache/SpiCacheManager.java
index 3e83203bd..5ef06b991 100644
--- a/src/main/java/io/ebeaninternal/server/cache/SpiCacheManager.java
+++ b/src/main/java/io/ebeaninternal/server/cache/SpiCacheManager.java
@@ -1,6 +1,10 @@
package io.ebeaninternal.server.cache;
import io.ebean.cache.ServerCache;
+import io.ebean.cache.ServerCacheRegion;
+import io.ebeaninternal.api.SpiCacheRegion;
+
+import java.util.List;
/**
* The cache service for server side caching of beans and query results.
@@ -16,6 +20,28 @@ public interface SpiCacheManager {
*/
boolean isLocalL2Caching();
+ /**
+ * Return all the regions.
+ */
+ List allRegions();
+
+ /**
+ * Set the regions that are enabled.
+ *
+ * @param regions A single region name or a comma delimited list of region names.
+ */
+ void setEnabledRegions(String regions);
+
+ /**
+ * Enable or disable all cache regions.
+ */
+ void setAllRegionsEnabled(boolean enabled);
+
+ /**
+ * Return the cache region. We can enable L2 caching by region.
+ */
+ SpiCacheRegion getRegion(String region);
+
/**
* Return the cache for mapping natural keys to id values.
*/
diff --git a/src/main/java/io/ebeaninternal/server/core/CacheOptions.java b/src/main/java/io/ebeaninternal/server/core/CacheOptions.java
index 24d441828..5fd2fcf54 100644
--- a/src/main/java/io/ebeaninternal/server/core/CacheOptions.java
+++ b/src/main/java/io/ebeaninternal/server/core/CacheOptions.java
@@ -19,16 +19,18 @@ public class CacheOptions {
private final boolean enableQueryCache;
private final boolean readOnly;
private final String[] naturalKey;
+ private final String region;
/**
* Construct for no caching.
*/
private CacheOptions() {
- invalidateQueryCache = false;
- enableBeanCache = false;
- enableQueryCache = false;
- readOnly = false;
- naturalKey = null;
+ this.invalidateQueryCache = false;
+ this.enableBeanCache = false;
+ this.enableQueryCache = false;
+ this.readOnly = false;
+ this.naturalKey = null;
+ this.region = null;
}
/**
@@ -36,21 +38,30 @@ public class CacheOptions {
*/
private CacheOptions(boolean invalidateQueryCache) {
this.invalidateQueryCache = invalidateQueryCache;
- enableBeanCache = false;
- enableQueryCache = false;
- readOnly = false;
- naturalKey = null;
+ this.enableBeanCache = false;
+ this.enableQueryCache = false;
+ this.readOnly = false;
+ this.naturalKey = null;
+ this.region = null;
}
/**
* Construct with cache annotation.
*/
public CacheOptions(Cache cache, String[] naturalKey) {
- invalidateQueryCache = false;
- enableBeanCache = cache.enableBeanCache();
- enableQueryCache = cache.enableQueryCache();
- readOnly = cache.readOnly();
+ this.invalidateQueryCache = false;
+ this.enableBeanCache = cache.enableBeanCache();
+ this.enableQueryCache = cache.enableQueryCache();
+ this.readOnly = cache.readOnly();
this.naturalKey = naturalKey;
+ this.region = cache.region();
+ }
+
+ /**
+ * Return the cache region name.
+ */
+ public String getRegion() {
+ return region;
}
/**
diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorCacheHelp.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorCacheHelp.java
index 88c816040..b2cb88ffb 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorCacheHelp.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorCacheHelp.java
@@ -7,6 +7,8 @@ import io.ebean.bean.PersistenceContext;
import io.ebean.cache.QueryCacheEntry;
import io.ebean.cache.ServerCache;
import io.ebeaninternal.api.BeanCacheResult;
+import io.ebeaninternal.api.SpiCacheControl;
+import io.ebeaninternal.api.SpiCacheRegion;
import io.ebeaninternal.api.SpiTransaction;
import io.ebeaninternal.api.TransactionEventTable.TableIUD;
import io.ebeaninternal.server.cache.CacheChangeSet;
@@ -72,6 +74,9 @@ final class BeanDescriptorCacheHelp {
private final boolean noCaching;
+ private final SpiCacheControl cacheControl;
+ private final SpiCacheRegion cacheRegion;
+
/**
* Set to true if all persist changes need to notify the cache.
*/
@@ -113,6 +118,13 @@ final class BeanDescriptorCacheHelp {
this.naturalKeyCache = null;
}
this.noCaching = (beanCache == null && queryCache == null);
+ if (noCaching) {
+ this.cacheControl = DCacheControlNone.INSTANCE;
+ this.cacheRegion = (invalidateQueryCache) ? cacheManager.getRegion(cacheOptions.getRegion()) : DCacheRegionNone.INSTANCE;
+ } else {
+ this.cacheRegion = cacheManager.getRegion(cacheOptions.getRegion());
+ this.cacheControl = new DCacheControl(cacheRegion, (beanCache != null), (naturalKeyCache != null), (queryCache != null));
+ }
}
/**
@@ -123,8 +135,8 @@ final class BeanDescriptorCacheHelp {
cacheNotifyOnDelete = !cacheNotifyOnAll && isNotifyOnDeletes();
if (logger.isDebugEnabled()) {
- if (isBeanCaching() || isQueryCaching() || cacheNotifyOnAll || cacheNotifyOnDelete) {
- String notifyMode = cacheNotifyOnAll ? "All" : (cacheNotifyOnDelete ? "Delete" : "None");
+ if (cacheNotifyOnAll || cacheNotifyOnDelete) {
+ String notifyMode = cacheNotifyOnAll ? "All" : "Delete";
logger.debug("l2 caching on {} - beanCaching:{} queryCaching:{} notifyMode:{} ",
desc.getFullName(), isBeanCaching(), isQueryCaching(), notifyMode);
}
@@ -148,36 +160,36 @@ final class BeanDescriptorCacheHelp {
* Return true if the persist request needs to notify the cache.
*/
boolean isCacheNotify(PersistRequest.Type type) {
- return cacheNotifyOnAll
- || cacheNotifyOnDelete && (type == PersistRequest.Type.DELETE || type == PersistRequest.Type.DELETE_PERMANENT);
+ return cacheRegion.isEnabled()
+ && (cacheNotifyOnAll || cacheNotifyOnDelete && (type == PersistRequest.Type.DELETE || type == PersistRequest.Type.DELETE_PERMANENT));
}
/**
* Return true if there is currently query caching for this type of bean.
*/
boolean isQueryCaching() {
- return queryCache != null;
+ return cacheControl.isQueryCaching();
}
/**
* Return true if there is currently bean caching for this type of bean.
*/
boolean isBeanCaching() {
- return beanCache != null;
+ return cacheControl.isBeanCaching();
}
/**
* Return true if there is natural key caching for this type of bean.
*/
boolean isNaturalKeyCaching() {
- return naturalKeyCache != null;
+ return cacheControl.isNaturalKeyCaching();
}
/**
* Return true if there is bean or query caching on this type.
*/
boolean isCaching() {
- return beanCache != null || queryCache != null;
+ return cacheControl.isCaching();
}
/**
@@ -206,7 +218,7 @@ final class BeanDescriptorCacheHelp {
/**
* Add query cache clear to the changeSet.
*/
- void queryCacheClear(CacheChangeSet changeSet) {
+ private void queryCacheClear(CacheChangeSet changeSet) {
if (queryCache != null) {
changeSet.addClearQuery(desc);
}
@@ -292,8 +304,8 @@ final class BeanDescriptorCacheHelp {
return false;
}
- Object ownerBean = bc.getOwnerBean();
- EntityBeanIntercept ebi = ((EntityBean) ownerBean)._ebean_getIntercept();
+ EntityBean ownerBean = bc.getOwnerBean();
+ EntityBeanIntercept ebi = ownerBean._ebean_getIntercept();
PersistenceContext persistenceContext = ebi.getPersistenceContext();
BeanDescriptor> targetDescriptor = many.getTargetDescriptor();
@@ -362,6 +374,28 @@ final class BeanDescriptorCacheHelp {
return new CachedManyIds(idList);
}
+// BeanCacheResult cacheIdLookup(PersistenceContext context, Collection> keys) {
+//
+// Set