mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-24 15:55:55 +00:00
#595 - Refactor - persistence context root type handling - fully expect root type
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+13
-14
@@ -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();
|
||||
|
||||
+7
-2
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user