mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Embedded beans support in l2 cache - initial work
This commit is contained in:
@@ -182,6 +182,13 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
public Object getEmbeddedOwner() {
|
||||
return embeddedOwner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the property index (for the parent) of this embedded bean.
|
||||
*/
|
||||
public int getEmbeddedOwnerIndex() {
|
||||
return embeddedOwnerIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Special case for a OneToOne, Set the parent bean (by relationship). This is
|
||||
|
||||
+10
@@ -15,10 +15,20 @@ public class CachedBeanDataFromBean {
|
||||
Object[] data = new Object[desc.getPropertyCount()];
|
||||
boolean[] loaded = new boolean[desc.getPropertyCount()];
|
||||
|
||||
BeanProperty idProperty = desc.getIdProperty();
|
||||
if (idProperty != null) {
|
||||
int propertyIndex = idProperty.getPropertyIndex();
|
||||
if (ebi.isLoadedProperty(propertyIndex)) {
|
||||
// extract the id property value
|
||||
data[propertyIndex] = idProperty.getCacheDataValue(bean);
|
||||
loaded[propertyIndex] = true;
|
||||
}
|
||||
}
|
||||
BeanProperty[] props = desc.propertiesNonMany();
|
||||
|
||||
Object naturalKey = null;
|
||||
|
||||
// extract all the non-many properties
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
BeanProperty prop = props[i];
|
||||
if (ebi.isLoadedProperty(prop.getPropertyIndex())) {
|
||||
|
||||
+22
-11
@@ -13,19 +13,17 @@ public class CachedBeanDataToBean {
|
||||
|
||||
EntityBeanIntercept ebi = bean._ebean_getIntercept();
|
||||
|
||||
|
||||
BeanProperty idProperty = desc.getIdProperty();
|
||||
if (idProperty != null) {
|
||||
// load the id property
|
||||
loadProperty(bean, cacheBeanData, ebi, idProperty);
|
||||
}
|
||||
|
||||
// load the non-many properties
|
||||
BeanProperty[] props = desc.propertiesNonMany();
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
|
||||
BeanProperty prop = props[i];
|
||||
int propertyIndex = prop.getPropertyIndex();
|
||||
if (cacheBeanData.isLoaded(propertyIndex)) {
|
||||
if (ebi.isLoadedProperty(propertyIndex)) {
|
||||
// already loaded (lazy load on partially loaded bean)
|
||||
} else {
|
||||
Object data = cacheBeanData.getData(propertyIndex);
|
||||
prop.setCacheDataValue(bean, data);
|
||||
}
|
||||
}
|
||||
loadProperty(bean, cacheBeanData, ebi, props[i]);
|
||||
}
|
||||
|
||||
BeanPropertyAssocMany<?>[] manys = desc.propertiesMany();
|
||||
@@ -38,4 +36,17 @@ public class CachedBeanDataToBean {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void loadProperty(EntityBean bean, CachedBeanData cacheBeanData, EntityBeanIntercept ebi, BeanProperty prop) {
|
||||
|
||||
int propertyIndex = prop.getPropertyIndex();
|
||||
if (cacheBeanData.isLoaded(propertyIndex)) {
|
||||
if (ebi.isLoadedProperty(propertyIndex)) {
|
||||
// already loaded (lazy load on partially loaded bean)
|
||||
} else {
|
||||
Object data = cacheBeanData.getData(propertyIndex);
|
||||
prop.setCacheDataValue(bean, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import com.avaje.ebeaninternal.api.SpiQuery;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery.Mode;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor.EntityType;
|
||||
import com.avaje.ebeaninternal.server.transaction.DefaultPersistenceContext;
|
||||
|
||||
/**
|
||||
@@ -324,19 +325,27 @@ public class DefaultBeanLoader {
|
||||
}
|
||||
|
||||
public void refresh(EntityBean bean) {
|
||||
refreshBeanInternal(bean, SpiQuery.Mode.REFRESH_BEAN);
|
||||
refreshBeanInternal(bean, SpiQuery.Mode.REFRESH_BEAN, -1);
|
||||
}
|
||||
|
||||
public void loadBean(EntityBeanIntercept ebi) {
|
||||
refreshBeanInternal(ebi.getOwner(), SpiQuery.Mode.LAZYLOAD_BEAN);
|
||||
refreshBeanInternal(ebi.getOwner(), SpiQuery.Mode.LAZYLOAD_BEAN, -1);
|
||||
}
|
||||
|
||||
private void refreshBeanInternal(EntityBean bean, SpiQuery.Mode mode) {
|
||||
private void refreshBeanInternal(EntityBean bean, SpiQuery.Mode mode, int embeddedOwnerIndex) {
|
||||
|
||||
EntityBeanIntercept ebi = ((EntityBean) bean)._ebean_getIntercept();;
|
||||
PersistenceContext pc = ebi.getPersistenceContext();
|
||||
|
||||
BeanDescriptor<?> desc = server.getBeanDescriptor(bean.getClass());
|
||||
if (EntityType.EMBEDDED == desc.getEntityType()) {
|
||||
// lazy loading on an embedded bean property
|
||||
EntityBean embeddedOwner = (EntityBean)ebi.getEmbeddedOwner();
|
||||
int ownerIndex = ebi.getEmbeddedOwnerIndex();
|
||||
|
||||
refreshBeanInternal(embeddedOwner, mode, ownerIndex);
|
||||
}
|
||||
|
||||
Object id = desc.getId(bean);
|
||||
|
||||
if (pc == null) {
|
||||
@@ -348,7 +357,7 @@ public class DefaultBeanLoader {
|
||||
}
|
||||
}
|
||||
|
||||
if (ebi != null) {
|
||||
if (embeddedOwnerIndex == -1) {
|
||||
if (SpiQuery.Mode.LAZYLOAD_BEAN.equals(mode) && desc.isBeanCaching()) {
|
||||
// lazy loading and the bean cache is active
|
||||
if (desc.cacheBeanLoad((EntityBean)bean, ebi, id)) {
|
||||
@@ -365,6 +374,11 @@ public class DefaultBeanLoader {
|
||||
query.setLazyLoadProperty(ebi.getLazyLoadProperty());
|
||||
}
|
||||
|
||||
if (embeddedOwnerIndex > -1) {
|
||||
String embeddedBeanPropertyName = ebi.getProperty(embeddedOwnerIndex);
|
||||
query.select("id,"+embeddedBeanPropertyName);
|
||||
}
|
||||
|
||||
// don't collect autoFetch usage profiling information
|
||||
// as we just copy the data out of these fetched beans
|
||||
// and put the data into the original bean
|
||||
@@ -373,12 +387,13 @@ public class DefaultBeanLoader {
|
||||
|
||||
query.setMode(mode);
|
||||
query.setId(id);
|
||||
// make sure the query doesn't use the cache
|
||||
if (mode.equals(SpiQuery.Mode.REFRESH_BEAN)) {
|
||||
|
||||
if (embeddedOwnerIndex > -1 || mode.equals(SpiQuery.Mode.REFRESH_BEAN)) {
|
||||
// make sure the query doesn't use the cache
|
||||
query.setUseCache(false);
|
||||
}
|
||||
|
||||
if (ebi != null && ebi.isReadOnly()) {
|
||||
if (ebi.isReadOnly()) {
|
||||
query.setReadOnly(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -842,6 +842,20 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
|
||||
cacheBeanPutData((EntityBean)bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the raw cache data from the bean.
|
||||
*/
|
||||
public CachedBeanData cacheBeanExtractData(EntityBean bean) {
|
||||
return cacheHelp.beanExtractData(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the raw cache data into the bean.
|
||||
*/
|
||||
public void cacheBeanLoadData(EntityBean bean, CachedBeanData data) {
|
||||
cacheHelp.beanLoadData(bean, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a bean into the bean cache.
|
||||
*/
|
||||
|
||||
@@ -360,12 +360,20 @@ public final class BeanDescriptorCacheHelp<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public CachedBeanData beanExtractData(EntityBean bean) {
|
||||
return CachedBeanDataFromBean.extract(desc, bean);
|
||||
}
|
||||
|
||||
public void beanLoadData(EntityBean bean, CachedBeanData data) {
|
||||
CachedBeanDataToBean.load(desc, bean, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a bean into the bean cache.
|
||||
*/
|
||||
public void beanCachePut(EntityBean bean) {
|
||||
|
||||
CachedBeanData beanData = CachedBeanDataFromBean.extract(desc, bean);
|
||||
CachedBeanData beanData = beanExtractData(bean);
|
||||
|
||||
Object id = desc.getId(bean);
|
||||
if (beanLog.isDebugEnabled()) {
|
||||
@@ -402,15 +410,15 @@ public final class BeanDescriptorCacheHelp<T> {
|
||||
@SuppressWarnings("unchecked")
|
||||
private T beanCacheGetInternal(Object id, Boolean readOnly) {
|
||||
|
||||
CachedBeanData d = (CachedBeanData) getBeanCache().get(id);
|
||||
if (d == null) {
|
||||
CachedBeanData data = (CachedBeanData) getBeanCache().get(id);
|
||||
if (data == null) {
|
||||
if (beanLog.isTraceEnabled()) {
|
||||
beanLog.trace(" GET {}({}) - cache miss", cacheName, id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (cacheSharableBeans && !Boolean.FALSE.equals(readOnly)) {
|
||||
Object bean = d.getSharableBean();
|
||||
Object bean = data.getSharableBean();
|
||||
if (bean != null) {
|
||||
if (beanLog.isTraceEnabled()) {
|
||||
beanLog.trace(" GET {}({}) - hit shared bean", cacheName, id);
|
||||
@@ -425,7 +433,7 @@ public final class BeanDescriptorCacheHelp<T> {
|
||||
bean._ebean_getIntercept().setReadOnly(true);
|
||||
}
|
||||
|
||||
CachedBeanDataToBean.load(desc, bean, d);
|
||||
beanLoadData(bean, data);
|
||||
if (beanLog.isTraceEnabled()) {
|
||||
beanLog.trace(" GET {}({}) - hit", cacheName, id);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.avaje.ebean.Transaction;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.bean.EntityBeanIntercept;
|
||||
import com.avaje.ebean.bean.PersistenceContext;
|
||||
import com.avaje.ebeaninternal.server.cache.CachedBeanData;
|
||||
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
import com.avaje.ebeaninternal.server.deploy.id.IdBinder;
|
||||
import com.avaje.ebeaninternal.server.deploy.id.ImportedId;
|
||||
@@ -323,15 +324,15 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
|
||||
public Object getCacheDataValue(EntityBean bean){
|
||||
if (embedded) {
|
||||
throw new RuntimeException();
|
||||
Object ap = getValue(bean);
|
||||
if (ap == null){
|
||||
return null;
|
||||
}
|
||||
if (embedded) {
|
||||
return targetDescriptor.cacheBeanExtractData((EntityBean) ap);
|
||||
|
||||
} else {
|
||||
Object ap = getValue(bean);
|
||||
if (ap == null){
|
||||
return null;
|
||||
} else {
|
||||
return targetDescriptor.getId((EntityBean)ap);
|
||||
}
|
||||
return targetDescriptor.getId((EntityBean)ap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +340,10 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
|
||||
public void setCacheDataValue(EntityBean bean, Object cacheData){
|
||||
if (cacheData != null) {
|
||||
if (embedded){
|
||||
throw new RuntimeException();
|
||||
EntityBean embeddedBean = targetDescriptor.createEntityBean();
|
||||
targetDescriptor.cacheBeanLoadData(embeddedBean, (CachedBeanData) cacheData);
|
||||
setValue(bean, embeddedBean);
|
||||
|
||||
} else {
|
||||
T ref = targetDescriptor.createReference(Boolean.FALSE, cacheData);
|
||||
setValue(bean, ref);
|
||||
|
||||
Reference in New Issue
Block a user