mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#684 - Refactor - rename @CacheStrategy to @Cache ... require explicit enableQueryCache=true for query cache use
This commit is contained in:
+22
-11
@@ -5,25 +5,36 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.avaje.ebean.Query;
|
||||
|
||||
/**
|
||||
* Specify the default cache use specific entity type.
|
||||
*/
|
||||
@Target({ ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface CacheStrategy {
|
||||
public @interface Cache {
|
||||
|
||||
/**
|
||||
* When set to true the bean cache will be used unless explicitly stated not
|
||||
* to in a query via {@link Query#setUseCache(boolean)}.
|
||||
*/
|
||||
boolean useBeanCache() default true;
|
||||
|
||||
/**
|
||||
* A single property that is a natural unique identifier for the bean.
|
||||
* Set this to true to enable the use of query cache.
|
||||
* <p>
|
||||
* When a findUnique query is used with this property as the sole expression
|
||||
* By default query caching is disabled as the query cache invalidates
|
||||
* frequently and so it is typically used for specific bean types and cases.
|
||||
* </p>
|
||||
*/
|
||||
boolean enableQueryCache() default false;
|
||||
|
||||
/**
|
||||
* Set this to false to disable the use of bean cache.
|
||||
* <p>
|
||||
* By default bean caching is expected so this defaults to true. We might
|
||||
* set this to false on a bean type that we want to use query caching but no
|
||||
* bean caching (and this is expected to be a rare case).
|
||||
* </p>
|
||||
*/
|
||||
boolean enableBeanCache() default true;
|
||||
|
||||
/**
|
||||
* Specify the property that is a natural unique identifier for the bean.
|
||||
* <p>
|
||||
* When a findUnique() query is used with this property as the sole expression
|
||||
* then there will be a lookup into the L2 natural key cache.
|
||||
* </p>
|
||||
*/
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.avaje.ebean.cache;
|
||||
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
|
||||
/**
|
||||
* Represents part of the "L2" server side cache.
|
||||
* <p>
|
||||
@@ -17,27 +15,6 @@ import com.avaje.ebean.EbeanServer;
|
||||
*/
|
||||
public interface ServerCache {
|
||||
|
||||
/**
|
||||
* Just after a cache is created this init method is called. This is so that a
|
||||
* cache implementation can make use of the BackgroundExecutor service to
|
||||
* trim/cleanup itself or use the EbeanServer to populate itself.
|
||||
* <p>
|
||||
* This method is called after the cache is constructed but before the cache
|
||||
* is made available for use.
|
||||
* </p>
|
||||
*/
|
||||
void init(EbeanServer ebeanServer);
|
||||
|
||||
/**
|
||||
* Return the configuration options for this cache.
|
||||
*/
|
||||
ServerCacheOptions getOptions();
|
||||
|
||||
/**
|
||||
* Update the configuration options for this cache.
|
||||
*/
|
||||
void setOptions(ServerCacheOptions options);
|
||||
|
||||
/**
|
||||
* Return the value given the key.
|
||||
*/
|
||||
|
||||
@@ -1,23 +1,10 @@
|
||||
package com.avaje.ebean.cache;
|
||||
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
|
||||
/**
|
||||
* Defines method for constructing caches for beans and queries.
|
||||
*/
|
||||
public interface ServerCacheFactory {
|
||||
|
||||
/**
|
||||
* Just after the ServerCacheFactory is constructed this method is called
|
||||
* passing the EbeanServer.
|
||||
* <p>
|
||||
* This is so that a cache implementation can utilise the EbeanServer to
|
||||
* populate itself or use the BackgroundExecutor service to schedule periodic
|
||||
* cache trimming/cleanup.
|
||||
* </p>
|
||||
*/
|
||||
void init(EbeanServer ebeanServer);
|
||||
|
||||
/**
|
||||
* Create the cache for the given type with options.
|
||||
*/
|
||||
|
||||
+3
-15
@@ -1,25 +1,10 @@
|
||||
package com.avaje.ebean.cache;
|
||||
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
|
||||
/**
|
||||
* The cache service for server side caching of beans and query results.
|
||||
*/
|
||||
public interface ServerCacheManager {
|
||||
|
||||
/**
|
||||
* This method is called just after the construction of the
|
||||
* ServerCacheManager.
|
||||
* <p>
|
||||
* The EbeanServer is provided so that cache implementations can make use of
|
||||
* EbeanServer and BackgroundExecutor for automatically populating and
|
||||
* background trimming of the cache.
|
||||
* </p>
|
||||
*/
|
||||
void init(EbeanServer server);
|
||||
|
||||
void setCaching(Class<?> beanType, boolean useCache);
|
||||
|
||||
/**
|
||||
* Return true if there is an active bean cache for this type of bean.
|
||||
*/
|
||||
@@ -35,6 +20,9 @@ public interface ServerCacheManager {
|
||||
*/
|
||||
ServerCache getBeanCache(Class<?> beanType);
|
||||
|
||||
/**
|
||||
* Return the cache for associated many properties of a bean type.
|
||||
*/
|
||||
ServerCache getCollectionIdsCache(Class<?> beanType, String propertyName);
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.avaje.ebean.cache;
|
||||
|
||||
import com.avaje.ebean.BackgroundExecutor;
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
|
||||
/**
|
||||
* The plugin interface that creates a ServerCacheFactory.
|
||||
*/
|
||||
public interface ServerCachePlugin {
|
||||
|
||||
/**
|
||||
* Create the ServerCacheFactory given the server config and background executor service.
|
||||
*/
|
||||
ServerCacheFactory create(ServerConfig config, BackgroundExecutor executor);
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import com.avaje.ebean.PersistenceContextScope;
|
||||
import com.avaje.ebean.annotation.Encrypted;
|
||||
import com.avaje.ebean.cache.ServerCacheFactory;
|
||||
import com.avaje.ebean.cache.ServerCacheManager;
|
||||
import com.avaje.ebean.cache.ServerCachePlugin;
|
||||
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
|
||||
import com.avaje.ebean.config.dbplatform.DbEncrypt;
|
||||
import com.avaje.ebean.event.BeanFindController;
|
||||
@@ -356,7 +357,7 @@ public class ServerConfig {
|
||||
|
||||
private DbEncrypt dbEncrypt;
|
||||
|
||||
private ServerCacheFactory serverCacheFactory;
|
||||
private ServerCachePlugin serverCachePlugin;
|
||||
|
||||
private ServerCacheManager serverCacheManager;
|
||||
|
||||
@@ -938,17 +939,17 @@ public class ServerConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ServerCacheFactory.
|
||||
* Return the ServerCachePlugin.
|
||||
*/
|
||||
public ServerCacheFactory getServerCacheFactory() {
|
||||
return serverCacheFactory;
|
||||
public ServerCachePlugin getServerCachePlugin() {
|
||||
return serverCachePlugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ServerCacheFactory to use.
|
||||
* Set the ServerCachePlugin to use.
|
||||
*/
|
||||
public void setServerCacheFactory(ServerCacheFactory serverCacheFactory) {
|
||||
this.serverCacheFactory = serverCacheFactory;
|
||||
public void setServerCachePlugin(ServerCachePlugin serverCachePlugin) {
|
||||
this.serverCachePlugin = serverCachePlugin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2352,7 +2353,7 @@ public class ServerConfig {
|
||||
encryptDeployManager = createInstance(p, EncryptDeployManager.class, "encryptDeployManager", encryptDeployManager);
|
||||
encryptor = createInstance(p, Encryptor.class, "encryptor", encryptor);
|
||||
dbEncrypt = createInstance(p, DbEncrypt.class, "dbEncrypt", dbEncrypt);
|
||||
serverCacheFactory = createInstance(p, ServerCacheFactory.class, "serverCacheFactory", serverCacheFactory);
|
||||
serverCachePlugin = createInstance(p, ServerCachePlugin.class, "serverCachePlugin", serverCachePlugin);
|
||||
serverCacheManager = createInstance(p, ServerCacheManager.class, "serverCacheManager", serverCacheManager);
|
||||
cacheWarmingDelay = p.getInt("cacheWarmingDelay", cacheWarmingDelay);
|
||||
classPathReaderClassName = p.get("classpathreader");
|
||||
|
||||
@@ -150,8 +150,8 @@ public class VisitAllUsing {
|
||||
}
|
||||
|
||||
public void visit(InheritInfo inheritInfo) {
|
||||
BeanProperty[] propertiesLocal = inheritInfo.getBeanDescriptor().propertiesLocal();
|
||||
for (int i = 0; i <propertiesLocal.length ; i++) {
|
||||
BeanProperty[] propertiesLocal = inheritInfo.desc().propertiesLocal();
|
||||
for (int i = 0; i < propertiesLocal.length; i++) {
|
||||
owner.visit(pv, propertiesLocal[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,8 +47,4 @@ public interface SpiServer extends EbeanServer {
|
||||
*/
|
||||
DataSource getDataSource();
|
||||
|
||||
/**
|
||||
* Initialise the query cache for the given bean type.
|
||||
*/
|
||||
boolean initQueryCache(String key);
|
||||
}
|
||||
|
||||
+6
-5
@@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.server.cache;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.bean.EntityBeanIntercept;
|
||||
import com.avaje.ebean.bean.PersistenceContext;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
@@ -9,20 +10,20 @@ import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
public class CachedBeanDataToBean {
|
||||
|
||||
|
||||
public static void load(BeanDescriptor<?> desc, EntityBean bean, CachedBeanData cacheBeanData) {
|
||||
public static void load(BeanDescriptor<?> desc, EntityBean bean, CachedBeanData cacheBeanData, PersistenceContext context) {
|
||||
|
||||
EntityBeanIntercept ebi = bean._ebean_getIntercept();
|
||||
|
||||
BeanProperty idProperty = desc.getIdProperty();
|
||||
if (idProperty != null) {
|
||||
// load the id property
|
||||
loadProperty(bean, cacheBeanData, ebi, idProperty);
|
||||
loadProperty(bean, cacheBeanData, ebi, idProperty, context);
|
||||
}
|
||||
|
||||
// load the non-many properties
|
||||
BeanProperty[] props = desc.propertiesNonMany();
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
loadProperty(bean, cacheBeanData, ebi, props[i]);
|
||||
loadProperty(bean, cacheBeanData, ebi, props[i], context);
|
||||
}
|
||||
|
||||
BeanPropertyAssocMany<?>[] many = desc.propertiesMany();
|
||||
@@ -33,12 +34,12 @@ public class CachedBeanDataToBean {
|
||||
ebi.setLoadedLazy();
|
||||
}
|
||||
|
||||
private static void loadProperty(EntityBean bean, CachedBeanData cacheBeanData, EntityBeanIntercept ebi, BeanProperty prop) {
|
||||
private static void loadProperty(EntityBean bean, CachedBeanData cacheBeanData, EntityBeanIntercept ebi, BeanProperty prop, PersistenceContext context) {
|
||||
|
||||
if (cacheBeanData.isLoaded(prop.getName())) {
|
||||
if (!ebi.isLoadedProperty(prop.getPropertyIndex())) {
|
||||
Object value = cacheBeanData.getData(prop.getName());
|
||||
prop.setCacheDataValue(bean, value);
|
||||
prop.setCacheDataValue(bean, value, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-31
@@ -107,15 +107,12 @@ public class DefaultServerCache implements ServerCache {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(EbeanServer server) {
|
||||
public void periodicTrim(BackgroundExecutor executor) {
|
||||
|
||||
EvictionRunnable trim = new EvictionRunnable();
|
||||
|
||||
// default to trimming the cache every 60 seconds
|
||||
long trimFreqSecs = (trimFrequency == 0) ? 60 : trimFrequency;
|
||||
|
||||
BackgroundExecutor executor = server.getBackgroundExecutor();
|
||||
executor.executePeriodically(trim, trimFreqSecs, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@@ -176,33 +173,6 @@ public class DefaultServerCache implements ServerCache {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the options controlling the cache.
|
||||
*/
|
||||
@Override
|
||||
public ServerCacheOptions getOptions() {
|
||||
synchronized (monitor) {
|
||||
ServerCacheOptions options = new ServerCacheOptions();
|
||||
options.setMaxIdleSecs(maxIdleSecs);
|
||||
options.setMaxSize(maxSize);
|
||||
options.setMaxSecsToLive(maxSecsToLive);
|
||||
options.setTrimFrequency(trimFrequency);
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the options controlling the cache
|
||||
*/
|
||||
@Override
|
||||
public void setOptions(ServerCacheOptions options) {
|
||||
synchronized (monitor) {
|
||||
maxIdleSecs = options.getMaxIdleSecs();
|
||||
maxSize = options.getMaxSize();
|
||||
maxSecsToLive = options.getMaxSecsToLive();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the cache.
|
||||
*/
|
||||
|
||||
+19
-7
@@ -1,6 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.cache;
|
||||
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
import com.avaje.ebean.BackgroundExecutor;
|
||||
import com.avaje.ebean.cache.ServerCache;
|
||||
import com.avaje.ebean.cache.ServerCacheFactory;
|
||||
import com.avaje.ebean.cache.ServerCacheOptions;
|
||||
@@ -10,18 +10,30 @@ import com.avaje.ebean.cache.ServerCacheType;
|
||||
/**
|
||||
* Default implementation of ServerCacheFactory.
|
||||
*/
|
||||
public class DefaultServerCacheFactory implements ServerCacheFactory {
|
||||
class DefaultServerCacheFactory implements ServerCacheFactory {
|
||||
|
||||
private EbeanServer ebeanServer;
|
||||
private final BackgroundExecutor executor;
|
||||
|
||||
public void init(EbeanServer ebeanServer) {
|
||||
this.ebeanServer = ebeanServer;
|
||||
/**
|
||||
* Construct when l2 cache is disabled.
|
||||
*/
|
||||
public DefaultServerCacheFactory() {
|
||||
this.executor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with executor service.
|
||||
*/
|
||||
public DefaultServerCacheFactory(BackgroundExecutor executor) {
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
public ServerCache createCache(ServerCacheType type, String cacheKey, ServerCacheOptions cacheOptions) {
|
||||
|
||||
ServerCache cache = new DefaultServerCache(cacheKey, cacheOptions);
|
||||
cache.init(ebeanServer);
|
||||
DefaultServerCache cache = new DefaultServerCache(cacheKey, cacheOptions);
|
||||
if (executor != null) {
|
||||
cache.periodicTrim(executor);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
|
||||
-19
@@ -1,12 +1,10 @@
|
||||
package com.avaje.ebeaninternal.server.cache;
|
||||
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
import com.avaje.ebean.cache.ServerCache;
|
||||
import com.avaje.ebean.cache.ServerCacheFactory;
|
||||
import com.avaje.ebean.cache.ServerCacheManager;
|
||||
import com.avaje.ebean.cache.ServerCacheOptions;
|
||||
import com.avaje.ebean.cache.ServerCacheType;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
|
||||
|
||||
/**
|
||||
@@ -22,15 +20,10 @@ public class DefaultServerCacheManager implements ServerCacheManager {
|
||||
|
||||
private final DefaultCacheHolder collectionIdsCache;
|
||||
|
||||
private final ServerCacheFactory cacheFactory;
|
||||
|
||||
private SpiEbeanServer ebeanServer;
|
||||
|
||||
/**
|
||||
* Create with a cache factory and default cache options.
|
||||
*/
|
||||
public DefaultServerCacheManager(ServerCacheFactory cacheFactory, ServerCacheOptions defaultBeanOptions, ServerCacheOptions defaultQueryOptions) {
|
||||
this.cacheFactory = cacheFactory;
|
||||
this.beanCache = new DefaultCacheHolder(cacheFactory, defaultBeanOptions);
|
||||
this.queryCache = new DefaultCacheHolder(cacheFactory, defaultQueryOptions);
|
||||
this.naturalKeyCache = new DefaultCacheHolder(cacheFactory, defaultBeanOptions);
|
||||
@@ -44,18 +37,6 @@ public class DefaultServerCacheManager implements ServerCacheManager {
|
||||
this(new DefaultServerCacheFactory(), new ServerCacheOptions(), new ServerCacheOptions());
|
||||
}
|
||||
|
||||
public void init(EbeanServer server) {
|
||||
cacheFactory.init(server);
|
||||
this.ebeanServer = (SpiEbeanServer) server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set bean caching on or off for a given bean type.
|
||||
*/
|
||||
public void setCaching(Class<?> beanType, boolean useCache) {
|
||||
ebeanServer.getBeanDescriptor(beanType).setUseCache(useCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear both the bean cache and the query cache for a
|
||||
* given bean type.
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.avaje.ebeaninternal.server.cache;
|
||||
|
||||
import com.avaje.ebean.BackgroundExecutor;
|
||||
import com.avaje.ebean.cache.ServerCacheFactory;
|
||||
import com.avaje.ebean.cache.ServerCachePlugin;
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
|
||||
/**
|
||||
* Default implementation of ServerCachePlugin.
|
||||
*/
|
||||
public class DefaultServerCachePlugin implements ServerCachePlugin {
|
||||
|
||||
/**
|
||||
* Creates the default ServerCacheFactory.
|
||||
*/
|
||||
@Override
|
||||
public ServerCacheFactory create(ServerConfig config, BackgroundExecutor executor) {
|
||||
return new DefaultServerCacheFactory(executor);
|
||||
}
|
||||
}
|
||||
@@ -1,111 +1,67 @@
|
||||
package com.avaje.ebeaninternal.server.core;
|
||||
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
|
||||
/**
|
||||
* Options for controlling cache behaviour for a given type.
|
||||
*/
|
||||
public class CacheOptions {
|
||||
|
||||
private boolean useCache;
|
||||
|
||||
private boolean readOnly;
|
||||
|
||||
private String naturalKey;
|
||||
|
||||
private int maxIdleSecs;
|
||||
|
||||
private long maxSecsToLive;
|
||||
|
||||
/**
|
||||
* Construct with options.
|
||||
* Instance when no caching is used.
|
||||
*/
|
||||
public CacheOptions() {
|
||||
public static CacheOptions NO_CACHING = new CacheOptions();
|
||||
|
||||
private final boolean enableBeanCache;
|
||||
private final boolean enableQueryCache;
|
||||
private final boolean readOnly;
|
||||
private final String naturalKey;
|
||||
|
||||
/**
|
||||
* Construct for no caching.
|
||||
*/
|
||||
private CacheOptions() {
|
||||
enableBeanCache = false;
|
||||
enableQueryCache = false;
|
||||
readOnly = false;
|
||||
naturalKey = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this should use a cache for lazy loading.
|
||||
* Construct with cache annotation.
|
||||
*/
|
||||
public boolean isUseCache() {
|
||||
return useCache;
|
||||
public CacheOptions(Cache cache, String naturalKey) {
|
||||
enableBeanCache = cache.enableBeanCache();
|
||||
enableQueryCache = cache.enableQueryCache();
|
||||
readOnly = cache.readOnly();
|
||||
this.naturalKey = naturalKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to use the bean cache for the associated type.
|
||||
* Return true if bean caching is enabled.
|
||||
*/
|
||||
public void setUseCache(boolean useCache) {
|
||||
this.useCache = useCache;
|
||||
public boolean isEnableBeanCache() {
|
||||
return enableBeanCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the readOnly default setting.
|
||||
* Return true if query caching is enabled.
|
||||
*/
|
||||
public boolean isEnableQueryCache() {
|
||||
return enableQueryCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if bean cache hits default to read only.
|
||||
*/
|
||||
public boolean isReadOnly() {
|
||||
return readOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set read Only default setting.
|
||||
*/
|
||||
public void setReadOnly(boolean readOnly) {
|
||||
this.readOnly = readOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if a natural key is set.
|
||||
*/
|
||||
public boolean isUseNaturalKeyCache() {
|
||||
return naturalKey != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the natural key property.
|
||||
* Return the natural key property name.
|
||||
*/
|
||||
public String getNaturalKey() {
|
||||
return naturalKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the natural key property.
|
||||
*/
|
||||
public void setNaturalKey(String naturalKey) {
|
||||
if (naturalKey != null && naturalKey.length() != 0) {
|
||||
this.naturalKey = naturalKey.trim();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the max age of entries in seconds.
|
||||
*/
|
||||
public long getMaxSecsToLive() {
|
||||
return maxSecsToLive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the max age of entries in seconds.
|
||||
*/
|
||||
public void setMaxSecsToLive(long maxSecsToLive) {
|
||||
this.maxSecsToLive = maxSecsToLive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the max idle seconds.
|
||||
*/
|
||||
public void setMaxIdleSecs(int maxIdleSecs) {
|
||||
this.maxIdleSecs = maxIdleSecs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the max idle seconds.
|
||||
*/
|
||||
public int getMaxIdleSecs() {
|
||||
return maxIdleSecs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the entry exceeds the maxIdleSecs or maxSecsToLive.
|
||||
*/
|
||||
public boolean isTooOldInMillis(long ageMillis) {
|
||||
long secs = ageMillis / 1000;
|
||||
return (maxIdleSecs > 0 && secs > maxIdleSecs) || (maxSecsToLive > 0 && secs > maxSecsToLive);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -270,15 +270,15 @@ public class DefaultBeanLoader {
|
||||
boolean draft = desc.isDraftInstance(bean);
|
||||
|
||||
if (embeddedOwnerIndex == -1) {
|
||||
if (!draft && SpiQuery.Mode.LAZYLOAD_BEAN.equals(mode) && desc.isBeanCaching()) {
|
||||
// lazy loading and the bean cache is active
|
||||
if (desc.cacheBeanLoad(bean, ebi, id)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (desc.lazyLoadMany(ebi)) {
|
||||
return;
|
||||
}
|
||||
if (!draft && SpiQuery.Mode.LAZYLOAD_BEAN.equals(mode) && desc.isBeanCaching()) {
|
||||
// lazy loading and the bean cache is active
|
||||
if (desc.cacheBeanLoad(bean, ebi, id, pc)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SpiQuery<?> query = (SpiQuery<?>) server.createQuery(desc.getBeanType());
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.avaje.ebeaninternal.server.core;
|
||||
|
||||
import com.avaje.ebean.BackgroundExecutor;
|
||||
import com.avaje.ebean.cache.ServerCacheFactory;
|
||||
import com.avaje.ebean.cache.ServerCacheManager;
|
||||
import com.avaje.ebean.cache.ServerCacheOptions;
|
||||
import com.avaje.ebean.cache.ServerCachePlugin;
|
||||
import com.avaje.ebean.common.SpiContainer;
|
||||
import com.avaje.ebean.config.ContainerConfig;
|
||||
import com.avaje.ebean.config.PropertyMap;
|
||||
@@ -12,7 +14,7 @@ import com.avaje.ebean.config.dbplatform.DatabasePlatform;
|
||||
import com.avaje.ebean.dbmigration.DbOffline;
|
||||
import com.avaje.ebeaninternal.api.SpiBackgroundExecutor;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.server.cache.DefaultServerCacheFactory;
|
||||
import com.avaje.ebeaninternal.server.cache.DefaultServerCachePlugin;
|
||||
import com.avaje.ebeaninternal.server.cache.DefaultServerCacheManager;
|
||||
import com.avaje.ebeaninternal.server.cluster.ClusterManager;
|
||||
import com.avaje.ebeaninternal.server.lib.ShutdownManager;
|
||||
@@ -108,19 +110,15 @@ public class DefaultContainer implements SpiContainer {
|
||||
// inform the NamingConvention of the associated DatabasePlatform
|
||||
serverConfig.getNamingConvention().setDatabasePlatform(serverConfig.getDatabasePlatform());
|
||||
|
||||
ServerCacheManager cacheManager = getCacheManager(online, serverConfig);
|
||||
// executor and l2 caching service setup early (used during server construction)
|
||||
SpiBackgroundExecutor executor = createBackgroundExecutor(serverConfig);
|
||||
ServerCacheManager cacheManager = getCacheManager(online, serverConfig, executor);
|
||||
|
||||
SpiBackgroundExecutor bgExecutor = createBackgroundExecutor(serverConfig);
|
||||
|
||||
XmlConfigLoader xmlConfigLoader = new XmlConfigLoader(null);
|
||||
XmlConfig xmlConfig = xmlConfigLoader.load();
|
||||
|
||||
InternalConfiguration c = new InternalConfiguration(xmlConfig, clusterManager, cacheManager, bgExecutor, serverConfig, bootupClasses);
|
||||
XmlConfig xmlConfig = new XmlConfigLoader(null).load();
|
||||
InternalConfiguration c = new InternalConfiguration(xmlConfig, clusterManager, cacheManager, executor, serverConfig, bootupClasses);
|
||||
|
||||
DefaultServer server = new DefaultServer(c, cacheManager);
|
||||
|
||||
cacheManager.init(server);
|
||||
|
||||
// generate and run DDL if required
|
||||
// if there are any other tasks requiring action in their plugins, do them as well
|
||||
if (!DbOffline.isRunningMigration()) {
|
||||
@@ -147,7 +145,7 @@ public class DefaultContainer implements SpiContainer {
|
||||
/**
|
||||
* Create and return the CacheManager.
|
||||
*/
|
||||
private ServerCacheManager getCacheManager(boolean online, ServerConfig serverConfig) {
|
||||
private ServerCacheManager getCacheManager(boolean online, ServerConfig serverConfig, BackgroundExecutor executor) {
|
||||
|
||||
if (!online || serverConfig.isDisableL2Cache()) {
|
||||
// use local only L2 cache implementation as placeholder
|
||||
@@ -171,21 +169,22 @@ public class DefaultContainer implements SpiContainer {
|
||||
queryOptions.setMaxIdleSecs(serverConfig.getQueryCacheMaxIdleTime());
|
||||
queryOptions.setMaxSecsToLive(serverConfig.getQueryCacheMaxTimeToLive());
|
||||
|
||||
ServerCacheFactory cacheFactory = serverConfig.getServerCacheFactory();
|
||||
if (cacheFactory == null) {
|
||||
ServiceLoader<ServerCacheFactory> cacheFactories = ServiceLoader.load(ServerCacheFactory.class);
|
||||
Iterator<ServerCacheFactory> iterator = cacheFactories.iterator();
|
||||
ServerCachePlugin plugin = serverConfig.getServerCachePlugin();
|
||||
if (plugin == null) {
|
||||
ServiceLoader<ServerCachePlugin> cacheFactories = ServiceLoader.load(ServerCachePlugin.class);
|
||||
Iterator<ServerCachePlugin> iterator = cacheFactories.iterator();
|
||||
if (iterator.hasNext()) {
|
||||
// use the cacheFactory (via classpath service loader)
|
||||
cacheFactory = iterator.next();
|
||||
logger.debug("using ServerCacheFactory {}", cacheFactory.getClass());
|
||||
plugin = iterator.next();
|
||||
logger.debug("using ServerCacheFactory {}", plugin.getClass());
|
||||
} else {
|
||||
// use the built in default
|
||||
cacheFactory = new DefaultServerCacheFactory();
|
||||
plugin = new DefaultServerCachePlugin();
|
||||
}
|
||||
}
|
||||
|
||||
return new DefaultServerCacheManager(cacheFactory, beanOptions, queryOptions);
|
||||
ServerCacheFactory factory = plugin.create(serverConfig, executor);
|
||||
return new DefaultServerCacheManager(factory, beanOptions, queryOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -335,11 +335,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
if (encryptKeyManager != null) {
|
||||
encryptKeyManager.initialise();
|
||||
}
|
||||
List<BeanDescriptor<?>> list = beanDescriptorManager.getBeanDescriptorList();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
list.get(i).cacheInitialise();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1026,7 +1021,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
* Try to get the object out of the persistence context.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T findIdCheckPersistenceContextAndCache(Transaction transaction, SpiQuery<T> query) {
|
||||
private <T> T findIdCheckPersistenceContextAndCache(Transaction transaction, SpiQuery<T> query, Object id) {
|
||||
|
||||
SpiTransaction t = (SpiTransaction) transaction;
|
||||
if (t == null) {
|
||||
@@ -1034,13 +1029,14 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
BeanDescriptor<T> desc = query.getBeanDescriptor();
|
||||
id = desc.convertId(id);
|
||||
|
||||
PersistenceContext pc = null;
|
||||
if (t != null && useTransactionPersistenceContext(query)) {
|
||||
// first look in the transaction scoped persistence context
|
||||
pc = t.getPersistenceContext();
|
||||
if (pc != null) {
|
||||
WithOption o = desc.contextGetWithOption(pc, query.getId());
|
||||
WithOption o = desc.contextGetWithOption(pc, id);
|
||||
if (o != null) {
|
||||
if (o.isDeleted()) {
|
||||
// Bean was previously deleted in the same transaction / persistence context
|
||||
@@ -1057,7 +1053,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
// Hit the L2 bean cache
|
||||
return desc.cacheBeanGet(query, pc);
|
||||
return desc.cacheBeanGet(id, query.isReadOnly(), pc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1083,7 +1079,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
if (SpiQuery.Mode.NORMAL.equals(spiQuery.getMode()) && !spiQuery.isLoadBeanCache()) {
|
||||
// See if we can skip doing the fetch completely by getting the bean from the
|
||||
// persistence context or the bean cache
|
||||
T bean = findIdCheckPersistenceContextAndCache(t, spiQuery);
|
||||
T bean = findIdCheckPersistenceContextAndCache(t, spiQuery, spiQuery.getId());
|
||||
if (bean != null) {
|
||||
return bean;
|
||||
}
|
||||
@@ -1104,19 +1100,21 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
|
||||
public <T> T findUnique(Query<T> query, Transaction t) {
|
||||
|
||||
// actually a find by Id type of query...
|
||||
// ... perhaps with joins and cache hints
|
||||
Object id = query.getId();
|
||||
if (id != null) {
|
||||
// actually a find by Id query
|
||||
return findId(query, t);
|
||||
}
|
||||
|
||||
SpiQuery<T> spiQuery = (SpiQuery<T>) query;
|
||||
BeanDescriptor<T> desc = spiQuery.getBeanDescriptor();
|
||||
|
||||
T bean = desc.cacheNaturalKeyLookup(spiQuery, (SpiTransaction) t);
|
||||
if (bean != null) {
|
||||
return bean;
|
||||
id = desc.cacheNaturalKeyIdLookup(spiQuery);
|
||||
if (id != null) {
|
||||
T bean = findIdCheckPersistenceContextAndCache(t, spiQuery, id);
|
||||
if (bean != null) {
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
// a query that is expected to return either 0 or 1 rows
|
||||
@@ -2025,16 +2023,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
return beanDescriptorManager.getBeanDescriptorByClassName(beanClassName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initQueryCache(String key) {
|
||||
BeanDescriptor<?> desc = getBeanDescriptorById(key);
|
||||
if (desc != null) {
|
||||
desc.queryCacheInit();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Another server in the cluster sent this event so that we can inform local
|
||||
* BeanListeners of inserts updates and deletes that occurred remotely (on
|
||||
|
||||
@@ -548,7 +548,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
* Create and return a new reference bean matching this beans Id value.
|
||||
*/
|
||||
public T createReference() {
|
||||
return beanDescriptor.createReference(Boolean.FALSE, getBeanId());
|
||||
return beanDescriptor.createReference(Boolean.FALSE, getBeanId(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,7 +46,7 @@ class AssocOneHelpRefInherit extends AssocOneHelp {
|
||||
|
||||
// check transaction context to see if it already exists
|
||||
PersistenceContext pc = ctx.getPersistenceContext();
|
||||
BeanDescriptor<?> desc = rowInheritInfo.getBeanDescriptor();
|
||||
BeanDescriptor<?> desc = rowInheritInfo.desc();
|
||||
Object existing = desc.contextGet(pc, id);
|
||||
if (existing != null) {
|
||||
return existing;
|
||||
|
||||
@@ -39,7 +39,6 @@ import com.avaje.ebeaninternal.api.CQueryPlanKey;
|
||||
import com.avaje.ebeaninternal.api.LoadContext;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery;
|
||||
import com.avaje.ebeaninternal.api.SpiTransaction;
|
||||
import com.avaje.ebeaninternal.api.SpiUpdatePlan;
|
||||
import com.avaje.ebeaninternal.api.TransactionEventTable.TableIUD;
|
||||
import com.avaje.ebeaninternal.server.cache.CacheChangeSet;
|
||||
@@ -723,7 +722,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
propertiesMany[i].initialisePostTarget();
|
||||
}
|
||||
if (inheritInfo != null && !inheritInfo.isRoot()) {
|
||||
docStoreAdapter = (DocStoreBeanAdapter<T>)inheritInfo.getRoot().getBeanDescriptor().docStoreAdapter();
|
||||
docStoreAdapter = (DocStoreBeanAdapter<T>)inheritInfo.getRoot().desc().docStoreAdapter();
|
||||
}
|
||||
docMapping = docStoreAdapter.createDocMapping();
|
||||
docStoreAdapter.registerPaths();
|
||||
@@ -803,13 +802,6 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
return new BeanChange(getBaseTable(), id, changeType, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the cache once the server has started.
|
||||
*/
|
||||
public void cacheInitialise() {
|
||||
cacheHelp.initialise();
|
||||
}
|
||||
|
||||
public SqlUpdate deleteById(Object id, List<Object> idList, boolean softDelete) {
|
||||
if (id != null) {
|
||||
return deleteById(id, softDelete);
|
||||
@@ -996,7 +988,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
*/
|
||||
public BeanType<?> root() {
|
||||
if (inheritInfo != null && !inheritInfo.isRoot()) {
|
||||
return inheritInfo.getRoot().getBeanDescriptor();
|
||||
return inheritInfo.getRoot().desc();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -1046,13 +1038,6 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
return draftDirty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bean caching on or off.
|
||||
*/
|
||||
public void setUseCache(boolean useCache) {
|
||||
cacheHelp.setUseCache(useCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if there is currently bean caching for this type of bean.
|
||||
*/
|
||||
@@ -1082,10 +1067,6 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
return cacheHelp.isCacheNotify();
|
||||
}
|
||||
|
||||
public void queryCacheInit() {
|
||||
cacheHelp.queryCacheInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the query cache.
|
||||
*/
|
||||
@@ -1153,22 +1134,22 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
/**
|
||||
* Load the embedded bean (taking into account inheritance).
|
||||
*/
|
||||
public EntityBean cacheEmbeddedBeanLoad(CachedBeanData data) {
|
||||
return cacheHelp.embeddedBeanLoad(data);
|
||||
public EntityBean cacheEmbeddedBeanLoad(CachedBeanData data, PersistenceContext context) {
|
||||
return cacheHelp.embeddedBeanLoad(data, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the embedded bean as the root type.
|
||||
*/
|
||||
EntityBean cacheEmbeddedBeanLoadDirect(CachedBeanData data) {
|
||||
return cacheHelp.embeddedBeanLoadDirect(data);
|
||||
EntityBean cacheEmbeddedBeanLoadDirect(CachedBeanData data, PersistenceContext context) {
|
||||
return cacheHelp.embeddedBeanLoadDirect(data, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the entity bean as the correct bean type.
|
||||
*/
|
||||
EntityBean cacheBeanLoadDirect(Object id, Boolean readOnly, CachedBeanData data) {
|
||||
return cacheHelp.loadBeanDirect(id, readOnly, data);
|
||||
EntityBean cacheBeanLoadDirect(Object id, Boolean readOnly, CachedBeanData data, PersistenceContext context) {
|
||||
return cacheHelp.loadBeanDirect(id, readOnly, data, context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1195,8 +1176,8 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
/**
|
||||
* Return a bean from the bean cache (or null).
|
||||
*/
|
||||
public T cacheBeanGet(SpiQuery<T> query, PersistenceContext context) {
|
||||
return cacheHelp.beanCacheGet(query, context);
|
||||
public T cacheBeanGet(Object id, Boolean readOnly, PersistenceContext context) {
|
||||
return cacheHelp.beanCacheGet(id, readOnly, context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1209,24 +1190,24 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
/**
|
||||
* Returns true if it managed to populate/load the bean from the cache.
|
||||
*/
|
||||
public boolean cacheBeanLoad(EntityBean bean, EntityBeanIntercept ebi, Object id) {
|
||||
return cacheHelp.beanCacheLoad(bean, ebi, id);
|
||||
public boolean cacheBeanLoad(EntityBean bean, EntityBeanIntercept ebi, Object id, PersistenceContext context) {
|
||||
return cacheHelp.beanCacheLoad(bean, ebi, id, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if it managed to populate/load the bean from the cache.
|
||||
*/
|
||||
public boolean cacheBeanLoad(EntityBeanIntercept ebi) {
|
||||
public boolean cacheBeanLoad(EntityBeanIntercept ebi, PersistenceContext context) {
|
||||
EntityBean bean = ebi.getOwner();
|
||||
Object id = getId(bean);
|
||||
return cacheBeanLoad(bean, ebi, id);
|
||||
return cacheBeanLoad(bean, ebi, id, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to hit the cache using the natural key.
|
||||
*/
|
||||
public T cacheNaturalKeyLookup(SpiQuery<T> query, SpiTransaction t) {
|
||||
return cacheHelp.naturalKeyLookup(query, t);
|
||||
public Object cacheNaturalKeyIdLookup(SpiQuery<T> query) {
|
||||
return cacheHelp.naturalKeyIdLookup(query);
|
||||
}
|
||||
|
||||
public void cacheNaturalKeyPut(Object id, Object newKey) {
|
||||
@@ -1604,7 +1585,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
* Create a reference bean based on the id.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T createReference(Boolean readOnly, Object id) {
|
||||
public T createReference(Boolean readOnly, Object id, PersistenceContext pc) {
|
||||
|
||||
if (cacheSharableBeans && !Boolean.FALSE.equals(readOnly)) {
|
||||
CachedBeanData d = cacheHelp.beanCacheGetData(id);
|
||||
@@ -1620,7 +1601,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
}
|
||||
try {
|
||||
EntityBean eb = createEntityBean();
|
||||
convertSetId(id, eb);
|
||||
id = convertSetId(id, eb);
|
||||
|
||||
EntityBeanIntercept ebi = eb._ebean_getIntercept();
|
||||
ebi.setBeanLoader(ebeanServer);
|
||||
@@ -1628,6 +1609,10 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
if (Boolean.TRUE == readOnly) {
|
||||
ebi.setReadOnly(true);
|
||||
}
|
||||
if (pc != null) {
|
||||
contextPut(pc, id, eb);
|
||||
ebi.setPersistenceContext(pc);
|
||||
}
|
||||
|
||||
return (T) eb;
|
||||
|
||||
@@ -1696,7 +1681,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
return unidirectional;
|
||||
}
|
||||
if (inheritInfo != null && !inheritInfo.isRoot()) {
|
||||
return inheritInfo.getParent().getBeanDescriptor().getUnidirectional();
|
||||
return inheritInfo.getParent().desc().getUnidirectional();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -1792,11 +1777,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
* Create a reference bean and put it in the persistence context (and return it).
|
||||
*/
|
||||
public Object contextRef(PersistenceContext pc, Boolean readOnly, Object id) {
|
||||
Object ref = createReference(readOnly, id);
|
||||
if (pc != null) {
|
||||
contextPut(pc, id, ref);
|
||||
}
|
||||
return ref;
|
||||
return createReference(readOnly, id, pc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1945,19 +1926,35 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
if (lazyLoadProperty == -1) {
|
||||
return false;
|
||||
}
|
||||
String lazyLoadPropertyName = ebi.getProperty(lazyLoadProperty);
|
||||
BeanProperty lazyLoadBeanProp = getBeanProperty(lazyLoadPropertyName);
|
||||
|
||||
if (inheritInfo != null) {
|
||||
return descOf(ebi.getOwner().getClass()).lazyLoadMany(ebi, lazyLoadProperty);
|
||||
}
|
||||
return lazyLoadMany(ebi, lazyLoadProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for lazy loading of many property.
|
||||
*/
|
||||
private boolean lazyLoadMany(EntityBeanIntercept ebi, int lazyLoadProperty) {
|
||||
|
||||
BeanProperty lazyLoadBeanProp = propertiesIndex[lazyLoadProperty];
|
||||
if (lazyLoadBeanProp instanceof BeanPropertyAssocMany<?>) {
|
||||
BeanPropertyAssocMany<?> manyProp = (BeanPropertyAssocMany<?>) lazyLoadBeanProp;
|
||||
manyProp.createReference(ebi.getOwner());
|
||||
ebi.setLoadedLazy();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the correct BeanDescriptor based on the bean class type.
|
||||
*/
|
||||
BeanDescriptor<?> descOf(Class<?> type) {
|
||||
return inheritInfo.readType(type).desc();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Comparator for local sorting of lists.
|
||||
*
|
||||
@@ -2176,8 +2173,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public T createBeanUsingDisc(Object discValue) {
|
||||
InheritInfo type = inheritInfo.getType(discValue.toString());
|
||||
return (T)type.getBeanDescriptor().createBean();
|
||||
return (T) inheritInfo.getType(discValue.toString()).desc().createBean();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,7 +7,6 @@ import com.avaje.ebean.bean.PersistenceContext;
|
||||
import com.avaje.ebean.cache.ServerCache;
|
||||
import com.avaje.ebean.cache.ServerCacheManager;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery;
|
||||
import com.avaje.ebeaninternal.api.SpiTransaction;
|
||||
import com.avaje.ebeaninternal.api.TransactionEventTable.TableIUD;
|
||||
import com.avaje.ebeaninternal.server.cache.CacheChangeSet;
|
||||
import com.avaje.ebeaninternal.server.cache.CachedBeanData;
|
||||
@@ -57,9 +56,9 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
private final BeanPropertyAssocOne<?>[] propertiesOneImported;
|
||||
private final String naturalKeyProperty;
|
||||
|
||||
private ServerCache beanCache;
|
||||
private ServerCache naturalKeyCache;
|
||||
private volatile ServerCache queryCache;
|
||||
private final ServerCache beanCache;
|
||||
private final ServerCache naturalKeyCache;
|
||||
private final ServerCache queryCache;
|
||||
|
||||
BeanDescriptorCacheHelp(BeanDescriptor<T> desc, ServerCacheManager cacheManager, CacheOptions cacheOptions,
|
||||
boolean cacheSharableBeans, BeanPropertyAssocOne<?>[] propertiesOneImported) {
|
||||
@@ -72,26 +71,23 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
this.cacheSharableBeans = cacheSharableBeans;
|
||||
this.propertiesOneImported = propertiesOneImported;
|
||||
this.naturalKeyProperty = cacheOptions.getNaturalKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the cache once the server has started.
|
||||
*/
|
||||
public void initialise() {
|
||||
if (cacheOptions.isUseNaturalKeyCache()) {
|
||||
this.naturalKeyCache = cacheManager.getNaturalKeyCache(beanType);
|
||||
}
|
||||
if (cacheOptions.isUseCache()) {
|
||||
this.beanCache = cacheManager.getBeanCache(beanType);
|
||||
}
|
||||
}
|
||||
|
||||
public void setUseCache(boolean useCache) {
|
||||
if (useCache) {
|
||||
getBeanCache();
|
||||
if (!cacheOptions.isEnableQueryCache()) {
|
||||
this.queryCache = null;
|
||||
} else {
|
||||
beanCacheClear();
|
||||
beanCache = null;
|
||||
this.queryCache = cacheManager.getQueryCache(beanType);
|
||||
}
|
||||
|
||||
if (cacheOptions.isEnableBeanCache()) {
|
||||
this.beanCache = cacheManager.getBeanCache(beanType);
|
||||
if (cacheOptions.getNaturalKey() != null) {
|
||||
this.naturalKeyCache = cacheManager.getNaturalKeyCache(beanType);
|
||||
} else {
|
||||
this.naturalKeyCache = null;
|
||||
}
|
||||
} else {
|
||||
this.beanCache = null;
|
||||
this.naturalKeyCache = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,17 +125,6 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
return cacheOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the query cache if required
|
||||
* (as some node in the cluster already has it).
|
||||
*/
|
||||
void queryCacheInit() {
|
||||
if (queryCache == null) {
|
||||
queryLog.debug(" init {}", cacheName);
|
||||
queryCache = cacheManager.getQueryCache(beanType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the query cache.
|
||||
*/
|
||||
@@ -167,18 +152,17 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
@SuppressWarnings("unchecked")
|
||||
BeanCollection<T> queryCacheGet(Object id) {
|
||||
if (queryCache == null) {
|
||||
return null;
|
||||
} else {
|
||||
BeanCollection<T> list = (BeanCollection<T>) queryCache.get(id);
|
||||
if (queryLog.isDebugEnabled()) {
|
||||
if (list == null) {
|
||||
queryLog.debug(" GET {}({}) - cache miss", cacheName, id);
|
||||
} else {
|
||||
queryLog.debug(" GET {}({}) - hit", cacheName, id);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
throw new IllegalStateException("No query cache enabled on " + desc + ". Need explicit @Cache(enableQueryCache=true)");
|
||||
}
|
||||
BeanCollection<T> list = (BeanCollection<T>) queryCache.get(id);
|
||||
if (queryLog.isDebugEnabled()) {
|
||||
if (list == null) {
|
||||
queryLog.debug(" GET {}({}) - cache miss", cacheName, id);
|
||||
} else {
|
||||
queryLog.debug(" GET {}({}) - hit", cacheName, id);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,7 +170,7 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
*/
|
||||
void queryCachePut(Object id, BeanCollection<T> query) {
|
||||
if (queryCache == null) {
|
||||
queryCache = cacheManager.getQueryCache(beanType);
|
||||
throw new IllegalStateException("No query cache enabled on " + desc + ". Need explicit @Cache(enableQueryCache=true)");
|
||||
}
|
||||
if (queryLog.isDebugEnabled()) {
|
||||
queryLog.debug(" PUT {}({})", cacheName, id);
|
||||
@@ -197,8 +181,8 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
|
||||
void manyPropRemove(String propertyName, Object parentId) {
|
||||
ServerCache collectionIdsCache = cacheManager.getCollectionIdsCache(beanType, propertyName);
|
||||
if (manyLog.isDebugEnabled()) {
|
||||
manyLog.debug(" REMOVE {}({}).{}", cacheName, parentId, propertyName);
|
||||
if (manyLog.isTraceEnabled()) {
|
||||
manyLog.trace(" REMOVE {}({}).{}", cacheName, parentId, propertyName);
|
||||
}
|
||||
collectionIdsCache.remove(parentId);
|
||||
}
|
||||
@@ -248,12 +232,8 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
bc.checkEmptyLazyLoad();
|
||||
for (int i = 0; i < idList.size(); i++) {
|
||||
Object id = idList.get(i);
|
||||
Object refBean = targetDescriptor.createReference(readOnly, id);
|
||||
EntityBeanIntercept refEbi = ((EntityBean) refBean)._ebean_getIntercept();
|
||||
|
||||
Object refBean = targetDescriptor.createReference(readOnly, id, persistenceContext);
|
||||
many.add(bc, (EntityBean) refBean);
|
||||
targetDescriptor.contextPut(persistenceContext, id, refBean);
|
||||
refEbi.setPersistenceContext(persistenceContext);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -291,46 +271,26 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
/**
|
||||
* Find the bean using the natural key lookup if available.
|
||||
*/
|
||||
T naturalKeyLookup(SpiQuery<T> query, SpiTransaction t) {
|
||||
|
||||
Object naturalKeyIdLookup(SpiQuery<T> query) {
|
||||
|
||||
if (!isNaturalKeyCaching(query.isUseBeanCache())) {
|
||||
// no natural key caching for this query
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// check if it is a find by unique id (using the natural key)
|
||||
NaturalKeyBindParam keyBindParam = query.getNaturalKeyBindParam();
|
||||
if (keyBindParam == null || !isNaturalKey(keyBindParam.getName())) {
|
||||
// query is not appropriate
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// try to lookup the id using the natural key
|
||||
Object id = naturalKeyCache.get(keyBindParam.getValue());
|
||||
if (natLog.isTraceEnabled()) {
|
||||
if (natLog.isTraceEnabled() && id != null) {
|
||||
natLog.trace(" LOOKUP {}({}) - id:{}", cacheName, keyBindParam.getValue(), id);
|
||||
}
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// try looking up into the bean cache using the id
|
||||
T cacheBean = beanCacheGetInternal(id, query.isReadOnly());
|
||||
if (cacheBean != null) {
|
||||
setupContext(cacheBean, getPersistenceContext(t));
|
||||
}
|
||||
return cacheBean;
|
||||
}
|
||||
|
||||
private PersistenceContext getPersistenceContext(SpiTransaction t) {
|
||||
PersistenceContext context = null;
|
||||
if (t == null) {
|
||||
t = desc.getEbeanServer().getCurrentServerTransaction();
|
||||
}
|
||||
if (t != null) {
|
||||
context = t.getPersistenceContext();
|
||||
}
|
||||
return context;
|
||||
return id;
|
||||
}
|
||||
|
||||
private boolean isNaturalKeyCaching(Boolean queryUseCache) {
|
||||
@@ -363,7 +323,7 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
*/
|
||||
private ServerCache getBeanCache() {
|
||||
if (beanCache == null) {
|
||||
beanCache = cacheManager.getBeanCache(beanType);
|
||||
throw new IllegalStateException("No bean cache enabled for " + desc + ". Add the @Cache annotation.");
|
||||
}
|
||||
return beanCache;
|
||||
}
|
||||
@@ -390,7 +350,7 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
void beanCachePut(EntityBean bean) {
|
||||
|
||||
if (desc.inheritInfo != null) {
|
||||
desc.inheritInfo.readType(bean.getClass()).getBeanDescriptor().cacheBeanPutDirect(bean);
|
||||
desc.descOf(bean.getClass()).cacheBeanPutDirect(bean);
|
||||
} else {
|
||||
beanCachePutDirect(bean);
|
||||
}
|
||||
@@ -424,9 +384,8 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
return (CachedBeanData) getBeanCache().get(id);
|
||||
}
|
||||
|
||||
T beanCacheGet(SpiQuery<T> query, PersistenceContext context) {
|
||||
Object id = desc.convertId(query.getId());
|
||||
T bean = beanCacheGetInternal(id, query.isReadOnly());
|
||||
T beanCacheGet(Object id, Boolean readOnly, PersistenceContext context) {
|
||||
T bean = beanCacheGetInternal(id, readOnly, context);
|
||||
if (bean != null) {
|
||||
setupContext(bean, context);
|
||||
}
|
||||
@@ -437,7 +396,7 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
* Return a bean from the bean cache.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private T beanCacheGetInternal(Object id, Boolean readOnly) {
|
||||
private T beanCacheGetInternal(Object id, Boolean readOnly, PersistenceContext context) {
|
||||
|
||||
CachedBeanData data = (CachedBeanData) getBeanCache().get(id);
|
||||
if (data == null) {
|
||||
@@ -459,19 +418,19 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
}
|
||||
}
|
||||
|
||||
return (T)loadBean(id, readOnly, data);
|
||||
return (T)loadBean(id, readOnly, data, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the entity bean taking into account inheritance.
|
||||
*/
|
||||
private EntityBean loadBean(Object id, Boolean readOnly, CachedBeanData data) {
|
||||
private EntityBean loadBean(Object id, Boolean readOnly, CachedBeanData data, PersistenceContext context) {
|
||||
|
||||
String discValue = data.getDiscValue();
|
||||
if (discValue == null) {
|
||||
return loadBeanDirect(id, readOnly, data);
|
||||
return loadBeanDirect(id, readOnly, data, context);
|
||||
} else {
|
||||
return rootDescriptor(discValue).cacheBeanLoadDirect(id, readOnly, data);
|
||||
return rootDescriptor(discValue).cacheBeanLoadDirect(id, readOnly, data, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,24 +438,32 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
* Return the root BeanDescriptor for inheritance.
|
||||
*/
|
||||
private BeanDescriptor<?> rootDescriptor(String discValue) {
|
||||
InheritInfo inheritInfo = desc.inheritInfo.readType(discValue);
|
||||
return inheritInfo.getBeanDescriptor();
|
||||
return desc.inheritInfo.readType(discValue).desc();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the entity bean from cache data given this is the root bean type.
|
||||
*/
|
||||
EntityBean loadBeanDirect(Object id, Boolean readOnly, CachedBeanData data) {
|
||||
EntityBean loadBeanDirect(Object id, Boolean readOnly, CachedBeanData data, PersistenceContext context) {
|
||||
|
||||
if (context == null) {
|
||||
context = new DefaultPersistenceContext();
|
||||
}
|
||||
|
||||
EntityBean bean = desc.createEntityBean();
|
||||
desc.convertSetId(id, bean);
|
||||
CachedBeanDataToBean.load(desc, bean, data);
|
||||
id = desc.convertSetId(id, bean);
|
||||
CachedBeanDataToBean.load(desc, bean, data, context);
|
||||
|
||||
EntityBeanIntercept ebi = bean._ebean_getIntercept();
|
||||
|
||||
// Not using a loadContext for beans coming out of L2 cache
|
||||
// so that means no batch lazy loading for these beans
|
||||
ebi.setBeanLoader(desc.getEbeanServer());
|
||||
if (Boolean.TRUE.equals(readOnly)) {
|
||||
ebi.setReadOnly(true);
|
||||
}
|
||||
ebi.setPersistenceContext(context);
|
||||
desc.contextPut(context, id, bean);
|
||||
|
||||
if (beanLog.isTraceEnabled()) {
|
||||
beanLog.trace(" GET {}({}) - hit", cacheName, id);
|
||||
@@ -510,22 +477,22 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
/**
|
||||
* Load the embedded bean checking for inheritance.
|
||||
*/
|
||||
EntityBean embeddedBeanLoad(CachedBeanData data) {
|
||||
EntityBean embeddedBeanLoad(CachedBeanData data, PersistenceContext context) {
|
||||
|
||||
String discValue = data.getDiscValue();
|
||||
if (discValue == null) {
|
||||
return embeddedBeanLoadDirect(data);
|
||||
return embeddedBeanLoadDirect(data, context);
|
||||
} else {
|
||||
return rootDescriptor(discValue).cacheEmbeddedBeanLoadDirect(data);
|
||||
return rootDescriptor(discValue).cacheEmbeddedBeanLoadDirect(data, context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the embedded bean given this is the bean type.
|
||||
*/
|
||||
EntityBean embeddedBeanLoadDirect(CachedBeanData data) {
|
||||
EntityBean embeddedBeanLoadDirect(CachedBeanData data, PersistenceContext context) {
|
||||
EntityBean bean = desc.createEntityBean();
|
||||
CachedBeanDataToBean.load(desc, bean, data);
|
||||
CachedBeanDataToBean.load(desc, bean, data, context);
|
||||
return bean;
|
||||
}
|
||||
|
||||
@@ -547,7 +514,7 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
/**
|
||||
* Returns true if it managed to populate/load the bean from the cache.
|
||||
*/
|
||||
boolean beanCacheLoad(EntityBean bean, EntityBeanIntercept ebi, Object id) {
|
||||
boolean beanCacheLoad(EntityBean bean, EntityBeanIntercept ebi, Object id, PersistenceContext context) {
|
||||
|
||||
CachedBeanData cacheData = (CachedBeanData) getBeanCache().get(id);
|
||||
if (cacheData == null) {
|
||||
@@ -559,12 +526,12 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
int lazyLoadProperty = ebi.getLazyLoadPropertyIndex();
|
||||
if (lazyLoadProperty > -1 && !cacheData.isLoaded(ebi.getLazyLoadProperty())) {
|
||||
if (beanLog.isTraceEnabled()) {
|
||||
beanLog.trace(" LOAD {}({}) - cache miss on property", cacheName, id);
|
||||
beanLog.trace(" LOAD {}({}) - cache miss on property({})", cacheName, id, ebi.getLazyLoadProperty());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
CachedBeanDataToBean.load(desc, bean, cacheData);
|
||||
CachedBeanDataToBean.load(desc, bean, cacheData, context);
|
||||
if (beanLog.isDebugEnabled()) {
|
||||
beanLog.debug(" LOAD {}({}) - hit", cacheName, id);
|
||||
}
|
||||
@@ -650,10 +617,6 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCachedDataTooOld(CachedBeanData existingData) {
|
||||
return cacheOptions.isTooOldInMillis(System.currentTimeMillis() - existingData.getWhenCreated());
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate parts of cache due to SqlUpdate or external modification etc.
|
||||
*/
|
||||
@@ -680,28 +643,21 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
ServerCache cache = getBeanCache();
|
||||
CachedBeanData existingData = (CachedBeanData) cache.get(id);
|
||||
if (existingData != null) {
|
||||
if (isCachedDataTooOld(existingData)) {
|
||||
long currentVersion = existingData.getVersion();
|
||||
if (version > 0 && version < currentVersion) {
|
||||
if (beanLog.isDebugEnabled()) {
|
||||
beanLog.debug(" REMOVE {}({}) - entry too old", cacheName, id);
|
||||
beanLog.debug(" REMOVE {}({}) - version conflict old:{} new:{}", cacheName, id, currentVersion, version);
|
||||
}
|
||||
cache.remove(id);
|
||||
} else {
|
||||
long currentVersion = existingData.getVersion();
|
||||
if (version > 0 && version < currentVersion) {
|
||||
if (beanLog.isDebugEnabled()) {
|
||||
beanLog.debug(" REMOVE {}({}) - version conflict old:{} new:{}", cacheName, id, currentVersion, version);
|
||||
}
|
||||
cache.remove(id);
|
||||
} else {
|
||||
if (version == 0) {
|
||||
version = currentVersion;
|
||||
}
|
||||
CachedBeanData newData = existingData.update(changes, version);
|
||||
if (beanLog.isDebugEnabled()) {
|
||||
beanLog.debug(" UPDATE {}({}) changes:{}", cacheName, id, changes);
|
||||
}
|
||||
cache.put(id, newData);
|
||||
if (version == 0) {
|
||||
version = currentVersion;
|
||||
}
|
||||
CachedBeanData newData = existingData.update(changes, version);
|
||||
if (beanLog.isDebugEnabled()) {
|
||||
beanLog.debug(" UPDATE {}({}) changes:{}", cacheName, id, changes);
|
||||
}
|
||||
cache.put(id, newData);
|
||||
}
|
||||
|
||||
if (updateNaturalKey) {
|
||||
|
||||
@@ -37,8 +37,7 @@ public class BeanDescriptorJsonHelp<T> {
|
||||
String discColumn = localInheritInfo.getDiscriminatorColumn();
|
||||
writeJson.gen().writeStringField(discColumn, discValue);
|
||||
|
||||
BeanDescriptor<?> localDescriptor = localInheritInfo.getBeanDescriptor();
|
||||
localDescriptor.jsonWriteProperties(writeJson, bean);
|
||||
localInheritInfo.desc().jsonWriteProperties(writeJson, bean);
|
||||
}
|
||||
|
||||
writeJson.writeEndObject();
|
||||
@@ -54,13 +53,9 @@ public class BeanDescriptorJsonHelp<T> {
|
||||
|
||||
if (inheritInfo == null) {
|
||||
jsonWriteDirtyProperties(writeJson, bean, dirtyProps);
|
||||
|
||||
} else {
|
||||
InheritInfo localInheritInfo = inheritInfo.readType(bean.getClass());
|
||||
BeanDescriptor<?> localDescriptor = localInheritInfo.getBeanDescriptor();
|
||||
localDescriptor.jsonWriteDirtyProperties(writeJson, bean, dirtyProps);
|
||||
desc.descOf(bean.getClass()).jsonWriteDirtyProperties(writeJson, bean, dirtyProps);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void jsonWriteDirtyProperties(WriteJson writeJson, EntityBean bean, boolean[] dirtyProps) throws IOException {
|
||||
@@ -120,11 +115,7 @@ public class BeanDescriptorJsonHelp<T> {
|
||||
}
|
||||
|
||||
String discValue = parser.nextTextValue();
|
||||
|
||||
// determine the sub type for this particular json object
|
||||
InheritInfo localInheritInfo = inheritInfo.readType(discValue);
|
||||
BeanDescriptor<?> localDescriptor = localInheritInfo.getBeanDescriptor();
|
||||
return (T) localDescriptor.jsonReadObject(jsonRead, path);
|
||||
return (T) inheritInfo.readType(discValue).desc().jsonReadObject(jsonRead, path);
|
||||
}
|
||||
|
||||
protected T jsonReadObject(ReadJson readJson, String path) throws IOException {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.server.deploy;
|
||||
|
||||
import com.avaje.ebean.ValuePair;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.bean.PersistenceContext;
|
||||
import com.avaje.ebean.config.EncryptKey;
|
||||
import com.avaje.ebean.config.dbplatform.DbEncryptFunction;
|
||||
import com.avaje.ebean.config.dbplatform.DbType;
|
||||
@@ -764,7 +765,7 @@ public class BeanProperty implements ElPropertyValue, Property {
|
||||
* This uses parse() as per the comment in getCacheDataValue().
|
||||
* </p>
|
||||
*/
|
||||
public void setCacheDataValue(EntityBean bean, Object cacheData) {
|
||||
public void setCacheDataValue(EntityBean bean, Object cacheData, PersistenceContext context) {
|
||||
if (cacheData instanceof String) {
|
||||
// parse back from string to support optimisation of java object serialisation
|
||||
cacheData = scalarType.parse((String)cacheData);
|
||||
|
||||
@@ -1022,7 +1022,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
if (isManyToMany()) {
|
||||
if (liveBean == null) {
|
||||
// add new relationship (Map not allowed here)
|
||||
liveVal.addBean(targetDescriptor.createReference(Boolean.FALSE, id));
|
||||
liveVal.addBean(targetDescriptor.createReference(Boolean.FALSE, id, null));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.avaje.ebean.SqlUpdate;
|
||||
import com.avaje.ebean.Transaction;
|
||||
import com.avaje.ebean.ValuePair;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.bean.PersistenceContext;
|
||||
import com.avaje.ebeaninternal.server.cache.CacheChangeSet;
|
||||
import com.avaje.ebeaninternal.server.cache.CachedBeanData;
|
||||
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
@@ -399,17 +400,22 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCacheDataValue(EntityBean bean, Object cacheData) {
|
||||
public void setCacheDataValue(EntityBean bean, Object cacheData, PersistenceContext context) {
|
||||
if (cacheData == null) {
|
||||
setValue(bean, null);
|
||||
} else {
|
||||
if (embedded) {
|
||||
setValue(bean, targetDescriptor.cacheEmbeddedBeanLoad((CachedBeanData) cacheData));
|
||||
setValue(bean, targetDescriptor.cacheEmbeddedBeanLoad((CachedBeanData) cacheData, context));
|
||||
} else {
|
||||
if (cacheData instanceof String) {
|
||||
cacheData = targetDescriptor.getIdProperty().scalarType.parse((String)cacheData);
|
||||
}
|
||||
setValue(bean, targetDescriptor.createReference(Boolean.FALSE, cacheData));
|
||||
// cacheData is the id value, maybe already in persistence context
|
||||
Object assocBean = targetDescriptor.contextGet(context, cacheData);
|
||||
if (assocBean == null) {
|
||||
assocBean = targetDescriptor.createReference(Boolean.FALSE, cacheData, context);
|
||||
}
|
||||
setValue(bean, assocBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ public class InheritInfo {
|
||||
/**
|
||||
* Return the associated BeanDescriptor for this node.
|
||||
*/
|
||||
public BeanDescriptor<?> getBeanDescriptor() {
|
||||
public BeanDescriptor<?> desc() {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@@ -161,10 +161,8 @@ public class InheritInfo {
|
||||
|
||||
for (int i = 0, x = children.size(); i < x; i++) {
|
||||
InheritInfo childInfo = children.get(i);
|
||||
|
||||
// recursively search this child bean descriptor
|
||||
prop = childInfo.getBeanDescriptor().findBeanProperty(propertyName);
|
||||
|
||||
prop = childInfo.desc().findBeanProperty(propertyName);
|
||||
if (prop != null) {
|
||||
return prop;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.deploy.meta;
|
||||
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
import com.avaje.ebeaninternal.api.ConcurrencyMode;
|
||||
import com.avaje.ebean.annotation.DocStore;
|
||||
import com.avaje.ebean.annotation.DocStoreMode;
|
||||
@@ -153,7 +154,7 @@ public class DeployBeanDescriptor<T> {
|
||||
private final List<BeanQueryAdapter> queryAdapters = new ArrayList<BeanQueryAdapter>();
|
||||
private final List<BeanPostLoad> postLoaders = new ArrayList<BeanPostLoad>();
|
||||
|
||||
private final CacheOptions cacheOptions = new CacheOptions();
|
||||
private CacheOptions cacheOptions = CacheOptions.NO_CACHING;
|
||||
|
||||
/**
|
||||
* If set overrides the find implementation. Server side only.
|
||||
@@ -442,6 +443,24 @@ public class DeployBeanDescriptor<T> {
|
||||
this.inheritInfo = inheritInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable L2 bean and query caching based on Cache annotation.
|
||||
*/
|
||||
public void setCache(Cache cache) {
|
||||
|
||||
String naturalKey = null;
|
||||
if (cache.naturalKey().length() > 0) {
|
||||
// find the property and mark as natural key property
|
||||
String propName = cache.naturalKey().trim();
|
||||
DeployBeanProperty beanProperty = getBeanProperty(propName);
|
||||
if (beanProperty != null) {
|
||||
beanProperty.setNaturalKey();
|
||||
naturalKey = propName;
|
||||
}
|
||||
}
|
||||
this.cacheOptions = new CacheOptions(cache, naturalKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the cache options.
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.deploy.parse;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.CacheBeanTuning;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
import com.avaje.ebean.annotation.DbComment;
|
||||
import com.avaje.ebean.annotation.DocStore;
|
||||
import com.avaje.ebean.annotation.Draftable;
|
||||
@@ -14,7 +13,6 @@ import com.avaje.ebean.annotation.ReadAudit;
|
||||
import com.avaje.ebean.annotation.UpdateMode;
|
||||
import com.avaje.ebean.annotation.View;
|
||||
import com.avaje.ebean.config.TableName;
|
||||
import com.avaje.ebeaninternal.server.core.CacheOptions;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor.EntityType;
|
||||
import com.avaje.ebeaninternal.server.deploy.CompoundUniqueConstraint;
|
||||
import com.avaje.ebeaninternal.server.deploy.DeployNamedQuery;
|
||||
@@ -202,34 +200,9 @@ public class AnnotationClass extends AnnotationParser {
|
||||
readNamedUpdate(namedUpdate);
|
||||
}
|
||||
|
||||
CacheStrategy cacheStrategy = cls.getAnnotation(CacheStrategy.class);
|
||||
CacheBeanTuning cacheBeanTuning = cls.getAnnotation(CacheBeanTuning.class);
|
||||
if (cacheStrategy != null || cacheBeanTuning != null) {
|
||||
readCacheStrategy(cacheStrategy, cacheBeanTuning);
|
||||
}
|
||||
}
|
||||
|
||||
private void readCacheStrategy(CacheStrategy cacheStrategy, CacheBeanTuning cacheBeanTuning) {
|
||||
|
||||
if (disableL2Cache) {
|
||||
return;
|
||||
}
|
||||
CacheOptions cacheOptions = descriptor.getCacheOptions();
|
||||
if (cacheBeanTuning != null) {
|
||||
cacheOptions.setMaxSecsToLive(cacheBeanTuning.maxSecsToLive());
|
||||
cacheOptions.setMaxIdleSecs(cacheBeanTuning.maxIdleSecs());
|
||||
}
|
||||
if (cacheStrategy != null) {
|
||||
cacheOptions.setUseCache(cacheStrategy.useBeanCache());
|
||||
cacheOptions.setReadOnly(cacheStrategy.readOnly());
|
||||
if (cacheStrategy.naturalKey().length() > 0) {
|
||||
String propName = cacheStrategy.naturalKey().trim();
|
||||
DeployBeanProperty beanProperty = descriptor.getBeanProperty(propName);
|
||||
if (beanProperty != null) {
|
||||
beanProperty.setNaturalKey();
|
||||
cacheOptions.setNaturalKey(propName);
|
||||
}
|
||||
}
|
||||
Cache cache = cls.getAnnotation(Cache.class);
|
||||
if (cache != null && !disableL2Cache) {
|
||||
descriptor.setCache(cache);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ public class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContex
|
||||
return;
|
||||
}
|
||||
|
||||
if (context.hitCache && context.desc.cacheBeanLoad(ebi)) {
|
||||
if (context.hitCache && context.desc.cacheBeanLoad(ebi, persistenceContext)) {
|
||||
// successfully hit the L2 cache so don't invoke DB lazy loading
|
||||
list.remove(ebi);
|
||||
return;
|
||||
@@ -185,7 +185,7 @@ public class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContex
|
||||
// check each of the beans in the batch to see if they are in the L2 cache.
|
||||
Iterator<EntityBeanIntercept> iterator = list.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (context.desc.cacheBeanLoad(iterator.next())) {
|
||||
if (context.desc.cacheBeanLoad(iterator.next(), persistenceContext)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1352,7 +1352,7 @@ public final class DefaultPersister implements Persister {
|
||||
// convert into a list of reference objects and perform delete by object
|
||||
List<Object> refList = new ArrayList<Object>(childIds.size());
|
||||
for (Object id : childIds) {
|
||||
refList.add(targetDesc.createReference(null, id));
|
||||
refList.add(targetDesc.createReference(null, id, null));
|
||||
}
|
||||
deleteList(refList, t, softDelete);
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@ public class SqlTreeNodeBean implements SqlTreeNode {
|
||||
localBean = localInfo.createEntityBean();
|
||||
localType = localInfo.getType();
|
||||
localIdBinder = localInfo.getIdBinder();
|
||||
localDesc = localInfo.getBeanDescriptor();
|
||||
localDesc = localInfo.desc();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@@ -2,9 +2,11 @@ package com.avaje.ebeaninternal.server.cache;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.bean.PersistenceContext;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import com.avaje.ebeaninternal.server.transaction.DefaultPersistenceContext;
|
||||
import com.avaje.tests.model.basic.Address;
|
||||
import com.avaje.tests.model.basic.Country;
|
||||
import com.avaje.tests.model.basic.Customer;
|
||||
@@ -50,7 +52,7 @@ public class CacheBeanDataTest extends BaseTestCase {
|
||||
|
||||
Customer newCustomer = new Customer();
|
||||
newCustomer.setId(c.getId());
|
||||
CachedBeanDataToBean.load(desc, (EntityBean) newCustomer, cacheData);
|
||||
CachedBeanDataToBean.load(desc, (EntityBean) newCustomer, cacheData, new DefaultPersistenceContext());
|
||||
|
||||
assertEquals(c.getId(), newCustomer.getId());
|
||||
assertEquals(c.getName(), newCustomer.getName());
|
||||
@@ -91,9 +93,11 @@ public class CacheBeanDataTest extends BaseTestCase {
|
||||
|
||||
CachedBeanData addressCacheData = (CachedBeanData) addressBeanProperty.getCacheDataValue((EntityBean) person);
|
||||
|
||||
PersistenceContext context = new DefaultPersistenceContext();
|
||||
|
||||
EPerson newPersonCheck = new EPerson();
|
||||
newPersonCheck.setId(98989L);
|
||||
addressBeanProperty.setCacheDataValue((EntityBean) newPersonCheck, addressCacheData);
|
||||
addressBeanProperty.setCacheDataValue((EntityBean) newPersonCheck, addressCacheData, context);
|
||||
|
||||
EAddress newAddress = newPersonCheck.getAddress();
|
||||
assertEquals(address.getStreet(), newAddress.getStreet());
|
||||
@@ -105,7 +109,7 @@ public class CacheBeanDataTest extends BaseTestCase {
|
||||
|
||||
assertNotNull(cacheData);
|
||||
|
||||
EPerson newPerson = (EPerson)desc.cacheEmbeddedBeanLoad(cacheData);
|
||||
EPerson newPerson = (EPerson)desc.cacheEmbeddedBeanLoad(cacheData, context);
|
||||
|
||||
assertNotNull(newPerson.getId());
|
||||
assertNotNull(newPerson.getName());
|
||||
|
||||
+2
-1
@@ -4,6 +4,7 @@ import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.transaction.DefaultPersistenceContext;
|
||||
import com.avaje.tests.model.basic.Address;
|
||||
import com.avaje.tests.model.basic.Car;
|
||||
import com.avaje.tests.model.basic.Customer;
|
||||
@@ -51,7 +52,7 @@ public class CachedBeanDataFromBeanTest extends BaseTestCase {
|
||||
|
||||
Car newCar = new Car();
|
||||
EntityBean entityBean = (EntityBean)newCar;
|
||||
CachedBeanDataToBean.load(carDesc, entityBean, cacheData);
|
||||
CachedBeanDataToBean.load(carDesc, entityBean, cacheData, new DefaultPersistenceContext());
|
||||
|
||||
assertEquals(newCar.getId(), car.getId());
|
||||
assertEquals(newCar.getDriver(), car.getDriver());
|
||||
|
||||
+3
-2
@@ -4,6 +4,7 @@ import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.transaction.DefaultPersistenceContext;
|
||||
import com.avaje.tests.model.basic.Customer;
|
||||
import com.avaje.tests.model.basic.ResetBasicData;
|
||||
import com.avaje.tests.model.basic.TBytesOnly;
|
||||
@@ -82,7 +83,7 @@ public class CachedBeanDataSerializeTest extends BaseTestCase {
|
||||
assertEquals(read.getData(), extract.getData());
|
||||
|
||||
Customer loadCustomer = new Customer();
|
||||
CachedBeanDataToBean.load(desc, (EntityBean)loadCustomer, read);
|
||||
CachedBeanDataToBean.load(desc, (EntityBean)loadCustomer, read, new DefaultPersistenceContext());
|
||||
|
||||
assertEquals(loadCustomer.getVersion(), customer.getVersion());
|
||||
assertEquals(loadCustomer.getId(), customer.getId());
|
||||
@@ -113,7 +114,7 @@ public class CachedBeanDataSerializeTest extends BaseTestCase {
|
||||
assertTrue(Arrays.equals(bean.getContent(), extraContent));
|
||||
|
||||
TBytesOnly loadBean= new TBytesOnly();
|
||||
CachedBeanDataToBean.load(desc, (EntityBean)loadBean, read);
|
||||
CachedBeanDataToBean.load(desc, (EntityBean)loadBean, read, new DefaultPersistenceContext());
|
||||
|
||||
assertEquals(loadBean.getId(), bean.getId());
|
||||
assertTrue(Arrays.equals(loadBean.getContent(), bean.getContent()));
|
||||
|
||||
@@ -18,7 +18,7 @@ public class BeanDescriptorTest extends BaseTestCase {
|
||||
@Test
|
||||
public void createReference() {
|
||||
|
||||
Customer bean = customerDesc.createReference(null, 42);
|
||||
Customer bean = customerDesc.createReference(null, 42, null);
|
||||
assertThat(bean.getId()).isEqualTo(42);
|
||||
assertThat(server().getBeanState(bean).isReadOnly()).isFalse();
|
||||
}
|
||||
@@ -26,14 +26,14 @@ public class BeanDescriptorTest extends BaseTestCase {
|
||||
@Test
|
||||
public void createReference_whenReadOnly() {
|
||||
|
||||
Customer bean = customerDesc.createReference(Boolean.TRUE, 42);
|
||||
Customer bean = customerDesc.createReference(Boolean.TRUE, 42, null);
|
||||
assertThat(server().getBeanState(bean).isReadOnly()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createReference_whenNotReadOnly() {
|
||||
|
||||
Customer bean = customerDesc.createReference(Boolean.FALSE, 42);
|
||||
Customer bean = customerDesc.createReference(Boolean.FALSE, 42, null);
|
||||
assertThat(server().getBeanState(bean).isReadOnly()).isFalse();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ public class TunedQueryInfoTest extends BaseTestCase {
|
||||
|
||||
ServerCacheManager serverCacheManager = Ebean.getServer(null).getServerCacheManager();
|
||||
serverCacheManager.clearAll();
|
||||
serverCacheManager.setCaching(Order.class, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,61 +1,66 @@
|
||||
package com.avaje.tests.basic;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.tests.model.basic.Order;
|
||||
import com.avaje.tests.model.basic.OrderDetail;
|
||||
import com.avaje.tests.model.basic.ResetBasicData;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TestManyLazyLoad extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void testLazyLoadRef() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
List<Order> list = Ebean.find(Order.class).order().asc("id").findList();
|
||||
Assert.assertTrue(list.size()+" > 0", list.size() > 0);
|
||||
|
||||
// just use the first one
|
||||
Order order = list.get(0);
|
||||
|
||||
// get it as a reference
|
||||
Order order1 = Ebean.getReference(Order.class, order.getId());
|
||||
Assert.assertNotNull(order1);
|
||||
|
||||
Date orderDate = order1.getOrderDate();
|
||||
Assert.assertNotNull(orderDate);
|
||||
|
||||
List<OrderDetail> details = order1.getDetails();
|
||||
|
||||
// lazy load the details
|
||||
int sz = details.size();
|
||||
Assert.assertTrue(sz+" > 0", sz > 0);
|
||||
|
||||
Order o = details.get(0).getOrder();
|
||||
Assert.assertTrue("same instance", o == order1);
|
||||
|
||||
@Test
|
||||
public void testLazyLoadRef() throws InterruptedException {
|
||||
|
||||
// change order... list before a scalar property
|
||||
Order order2 = Ebean.getReference(Order.class, order.getId());
|
||||
Assert.assertNotNull(order2);
|
||||
|
||||
List<OrderDetail> details2 = order2.getDetails();
|
||||
|
||||
// lazy load the details
|
||||
int sz2 = details2.size();
|
||||
Assert.assertTrue(sz2+" > 0", sz2 > 0);
|
||||
|
||||
Order o2 = details2.get(0).getOrder();
|
||||
Assert.assertTrue("same instance", o2 == order2);
|
||||
ResetBasicData.reset();
|
||||
|
||||
awaitL2Cache();
|
||||
|
||||
List<Order> list = Ebean.find(Order.class).order().asc("id").findList();
|
||||
assertTrue(list.size() + " > 0", list.size() > 0);
|
||||
|
||||
// just use the first one
|
||||
Order order = list.get(0);
|
||||
|
||||
// get it as a reference
|
||||
Order order1 = Ebean.getReference(Order.class, order.getId());
|
||||
assertNotNull(order1);
|
||||
|
||||
Date orderDate = order1.getOrderDate();
|
||||
assertNotNull(orderDate);
|
||||
|
||||
List<OrderDetail> details = order1.getDetails();
|
||||
|
||||
// lazy load the details
|
||||
int sz = details.size();
|
||||
assertTrue(sz + " > 0", sz > 0);
|
||||
|
||||
OrderDetail orderDetail = details.get(0);
|
||||
Order o = orderDetail.getOrder();
|
||||
assertSame(o, order1);
|
||||
|
||||
// load detail into cache
|
||||
Ebean.find(OrderDetail.class, orderDetail.getId());
|
||||
|
||||
// change order... list before a scalar property
|
||||
Order order2 = Ebean.getReference(Order.class, order.getId());
|
||||
assertNotNull(order2);
|
||||
|
||||
List<OrderDetail> details2 = order2.getDetails();
|
||||
|
||||
// lazy load the details
|
||||
int sz2 = details2.size();
|
||||
assertTrue(sz2 + " > 0", sz2 > 0);
|
||||
|
||||
Order o2 = details2.get(0).getOrder();
|
||||
assertSame(o2, order2);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -85,7 +85,6 @@ public class TestQueryWithCache extends BaseTestCase {
|
||||
CacheOptions cacheOptions = beanDescriptor.getCacheOptions();
|
||||
|
||||
Assert.assertNotNull(cacheOptions);
|
||||
Assert.assertTrue(cacheOptions.isUseCache());
|
||||
Assert.assertTrue(cacheOptions.isReadOnly());
|
||||
Assert.assertTrue(beanDescriptor.isCacheSharableBeans());
|
||||
|
||||
|
||||
@@ -28,9 +28,6 @@ public class TestBatchLazyWithCacheHits extends BaseTestCase {
|
||||
inserted.add(insert(names[i]));
|
||||
}
|
||||
|
||||
ServerCacheManager serverCacheManager = Ebean.getServerCacheManager();
|
||||
serverCacheManager.setCaching(UUOne.class, true);
|
||||
|
||||
UUOne b = Ebean.find(UUOne.class)
|
||||
.setId(inserted.get(1).getId())
|
||||
.setUseCache(true)
|
||||
|
||||
@@ -12,28 +12,33 @@ import com.avaje.ebean.cache.ServerCacheStatistics;
|
||||
import com.avaje.tests.model.basic.Country;
|
||||
import com.avaje.tests.model.basic.ResetBasicData;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TestQueryCacheCountry extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
|
||||
awaitL2Cache();
|
||||
|
||||
ServerCache queryCache = Ebean.getServerCacheManager().getQueryCache(Country.class);
|
||||
queryCache.clear();
|
||||
|
||||
ServerCache beanCache = Ebean.getServerCacheManager().getBeanCache(Country.class);
|
||||
beanCache.clear();
|
||||
|
||||
Assert.assertEquals(0, queryCache.getStatistics(false).getSize());
|
||||
assertEquals(0, queryCache.getStatistics(false).getSize());
|
||||
|
||||
List<Country> countryList0 = Ebean.find(Country.class)
|
||||
.setUseQueryCache(true)
|
||||
.order().asc("name")
|
||||
.findList();
|
||||
|
||||
Assert.assertEquals(1, queryCache.getStatistics(false).getSize());
|
||||
Assert.assertTrue(countryList0.size() > 0);
|
||||
assertEquals(1, queryCache.getStatistics(false).getSize());
|
||||
assertTrue(countryList0.size() > 0);
|
||||
|
||||
List<Country> countryList1 = Ebean.find(Country.class)
|
||||
.setUseQueryCache(true)
|
||||
@@ -41,8 +46,8 @@ public class TestQueryCacheCountry extends BaseTestCase {
|
||||
.findList();
|
||||
|
||||
ServerCacheStatistics statistics = queryCache.getStatistics(false);
|
||||
Assert.assertEquals(1, statistics.getSize());
|
||||
Assert.assertEquals(1, statistics.getHitCount());
|
||||
assertEquals(1, statistics.getSize());
|
||||
assertEquals(1, statistics.getHitCount());
|
||||
Assert.assertSame(countryList1, countryList0);
|
||||
|
||||
Country nz = Ebean.find(Country.class, "NZ");
|
||||
@@ -51,7 +56,7 @@ public class TestQueryCacheCountry extends BaseTestCase {
|
||||
awaitL2Cache();
|
||||
|
||||
statistics = queryCache.getStatistics(false);
|
||||
Assert.assertEquals(0, statistics.getSize());
|
||||
assertEquals(0, statistics.getSize());
|
||||
|
||||
List<Country> countryList2 = Ebean.find(Country.class)
|
||||
.setUseQueryCache(true)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.avaje.tests.model.basic;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
import com.avaje.ebean.annotation.CacheBeanTuning;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
@@ -10,7 +10,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@CacheStrategy
|
||||
@Cache
|
||||
@CacheBeanTuning(maxSecsToLive = 45)
|
||||
@Entity
|
||||
public class Article extends BasicDomain {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.avaje.tests.model.basic;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
import com.avaje.ebean.annotation.ChangeLog;
|
||||
import com.avaje.ebean.annotation.CreatedTimestamp;
|
||||
import com.avaje.ebean.annotation.DocEmbedded;
|
||||
@@ -17,136 +17,134 @@ import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
|
||||
@DocStore
|
||||
@Index(columnNames = {"last_name","first_name"})
|
||||
@Index(columnNames = {"last_name", "first_name"})
|
||||
@ChangeLog
|
||||
@Entity
|
||||
@CacheStrategy(naturalKey="email")
|
||||
@Cache(naturalKey = "email")
|
||||
public class Contact {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Id
|
||||
int id;
|
||||
|
||||
@Id
|
||||
int id;
|
||||
String firstName;
|
||||
String lastName;
|
||||
|
||||
String firstName;
|
||||
String lastName;
|
||||
String phone;
|
||||
String mobile;
|
||||
String email;
|
||||
|
||||
String phone;
|
||||
String mobile;
|
||||
String email;
|
||||
@DocEmbedded(doc = "id,name")
|
||||
@ManyToOne(optional = false)
|
||||
Customer customer;
|
||||
|
||||
@DocEmbedded(doc="id,name")
|
||||
@ManyToOne(optional=false)
|
||||
Customer customer;
|
||||
|
||||
@ManyToOne(optional=true)
|
||||
ContactGroup group;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
List<ContactNote> notes;
|
||||
@ManyToOne(optional = true)
|
||||
ContactGroup group;
|
||||
|
||||
@CreatedTimestamp
|
||||
Timestamp cretime;
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
List<ContactNote> notes;
|
||||
|
||||
@Version
|
||||
Timestamp updtime;
|
||||
@CreatedTimestamp
|
||||
Timestamp cretime;
|
||||
|
||||
@Version
|
||||
Timestamp updtime;
|
||||
|
||||
|
||||
public Contact(String firstName, String lastName) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
public Contact(String firstName, String lastName) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public Contact() {
|
||||
public Contact() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Timestamp getUpdtime() {
|
||||
return updtime;
|
||||
}
|
||||
public Timestamp getUpdtime() {
|
||||
return updtime;
|
||||
}
|
||||
|
||||
public void setUpdtime(Timestamp updtime) {
|
||||
this.updtime = updtime;
|
||||
}
|
||||
public void setUpdtime(Timestamp updtime) {
|
||||
this.updtime = updtime;
|
||||
}
|
||||
|
||||
public Timestamp getCretime() {
|
||||
return cretime;
|
||||
}
|
||||
public Timestamp getCretime() {
|
||||
return cretime;
|
||||
}
|
||||
|
||||
public void setCretime(Timestamp cretime) {
|
||||
this.cretime = cretime;
|
||||
}
|
||||
public void setCretime(Timestamp cretime) {
|
||||
this.cretime = cretime;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public String getMobile() {
|
||||
return mobile;
|
||||
}
|
||||
public String getMobile() {
|
||||
return mobile;
|
||||
}
|
||||
|
||||
public void setMobile(String mobile) {
|
||||
this.mobile = mobile;
|
||||
}
|
||||
public void setMobile(String mobile) {
|
||||
this.mobile = mobile;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public Customer getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
public Customer getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
|
||||
public void setCustomer(Customer customer) {
|
||||
this.customer = customer;
|
||||
}
|
||||
|
||||
public ContactGroup getGroup() {
|
||||
return group;
|
||||
}
|
||||
public void setCustomer(Customer customer) {
|
||||
this.customer = customer;
|
||||
}
|
||||
|
||||
public void setGroup(ContactGroup group) {
|
||||
this.group = group;
|
||||
}
|
||||
public ContactGroup getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public List<ContactNote> getNotes() {
|
||||
return notes;
|
||||
}
|
||||
public void setGroup(ContactGroup group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public void setNotes(List<ContactNote> notes) {
|
||||
this.notes = notes;
|
||||
}
|
||||
public List<ContactNote> getNotes() {
|
||||
return notes;
|
||||
}
|
||||
|
||||
public void setNotes(List<ContactNote> notes) {
|
||||
this.notes = notes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.avaje.tests.model.basic;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
import com.avaje.ebean.annotation.CacheBeanTuning;
|
||||
import com.avaje.ebean.annotation.ChangeLog;
|
||||
import com.avaje.ebean.annotation.ChangeLogInsertMode;
|
||||
@@ -18,7 +18,7 @@ import javax.validation.constraints.Size;
|
||||
@DocStore
|
||||
@ReadAudit
|
||||
@ChangeLog(inserts = ChangeLogInsertMode.INCLUDE)
|
||||
@CacheStrategy(readOnly = true)
|
||||
@Cache(readOnly = true, enableQueryCache = true)
|
||||
@CacheBeanTuning(maxSize = 500)
|
||||
@Entity
|
||||
@Table(name = "o_country")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.tests.model.basic;
|
||||
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
import com.avaje.ebean.annotation.ChangeLog;
|
||||
import com.avaje.ebean.annotation.ChangeLogInsertMode;
|
||||
import com.avaje.ebean.annotation.DbComment;
|
||||
@@ -26,6 +27,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
/**
|
||||
* Customer entity bean.
|
||||
*/
|
||||
@Cache(enableQueryCache = true)
|
||||
@DocStore
|
||||
@ChangeLog(inserts = ChangeLogInsertMode.EXCLUDE, updatesThatInclude = {"name","status"})
|
||||
@Entity
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.tests.model.basic;
|
||||
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
import com.avaje.ebean.annotation.ChangeLog;
|
||||
import com.avaje.ebean.annotation.ReadAudit;
|
||||
import com.avaje.ebean.annotation.WhenCreated;
|
||||
@@ -13,6 +14,7 @@ import javax.persistence.Version;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
@Cache(enableQueryCache = true)
|
||||
@ReadAudit
|
||||
@ChangeLog(updatesThatInclude = {"name","shortDescription"})
|
||||
@Entity
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.avaje.tests.model.basic;
|
||||
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
@@ -7,6 +9,7 @@ import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Version;
|
||||
|
||||
@Cache(enableQueryCache = true)
|
||||
@Entity
|
||||
@Table(name = "e_basicver")
|
||||
public class EBasicVer {
|
||||
|
||||
@@ -4,9 +4,9 @@ import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
|
||||
@CacheStrategy(readOnly = true, useBeanCache = true)
|
||||
@Cache(readOnly = true)
|
||||
@Entity
|
||||
@Table(name="feature_desc")
|
||||
public class FeatureDescription {
|
||||
|
||||
@@ -10,12 +10,12 @@ import javax.persistence.ManyToMany;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
|
||||
/**
|
||||
* Cached bean for testing caching implementation.
|
||||
*/
|
||||
@CacheStrategy
|
||||
@Cache
|
||||
@Entity
|
||||
@Table(name = "o_cached_bean")
|
||||
public class OCachedBean {
|
||||
|
||||
@@ -5,12 +5,12 @@ import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
|
||||
/**
|
||||
* Cached bean for testing caching implementation, especially relations.
|
||||
*/
|
||||
@CacheStrategy
|
||||
@Cache
|
||||
@Entity
|
||||
@Table(name = "o_cached_bean_child")
|
||||
public class OCachedBeanChild {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.tests.model.basic;
|
||||
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
import com.avaje.ebean.annotation.ChangeLog;
|
||||
import com.avaje.ebean.annotation.DocEmbedded;
|
||||
import com.avaje.ebean.annotation.DocStore;
|
||||
@@ -30,6 +31,7 @@ import java.util.List;
|
||||
/**
|
||||
* Order entity bean.
|
||||
*/
|
||||
@Cache
|
||||
@DocStore
|
||||
@ChangeLog
|
||||
@Entity
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.tests.model.basic;
|
||||
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
import com.avaje.ebean.annotation.DocEmbedded;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
@@ -13,146 +14,147 @@ import java.sql.Timestamp;
|
||||
/**
|
||||
* Order Detail entity bean.
|
||||
*/
|
||||
@Cache
|
||||
@Entity
|
||||
@Table(name = "o_order_detail")
|
||||
public class OrderDetail implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
Integer id;
|
||||
@Id
|
||||
Integer id;
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
Order order;
|
||||
@ManyToOne(optional = false)
|
||||
Order order;
|
||||
|
||||
Integer orderQty;
|
||||
Integer orderQty;
|
||||
|
||||
Integer shipQty;
|
||||
Integer shipQty;
|
||||
|
||||
Double unitPrice;
|
||||
Double unitPrice;
|
||||
|
||||
@ManyToOne
|
||||
@DocEmbedded(doc = "id,name,sku")
|
||||
Product product;
|
||||
@ManyToOne
|
||||
@DocEmbedded(doc = "id,name,sku")
|
||||
Product product;
|
||||
|
||||
Timestamp cretime;
|
||||
Timestamp cretime;
|
||||
|
||||
@Version
|
||||
Timestamp updtime;
|
||||
@Version
|
||||
Timestamp updtime;
|
||||
|
||||
public OrderDetail() {
|
||||
}
|
||||
public OrderDetail() {
|
||||
}
|
||||
|
||||
public OrderDetail(Product product, Integer orderQty, Double unitPrice) {
|
||||
this.product = product;
|
||||
this.orderQty = orderQty;
|
||||
this.unitPrice = unitPrice;
|
||||
}
|
||||
public OrderDetail(Product product, Integer orderQty, Double unitPrice) {
|
||||
this.product = product;
|
||||
this.orderQty = orderQty;
|
||||
this.unitPrice = unitPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return id.
|
||||
*/
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* Return id.
|
||||
*/
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set id.
|
||||
*/
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
/**
|
||||
* Set id.
|
||||
*/
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return order qty.
|
||||
*/
|
||||
public Integer getOrderQty() {
|
||||
return orderQty;
|
||||
}
|
||||
/**
|
||||
* Return order qty.
|
||||
*/
|
||||
public Integer getOrderQty() {
|
||||
return orderQty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set order qty.
|
||||
*/
|
||||
public void setOrderQty(Integer orderQty) {
|
||||
this.orderQty = orderQty;
|
||||
}
|
||||
/**
|
||||
* Set order qty.
|
||||
*/
|
||||
public void setOrderQty(Integer orderQty) {
|
||||
this.orderQty = orderQty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return ship qty.
|
||||
*/
|
||||
public Integer getShipQty() {
|
||||
return shipQty;
|
||||
}
|
||||
/**
|
||||
* Return ship qty.
|
||||
*/
|
||||
public Integer getShipQty() {
|
||||
return shipQty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ship qty.
|
||||
*/
|
||||
public void setShipQty(Integer shipQty) {
|
||||
this.shipQty = shipQty;
|
||||
}
|
||||
/**
|
||||
* Set ship qty.
|
||||
*/
|
||||
public void setShipQty(Integer shipQty) {
|
||||
this.shipQty = shipQty;
|
||||
}
|
||||
|
||||
public Double getUnitPrice() {
|
||||
return unitPrice;
|
||||
}
|
||||
public Double getUnitPrice() {
|
||||
return unitPrice;
|
||||
}
|
||||
|
||||
public void setUnitPrice(Double unitPrice) {
|
||||
this.unitPrice = unitPrice;
|
||||
}
|
||||
public void setUnitPrice(Double unitPrice) {
|
||||
this.unitPrice = unitPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return cretime.
|
||||
*/
|
||||
public Timestamp getCretime() {
|
||||
return cretime;
|
||||
}
|
||||
/**
|
||||
* Return cretime.
|
||||
*/
|
||||
public Timestamp getCretime() {
|
||||
return cretime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cretime.
|
||||
*/
|
||||
public void setCretime(Timestamp cretime) {
|
||||
this.cretime = cretime;
|
||||
}
|
||||
/**
|
||||
* Set cretime.
|
||||
*/
|
||||
public void setCretime(Timestamp cretime) {
|
||||
this.cretime = cretime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return updtime.
|
||||
*/
|
||||
public Timestamp getUpdtime() {
|
||||
return updtime;
|
||||
}
|
||||
/**
|
||||
* Return updtime.
|
||||
*/
|
||||
public Timestamp getUpdtime() {
|
||||
return updtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set updtime.
|
||||
*/
|
||||
public void setUpdtime(Timestamp updtime) {
|
||||
this.updtime = updtime;
|
||||
}
|
||||
/**
|
||||
* Set updtime.
|
||||
*/
|
||||
public void setUpdtime(Timestamp updtime) {
|
||||
this.updtime = updtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return order.
|
||||
*/
|
||||
public Order getOrder() {
|
||||
return order;
|
||||
}
|
||||
/**
|
||||
* Return order.
|
||||
*/
|
||||
public Order getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set order.
|
||||
*/
|
||||
public void setOrder(Order order) {
|
||||
this.order = order;
|
||||
}
|
||||
/**
|
||||
* Set order.
|
||||
*/
|
||||
public void setOrder(Order order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return product.
|
||||
*/
|
||||
public Product getProduct() {
|
||||
return product;
|
||||
}
|
||||
/**
|
||||
* Return product.
|
||||
*/
|
||||
public Product getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set product.
|
||||
*/
|
||||
public void setProduct(Product product) {
|
||||
this.product = product;
|
||||
}
|
||||
/**
|
||||
* Set product.
|
||||
*/
|
||||
public void setProduct(Product product) {
|
||||
this.product = product;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import javax.persistence.Version;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheQueryTuning;
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
import com.avaje.ebean.annotation.CreatedTimestamp;
|
||||
import com.avaje.ebean.annotation.DocStore;
|
||||
|
||||
@@ -18,7 +18,7 @@ import com.avaje.ebean.annotation.DocStore;
|
||||
* Product entity bean.
|
||||
*/
|
||||
@DocStore
|
||||
@CacheStrategy
|
||||
@Cache
|
||||
@CacheQueryTuning(maxSecsToLive = 15)
|
||||
@Entity
|
||||
@Table(name = "o_product")
|
||||
|
||||
@@ -9,9 +9,9 @@ import javax.persistence.Lob;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
|
||||
@CacheStrategy(useBeanCache=true)
|
||||
@Cache
|
||||
@Entity
|
||||
public class Section extends BasicDomain {
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ package com.avaje.tests.model.basic;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
|
||||
@CacheStrategy(useBeanCache=true)
|
||||
@Cache
|
||||
@Entity
|
||||
public class SubSection extends BasicDomain {
|
||||
|
||||
|
||||
@@ -1,47 +1,49 @@
|
||||
package com.avaje.tests.model.basic;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Cache
|
||||
@Entity
|
||||
public class UUOne {
|
||||
|
||||
@Id
|
||||
UUID id;
|
||||
|
||||
String name;
|
||||
@Id
|
||||
UUID id;
|
||||
|
||||
String name;
|
||||
|
||||
|
||||
@OneToMany(cascade=CascadeType.ALL, mappedBy="master")
|
||||
List<UUTwo> comments;
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "master")
|
||||
List<UUTwo> comments;
|
||||
|
||||
public void setId(UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setId(UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<UUTwo> getComments() {
|
||||
return comments;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<UUTwo> getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(List<UUTwo> comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
public void setComments(List<UUTwo> comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.avaje.tests.model.basic.cache;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Inheritance;
|
||||
|
||||
@CacheStrategy
|
||||
@Cache
|
||||
@Entity
|
||||
@Inheritance
|
||||
@DiscriminatorValue("O")
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package com.avaje.tests.model.basic.cache;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
import com.avaje.tests.model.basic.BasicDomain;
|
||||
|
||||
import javax.persistence.DiscriminatorColumn;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Inheritance;
|
||||
|
||||
@CacheStrategy
|
||||
@Cache
|
||||
@Entity
|
||||
@Inheritance
|
||||
@DiscriminatorColumn(length = 3)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.avaje.tests.model.basic.cache;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Inheritance;
|
||||
|
||||
@CacheStrategy
|
||||
@Cache
|
||||
@Entity
|
||||
@Inheritance
|
||||
@DiscriminatorValue("T")
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.avaje.tests.model.embedded;
|
||||
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.AttributeOverride;
|
||||
@@ -11,6 +13,7 @@ import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Version;
|
||||
|
||||
@Cache
|
||||
@Entity
|
||||
public class EInvoice {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.avaje.tests.model.m2m;
|
||||
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.Cache;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
@@ -14,7 +14,7 @@ import java.util.UUID;
|
||||
* The Class Permission.
|
||||
*/
|
||||
@Entity
|
||||
@CacheStrategy(readOnly = true)
|
||||
@Cache(readOnly = true)
|
||||
@Table(name = "mt_permission")
|
||||
public class Permission {
|
||||
|
||||
|
||||
@@ -55,6 +55,8 @@ public class TestMultipleEmbeddedLoading extends BaseTestCase {
|
||||
invoice2.getBillAddress().setStreet("3 Pineapple St");
|
||||
// bean should be dirty
|
||||
Ebean.save(invoice2);
|
||||
|
||||
awaitL2Cache();
|
||||
|
||||
EInvoice invoice3 = Ebean.find(EInvoice.class)
|
||||
.where().idEq(invoice.getId())
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
package com.avaje.tests.transaction;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebeaninternal.api.SpiTransaction;
|
||||
import com.avaje.tests.model.basic.EBasicVer;
|
||||
import com.avaje.tests.model.basic.ResetBasicData;
|
||||
import org.junit.Test;
|
||||
|
||||
import static junit.framework.TestCase.assertNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
public class TestDeleteFromPersistenceContext extends BaseTestCase {
|
||||
|
||||
@@ -25,30 +27,33 @@ public class TestDeleteFromPersistenceContext extends BaseTestCase {
|
||||
try {
|
||||
|
||||
EBasicVer bean2 = Ebean.find(EBasicVer.class, bean.getId());
|
||||
Assert.assertNotSame(bean, bean2);
|
||||
assertNotSame(bean, bean2);
|
||||
|
||||
EBasicVer bean3 = Ebean.find(EBasicVer.class, bean.getId());
|
||||
// same instance from PersistenceContext
|
||||
Assert.assertSame(bean2, bean3);
|
||||
assertSame(bean2, bean3);
|
||||
|
||||
Object bean4 = transaction.getPersistenceContext().get(EBasicVer.class, bean.getId());
|
||||
Assert.assertSame(bean2, bean4);
|
||||
assertSame(bean2, bean4);
|
||||
|
||||
Ebean.delete(bean2);
|
||||
|
||||
Object bean5 = transaction.getPersistenceContext().get(EBasicVer.class, bean.getId());
|
||||
Assert.assertNull("Bean is deleted from PersistenceContext",bean5);
|
||||
|
||||
EBasicVer bean6 = Ebean.find(EBasicVer.class).where().eq("id", bean.getId()).findUnique();
|
||||
Assert.assertNull("Bean where id eq is not found "+bean6, bean6);
|
||||
|
||||
EBasicVer bean7 = Ebean.find(EBasicVer.class, bean.getId());
|
||||
Assert.assertNull("Bean is not expected to be found? "+bean7, bean7);
|
||||
|
||||
assertNull("Bean is deleted from PersistenceContext",bean5);
|
||||
|
||||
Ebean.commitTransaction();
|
||||
|
||||
} finally {
|
||||
Ebean.endTransaction();
|
||||
}
|
||||
|
||||
|
||||
EBasicVer bean6 = Ebean.find(EBasicVer.class).where().eq("id", bean.getId()).findUnique();
|
||||
assertNull("Bean where id eq is not found "+bean6, bean6);
|
||||
|
||||
awaitL2Cache();
|
||||
EBasicVer bean7 = Ebean.find(EBasicVer.class, bean.getId());
|
||||
assertNull("Bean is not expected to be found? "+bean7, bean7);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -72,7 +72,6 @@
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
|
||||
<logger name="com.avaje.ebeaninternal.server.autotune" level="TRACE"/>
|
||||
|
||||
<logger name="com.avaje.ebean" level="INFO"/>
|
||||
<logger name="org.avaje.ebean" level="INFO"/>
|
||||
@@ -82,12 +81,14 @@
|
||||
<!--<logger name="org.avaje.ebean.SUM" level="TRACE"/>-->
|
||||
<!--<logger name="org.avaje.ebean.ELA" level="TRACE"/>-->
|
||||
|
||||
<logger name="org.avaje.classpath" level="INFO"/>
|
||||
|
||||
<!--<logger name="org.avaje.ebean.cache.QUERY" level="TRACE"/>-->
|
||||
<!--<logger name="org.avaje.ebean.cache.BEAN" level="TRACE"/>-->
|
||||
<!--<logger name="org.avaje.ebean.cache.COLL" level="TRACE"/>-->
|
||||
<!--<logger name="org.avaje.ebean.cache.NATKEY" level="TRACE"/>-->
|
||||
<!--<logger name="org.avaje.ebean.cache.COLL" level="DEBUG"/>-->
|
||||
|
||||
<!--<logger name="org.avaje.classpath" level="INFO"/>-->
|
||||
|
||||
<!--<logger name="com.avaje.ebeaninternal.server.autotune" level="TRACE"/>-->
|
||||
|
||||
<!--<logger name="com.avaje.ebean.dbmigration.DdlRunner" level="DEBUG"/>-->
|
||||
<!--<logger name="com.avaje.ebean.config.dbplatform.H2HistoryTrigger" level="DEBUG"/>-->
|
||||
|
||||
Reference in New Issue
Block a user