Man, does Wonder also have a method to find the meaning of life since it have 
something for everything else? :-)

> No question, put them in the database.  Use ERXEnterpriseObjectCache to avoid 
> needless repeated database trips.
> 
> Using the standard WO classes:
> 
>   /**
>     * 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 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 EOEditingContext();
>        ec.lock();
>        try
>        {
>            EOObjectStoreCoordinator osc = (EOObjectStoreCoordinator) 
> ec.rootObjectStore();
>            osc.lock();
> 
>            try
>            {
>                long timeout = // get this from a property
>                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;  **/
>    }
> 
> 
>    private static Method _setTimestampForCachedGlobalID = null;
>    /**
>     * Hack to access protected method in EODatabase.
>     * @return Method for protected void 
> _setTimestampForCachedGlobalID(EOGlobalID gid)
>     */
>    private static Method _setTimestampForCachedGlobalID()
>    {
>        synchronized (GenericRecord.class)
>        {
>            if (_setTimestampForCachedGlobalID == null)
>            {
>                try
>                {
>                    _setTimestampForCachedGlobalID = 
> EODatabase.class.getDeclaredMethod("_setTimestampForCachedGlobalID",
>                                                                               
>          new Class[] {EOGlobalID.class});
>                    _setTimestampForCachedGlobalID.setAccessible(true);
>                }
>                catch (Exception e)
>                {
>                    throw new ExceptionConverter(e);
>                }
>            }
>        }
> 
>        return _setTimestampForCachedGlobalID;
>    }
> 
> Chuck
> 
> 
> 
> On 2011-11-24, at 12:45 PM, Pascal Robert wrote:
> 
>> I want to add some "system preferences" to SimpleBlog, for things like 
>> number of comments per page, if comments are moderated or not, etc. I'm 
>> wondering what's the best way to handle that. I was thinking of using a 
>> plist and read it at "boot time" so that the preferences are in memory, and 
>> writing the file when a pref changes. The problem with this solution is that 
>> the file will have to be outside the .woa since the preferences have to 
>> survive a upgrade. And if a server have more than one SimpleBlog instance 
>> (e.g., "multi tenants"), it would have to be different files.
>> 
>> The other solution would be to store the preferences in the database. In the 
>> case of multi tenants, each instance would have to have it own databases. 
>> The potential problem would be a performance one, we would need to call EOF 
>> every time a preference is needed (for display groups, etc.). Sure, I'm not 
>> talking about high performance system here, but it would be great to show 
>> best practices.
>> 
>> So, how would you manage this?
>> _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Webobjects-dev mailing list      ([email protected])
>> Help/Unsubscribe/Update your Subscription:
>> http://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/products/practical_webobjects
> 
> 
> 
> 
> 
> 
> 

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to