From f089457f2a6d712f1bf92c4d3ffc4866f54f5ec1 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Sun, 3 Jun 2007 01:39:33 +0000 Subject: Prevent premature uncaching of StorableInfo. --- .../carbonado/info/StorableIntrospector.java | 43 ++++++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java b/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java index 0fd427d..ce704e3 100644 --- a/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java +++ b/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java @@ -223,15 +223,24 @@ public class StorableIntrospector { primaryKey, alternateKeys, type.getAnnotation(Independent.class) != null, type.getAnnotation(Authoritative.class) != null); + cCache.put(type, new SoftReference>(info)); + // Now that the StorableInfo object has been constructed, assign it + // to all properties to prevent it from being prematurely uncached. + for (StorableProperty property : properties.values()) { + if (property instanceof SimpleProperty) { + ((SimpleProperty)property).setEnclosingInfo(info); + } + } + // Finish resolving join properties, after properties have been // added to cache. This makes it possible for joins to (directly or // indirectly) reference their own enclosing type. If not resolved // late, then there would be a stack overflow. for (StorableProperty property : properties.values()) { if (property instanceof JoinProperty) { - ((JoinProperty)property).resolveJoin(errorMessages, info); + ((JoinProperty)property).resolveJoin(errorMessages); } } @@ -241,7 +250,7 @@ public class StorableIntrospector { for (StorableProperty property : properties.values()) { if (property instanceof SimpleProperty && property.isDerived()) { anyDerived = true; - ((SimpleProperty)property).resolveDerivedFrom(errorMessages, info); + ((SimpleProperty)property).resolveDerivedFrom(errorMessages); } } @@ -1573,6 +1582,11 @@ public class StorableIntrospector { // Resolved derived to properties. private ChainedProperty[] mDerivedTo; + // Reference to enclosing StorableInfo. This reference exists to + // prevent the StorableInfo from being uncached so as long as a + // reference from a property exists. + protected StorableInfo mEnclosingInfo; + SimpleProperty(BeanProperty property, Class enclosing, boolean nullable, boolean primaryKey, boolean alternateKey, String[] aliases, StorablePropertyConstraint[] constraints, @@ -1822,7 +1836,11 @@ public class StorableIntrospector { app.append('}'); } - void resolveDerivedFrom(List errorMessages, StorableInfo info) { + void setEnclosingInfo(StorableInfo info) { + mEnclosingInfo = info; + } + + void resolveDerivedFrom(List errorMessages) { Derived derived = mDerived; // Don't need this anymore. mDerived = null; @@ -1840,7 +1858,7 @@ public class StorableIntrospector { for (String fromName : fromNames) { ChainedProperty from; try { - from = ChainedProperty.parse(info, fromName); + from = ChainedProperty.parse(mEnclosingInfo, fromName); } catch (IllegalArgumentException e) { errorMessages.add ("Cannot find derived-from property: \"" + @@ -1885,8 +1903,7 @@ public class StorableIntrospector { if (lastInChain.isDerived()) { // Expand derived dependencies. - ((SimpleProperty) lastInChain) - .resolveDerivedFrom(errorMessages, examine(lastInChain.getEnclosingType())); + ((SimpleProperty) lastInChain).resolveDerivedFrom(errorMessages); for (ChainedProperty lastFrom : lastInChain.getDerivedFromProperties()) { ChainedProperty dep; if (trimmed == null) { @@ -2109,7 +2126,7 @@ public class StorableIntrospector { * Finishes the definition of this join property. Can only be called once. */ @SuppressWarnings("unchecked") - void resolveJoin(List errorMessages, StorableInfo info) { + void resolveJoin(List errorMessages) { StorableInfo joinedInfo; try { joinedInfo = examine(getJoinedType()); @@ -2150,7 +2167,7 @@ public class StorableIntrospector { // Verify that internal properties exist and are not themselves joins. for (int i=0; i internalPrimaryKey = - new HashSet(info.getPrimaryKeyProperties().values()); + Set internalPrimaryKey = new HashSet + (mEnclosingInfo.getPrimaryKeyProperties().values()); for (int i=0; i altKey = new HashSet(); - for (OrderedProperty op : info.getAlternateKey(i).getProperties()) { + for (OrderedProperty op : + mEnclosingInfo.getAlternateKey(i).getProperties()) + { ChainedProperty chained = op.getChainedProperty(); if (chained.getChainCount() > 0) { // Funny alt key. Pretend it does not exist. -- cgit v1.2.3