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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user