I am not sure, but here is how I have been using it:
/**
* Creates a standard EO cache object for the passed entity name and
keypath for all objects of
* the entity that match restrictingQualifier. If restrictingQualifier is
null, all objects of this entity are
* cached.
*
* @param entityName name of the EOEntity for the instances that will be in
the cache
* @param keyPath key path of unique value in EOs
* @param restrictingQualifier EOQualifier restricting the set of objects
in the cache
* @param shouldFetchInitialValues true if the cache should be fully
populated on first access
* @return a Cadre standard EO cache object for the passed entity name and
keypath
*/
public static ERXEnterpriseObjectCache createCache(String entityName,
String keyPath, EOQualifier restrictingQualifier, boolean
shouldFetchInitialValues) {
/** require [valid_entityName] entityName != null;
[valid_keyPath] keyPath != null;
**/
EOEditingContext ec = new CadreEditingContext();
ec.lock();
try
{
EOObjectStoreCoordinator osc = (EOObjectStoreCoordinator)
ec.rootObjectStore();
osc.lock();
try
{
long timeout =
WOApplication.appProperties().longPropertyForKey(CadreApplication.ERXEnterpriseObjectCacheTimeoutInMinutes)
* 60 * 1000;
boolean shouldRetainObjects = true;
boolean shouldReturnUnsavedObjects = true; // Needed for
imports where new objects reference other new objects
ERXEnterpriseObjectCache cache = new
ERXEnterpriseObjectCache(entityName, keyPath, restrictingQualifier, timeout,
shouldRetainObjects, shouldFetchInitialValues, shouldReturnUnsavedObjects);
/**
* OK, things get nasty here. You HAVE been warned!
*
* The cache has an interaction with the EOEditingContext
fetchTimestamp()/defaultFetchTimestampLag(). After
* the objects have been fetched into the cache, if the
defaultFetchTimestampLag() passes before they are
* re-fetched, when they are faulted into a new editing context
(localInstanceOfObject), the snapshot will be discarded
* and the objects re-fetched, one by one. This rather
eliminates the value of the cache.
*
* There are a few options to fix this:
* - use a large defaultFetchTimestampLag() and ensure that all
the places that need fresh data use
* a fetch specification that refreshes re-fetched objects.
This also means that you must pre-fetch all
* the objects that need fresh data. This makes the
defaultFetchTimestampLag() rather useless to control
* data freshness.
*
* - use a large defaultFetchTimestampLag() and implement
ERChangeNotification to keep all the EOF stacks
* in sync. This ensures current data without needing to use
defaultFetchTimestampLag().
*
* - use a custom EODatabaseContext.delegate and implement the
delegate method
* databaseContextShouldFetchObjectFault(EODatabaseContext,
Object) to use the existing snapshot regardless of age.
* To implement this, the delegate will need to know that the
entity is being cached. This can be done by setting
* a flag in EOEntity.userInfo in this method.
*
* - make the objects as "Cache in Memory" in the EOModel. The
large drawback of this is that the objects will never
* be refreshed. Refreshing fetch specifications do not
affect entities cached in memory.
*
* - mark the snapshots of the cached objects as expiring at
some time in the distant future. As they expire from the
* cache they will be re-fetched and refreshed from the
database. This option was chosen as it more closely matches
* what should happen. It does require access to a protected
method in EODatabase. It is possible that future
* versions of WebObjects will break this implementation, but
there should be some way of achieving the result.
*/
EOEntity entity = EOUtilities.entityNamed(ec, entityName);
EODatabaseContext dbContext =
EOUtilities.databaseContextForModelNamed(ec, entity.model().name());
EODatabase database = dbContext.database();
NSArray objectsInCache = cache.allObjects(ec);
for (int i = 0; i < objectsInCache.count(); i++)
{
EOEnterpriseObject eo = (EOEnterpriseObject)
objectsInCache.objectAtIndex(i);
// Sets the expiration timestamp for the snapshot to
NSTimestamp.DistantFuture.getTime()
_setTimestampForCachedGlobalID().invoke(database,
ec.globalIDForObject(eo));
}
return cache;
}
catch (Exception e)
{
throw new ExceptionConverter(e);
}
finally
{
osc.unlock();
}
}
finally
{
ec.unlock();
ec.dispose();
}
/** ensure [valid_result] Result != null; **/
}
On 2013-02-05, at 10:57 AM, JR Ruggentaler wrote:
> I added a ERXEnterpriseObjectCache to my entity and when some of my old code
> tries to query the database instead of using the cache EOF throws the
> following exception. If I defer loading the cache
> (shouldFetchInitialValues=false) everything works. Is this a Wonder, EOF,…
> bug?
>
> [2013-02-04 15:41:16,593] <performWork> ERROR Exception:
> java.lang.NullPointerException - null
> NullPointerException
> at
> com.webobjects.eoaccess.EODatabaseContext._objectFaultWithSnapshotRelationshipEditingContext(EODatabaseContext.java:2356)
> ... skipped 2 stack elements
> at
> com.webobjects.eocontrol.EOObjectStoreCoordinator.initializeObject(EOObjectStoreCoordinator.java:597)
> at
> com.webobjects.eocontrol.EOEditingContext.initializeObject(EOEditingContext.java:3768)
> at er.extensions.eof.ERXEC.initializeObject(ERXEC.java:1141)
> ... skipped 3 stack elements
> at
> com.webobjects.eocontrol.EOObjectStoreCoordinator.objectsWithFetchSpecification(EOObjectStoreCoordinator.java:488)
> at
> com.webobjects.eocontrol.EOEditingContext.objectsWithFetchSpecification(EOEditingContext.java:4069)
> at er.extensions.eof.ERXEC.objectsWithFetchSpecification(ERXEC.java:1206)
> at
> com.webobjects.eocontrol.EOEditingContext.objectsWithFetchSpecification(EOEditingContext.java:4444)
> at com.mpv.mapload.Handler.loadingContextWillLoadObject(Handler.java:312)
> at com.mpv.mapload.LoadingContext.willLoadObject(LoadingContext.java:930)
> at com.mpv.mapload.LoadingContext.load(LoadingContext.java:737)
> at com.mpv.agent.loaderagent.LoaderAgent.performWork(LoaderAgent.java:154)
> at com.mpv.agent.MPVAgent._performWork(MPVAgent.java:310)
> at com.mpv.agent.MPVAgent$MPVAgentTask._run(MPVAgent.java:198)
> at er.extensions.concurrency.ERXTimerTask.run(ERXTimerTask.java:25)
> at java.util.TimerThread.mainLoop(Timer.java:512)
> at java.util.TimerThread.run(Timer.java:462)
>
> Here is the code that adds the cache to the entity.
>
> public static class Util<T extends UserGroup> extends _UserGroup.Util<T> {
> /**
> * UserGroup are static and stored in a lookup table. We use a cache
> * to provide quick access to them. The cache is keyed by the userGroupID
> * property.
> */
> ERXEnterpriseObjectCache<T> _userGroupIDCache = new
> ERXEnterpriseObjectCache<T>(
> UserGroup.ENTITY_NAME, UserGroup.USER_GROUP_ID_KEY);
>
> /**
> * Returns the UserGroup instance whose userGroupID property is equal to
> <code>value</code>.
> * The UserGroup is localized into the provided editing context.
> *
> * @param ec
> *
> editing context in which the returned UserGroup instance is to live
> * @param value
> *
> UserGroup that is sought
> * @return the UserGroup instance whose userGroupID property matches
> <code>userGroupID</code>
> */
> public T findUserGroupForUserGroupID(EOEditingContext ec, Integer value) {
> return _userGroupIDCache.objectForKey(ec, value);
> }
>
> }
>
> JR
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Webobjects-dev mailing list ([email protected])
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/webobjects-dev/chill%40global-village.net
>
> This email sent to [email protected]
--
Chuck Hill Senior Consultant / VP Development
Practical WebObjects - for developers who want to increase their overall
knowledge of WebObjects or who are trying to solve specific problems.
http://www.global-village.net/gvc/practical_webobjects
Global Village Consulting ranks 13th in 2012 in BIV's Top 100 Fastest Growing
Companies in B.C!
Global Village Consulting ranks 76th in 24th annual PROFIT 200 ranking of
Canada’s Fastest-Growing Companies by PROFIT Magazine!
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com
This email sent to [email protected]