#595 - Refactor - persistence context root type handling - fully expect root type

This commit is contained in:
Robin Bygrave
2016-03-11 20:54:57 +13:00
parent 33f69902dc
commit 49121a9c1f
8 changed files with 60 additions and 36 deletions
@@ -27,14 +27,14 @@ public interface PersistenceContext {
/**
* Return an object given its type and unique id.
*/
Object get(Class<?> beanType, Object uid);
Object get(Class<?> rootType, Object uid);
/**
* Get the bean from the persistence context also checked to see if it had
* been previously deleted (if so then you also can't hit the L2 cache to
* fetch the bean for this particular persistence context).
*/
WithOption getWithOption(Class<?> beanType, Object uid);
WithOption getWithOption(Class<?> rootType, Object uid);
/**
* Clear all the references.
@@ -44,22 +44,22 @@ public interface PersistenceContext {
/**
* Clear all the references for a given type of entity bean.
*/
void clear(Class<?> beanType);
void clear(Class<?> rootType);
/**
* Clear the reference to a specific entity bean.
*/
void clear(Class<?> beanType, Object uid);
void clear(Class<?> rootType, Object uid);
/**
* Clear the reference as a result of an entity being deleted.
*/
void deleted(Class<?> beanType, Object id);
void deleted(Class<?> rootType, Object id);
/**
* Return the number of beans of the given type in the persistence context.
*/
int size(Class<?> beanType);
int size(Class<?> rootType);
/**
* Wrapper on a bean to also indicate if a bean has been deleted.
@@ -1065,31 +1065,32 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
if (t == null) {
t = getCurrentServerTransaction();
}
PersistenceContext context = null;
BeanDescriptor<T> desc = query.getBeanDescriptor();
PersistenceContext pc = null;
if (t != null && useTransactionPersistenceContext(query)) {
// first look in the transaction scoped persistence context
context = t.getPersistenceContext();
if (context != null) {
WithOption o = context.getWithOption(query.getBeanType(), query.getId());
pc = t.getPersistenceContext();
if (pc != null) {
WithOption o = desc.contextGetWithOption(pc, query.getId());
if (o != null) {
if (o.isDeleted()) {
// Bean was previously deleted in the same transaction / persistence context
return null;
}
// Return the entity bean instance from the persistence context
return (T) o.getBean();
}
}
}
BeanDescriptor<T> desc = query.getBeanDescriptor();
if (!desc.calculateUseCache(query.isUseBeanCache())) {
// not using bean cache
return null;
}
// Hit the L2 bean cache
return desc.cacheBeanGet(query, context);
return desc.cacheBeanGet(query, pc);
}
/**
@@ -698,7 +698,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
*/
private void postUpdate() {
if (statelessUpdate) {
transaction.getPersistenceContext().clear(beanDescriptor.getBeanType(), idValue);
beanDescriptor.contextClear(transaction.getPersistenceContext(), idValue);
}
}
@@ -706,9 +706,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
* Aggressive L1 and L2 cache cleanup for deletes.
*/
private void postDelete() {
// Delete the bean from the PersistenceContent
transaction.getPersistenceContext().clear(beanDescriptor.getBeanType(), idValue);
// Delete from cache early even if transaction fails
beanDescriptor.contextClear(transaction.getPersistenceContext(), idValue);
beanDescriptor.cacheHandleDelete(idValue, this);
}
@@ -1675,6 +1675,13 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
return pc.get(rootBeanType, id);
}
/**
* Get the bean from the persistence context with delete check option.
*/
public PersistenceContext.WithOption contextGetWithOption(PersistenceContext pc, Object id) {
return pc.getWithOption(rootBeanType, id);
}
/**
* Put the bean into the persistence context.
*/
@@ -1700,6 +1707,20 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
return ref;
}
/**
* Clear a bean from the persistence context.
*/
public void contextClear(PersistenceContext pc, Object idValue) {
pc.clear(rootBeanType, idValue);
}
/**
* Delete a bean from the persistence context (such that we don't fetch it in the same transaction).
*/
public void contextDeleted(PersistenceContext pc, Object idValue) {
pc.deleted(rootBeanType, idValue);
}
/**
* Helper method to return the unique property. If only one property makes up
* the unique id then it's value is returned. If there is a concatenated
@@ -706,10 +706,10 @@ public final class DefaultPersister implements Persister {
PersistenceContext persistenceContext = t.getPersistenceContext();
if (idList != null) {
for (Object idValue : idList) {
persistenceContext.deleted(descriptor.getBeanType(), idValue);
descriptor.contextDeleted(persistenceContext, idValue);
}
} else {
persistenceContext.deleted(descriptor.getBeanType(), id);
descriptor.contextDeleted(persistenceContext, id);
}
return rows;
}
@@ -394,7 +394,7 @@ public class CQuery<T> implements DbReadContext, CancelableQuery {
if (lazyLoadParentId != null) {
if (!lazyLoadParentId.equals(this.lazyLoadParentId)) {
// get the appropriate parent bean from the persistence context
this.lazyLoadParentBean = (EntityBean) getPersistenceContext().get(lazyLoadManyProperty.getBeanDescriptor().getBeanType(), lazyLoadParentId);
this.lazyLoadParentBean = (EntityBean) lazyLoadManyProperty.getBeanDescriptor().contextGet(getPersistenceContext(), lazyLoadParentId);
this.lazyLoadParentId = lazyLoadParentId;
}
@@ -59,24 +59,24 @@ public final class DefaultPersistenceContext implements PersistenceContext {
/**
* Return an object given its type and unique id.
*/
public Object get(Class<?> beanType, Object id) {
public Object get(Class<?> rootType, Object id) {
synchronized (monitor) {
return getClassContext(beanType).get(id);
return getClassContext(rootType).get(id);
}
}
public WithOption getWithOption(Class<?> beanType, Object id) {
public WithOption getWithOption(Class<?> rootType, Object id) {
synchronized (monitor) {
return getClassContext(beanType).getWithOption(id);
return getClassContext(rootType).getWithOption(id);
}
}
/**
* Return the number of beans of the given type in the persistence context.
*/
public int size(Class<?> beanType) {
public int size(Class<?> rootType) {
synchronized (monitor) {
ClassContext classMap = typeCache.get(beanType);
ClassContext classMap = typeCache.get(rootType);
return classMap == null ? 0 : classMap.size();
}
}
@@ -90,27 +90,27 @@ public final class DefaultPersistenceContext implements PersistenceContext {
}
}
public void clear(Class<?> beanType) {
public void clear(Class<?> rootType) {
synchronized (monitor) {
ClassContext classMap = typeCache.get(beanType);
ClassContext classMap = typeCache.get(rootType);
if (classMap != null) {
classMap.clear();
}
}
}
public void deleted(Class<?> beanType, Object id) {
public void deleted(Class<?> rootType, Object id) {
synchronized (monitor) {
ClassContext classMap = typeCache.get(beanType);
ClassContext classMap = typeCache.get(rootType);
if (classMap != null && id != null) {
classMap.deleted(id);
}
}
}
public void clear(Class<?> beanType, Object id) {
public void clear(Class<?> rootType, Object id) {
synchronized (monitor) {
ClassContext classMap = typeCache.get(beanType);
ClassContext classMap = typeCache.get(rootType);
if (classMap != null && id != null) {
classMap.remove(id);
}
@@ -123,9 +123,8 @@ public final class DefaultPersistenceContext implements PersistenceContext {
}
}
private ClassContext getClassContext(Class<?> beanType) {
private ClassContext getClassContext(Class<?> rootType) {
Class<?> rootType = PersistenceContextUtil.root(beanType);
ClassContext classMap = typeCache.get(rootType);
if (classMap == null) {
classMap = new ClassContext();
@@ -1,6 +1,7 @@
package com.avaje.ebeaninternal.server.transaction;
import com.avaje.ebean.bean.PersistenceContext;
import com.avaje.ebean.bean.PersistenceContextUtil;
import com.avaje.tests.model.basic.Car;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.Vehicle;
@@ -32,13 +33,17 @@ public class DefaultPersistenceContextTest {
return pc;
}
Class<?> root(Class<?> cls) {
return PersistenceContextUtil.root(cls);
}
@Test
public void put_get_withInheritance() throws Exception {
PersistenceContext pc = pc();
pc.put(Vehicle.class, 1, car1);
pc.put(root(Vehicle.class), 1, car1);
Object found = pc.get(Car.class, 1);
Object found = pc.get(root(Car.class), 1);
assertThat(found).isSameAs(car1);
}