From 49121a9c1f702150bfdeabb86a34c1104583c12b Mon Sep 17 00:00:00 2001 From: Robin Bygrave Date: Fri, 11 Mar 2016 20:54:57 +1300 Subject: [PATCH] #595 - Refactor - persistence context root type handling - fully expect root type --- .../avaje/ebean/bean/PersistenceContext.java | 12 ++++----- .../server/core/DefaultServer.java | 15 ++++++----- .../server/core/PersistRequestBean.java | 6 ++--- .../server/deploy/BeanDescriptor.java | 21 +++++++++++++++ .../server/persist/DefaultPersister.java | 4 +-- .../ebeaninternal/server/query/CQuery.java | 2 +- .../DefaultPersistenceContext.java | 27 +++++++++---------- .../DefaultPersistenceContextTest.java | 9 +++++-- 8 files changed, 60 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/avaje/ebean/bean/PersistenceContext.java b/src/main/java/com/avaje/ebean/bean/PersistenceContext.java index a49f76fb7..6e67034e2 100644 --- a/src/main/java/com/avaje/ebean/bean/PersistenceContext.java +++ b/src/main/java/com/avaje/ebean/bean/PersistenceContext.java @@ -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. diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java index a87c95ee6..707fc4859 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java +++ b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java @@ -1065,31 +1065,32 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { if (t == null) { t = getCurrentServerTransaction(); } - PersistenceContext context = null; + + BeanDescriptor 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 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); } /** diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java b/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java index 9b4ec4ca3..d48b5e755 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java +++ b/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java @@ -698,7 +698,7 @@ public final class PersistRequestBean 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 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); } diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java index dbeec00f1..8fbee99a0 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java @@ -1675,6 +1675,13 @@ public class BeanDescriptor implements MetaBeanInfo, BeanType { 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 implements MetaBeanInfo, BeanType { 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 diff --git a/src/main/java/com/avaje/ebeaninternal/server/persist/DefaultPersister.java b/src/main/java/com/avaje/ebeaninternal/server/persist/DefaultPersister.java index fc7bf1315..63c7f9b3a 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/persist/DefaultPersister.java +++ b/src/main/java/com/avaje/ebeaninternal/server/persist/DefaultPersister.java @@ -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; } diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/CQuery.java b/src/main/java/com/avaje/ebeaninternal/server/query/CQuery.java index cbd2c2156..523981f58 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/CQuery.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/CQuery.java @@ -394,7 +394,7 @@ public class CQuery 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; } diff --git a/src/main/java/com/avaje/ebeaninternal/server/transaction/DefaultPersistenceContext.java b/src/main/java/com/avaje/ebeaninternal/server/transaction/DefaultPersistenceContext.java index d54659b8e..b989605df 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/transaction/DefaultPersistenceContext.java +++ b/src/main/java/com/avaje/ebeaninternal/server/transaction/DefaultPersistenceContext.java @@ -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(); diff --git a/src/test/java/com/avaje/ebeaninternal/server/transaction/DefaultPersistenceContextTest.java b/src/test/java/com/avaje/ebeaninternal/server/transaction/DefaultPersistenceContextTest.java index 380dcc9d8..dd2a13ff3 100644 --- a/src/test/java/com/avaje/ebeaninternal/server/transaction/DefaultPersistenceContextTest.java +++ b/src/test/java/com/avaje/ebeaninternal/server/transaction/DefaultPersistenceContextTest.java @@ -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); }