Hi Robert and Johan,

First of all, DON'T DO IT!!! For the love of God and all that is good and kind 
in this world, don't do it! 

If you won't not do it for me, then don't do it for Chuck and all the little 
fluffy bunnies!

Don't mark fetch specs as shared! Turn off the shared EC, walk away and don't 
look back.

The EOSharedEditingContext (EOSEC) is evil. Evil, EVIL, E-V-I-L! And not in an 
obvious, spawn-of-satan way, oh no, it is far more subtle than that. There are 
lots of things that either don't work, or work differently when an EO is shared 
and none of them are obvious. You have to always keep in mind that the object 
you are working with is in the EOSEC and often do things differently. It 
completely ignores the fundamental concept of polymorphism. 

For example, let's say you want to edit the name of a Country, which is a 
shared. You can't just edit it in the EOSEC because EOSEC#saveChanges() raises 
an exception. You have to localInstance it into a standard EC first do your 
editing and save it there. But even that's not as easy as it sounds. Here's a 
fun exercise:

EOEditingContext newEC = ERXEC.newEditingContext();
country = country.localInstanceIn(newEC);

What editing context is the country in? newEC? Nope. It's still in the EOSEC. 
Obvious, right? Welcome to the nightmare.

First you have to call: newEC.setSharedEditingContext(null); before 
localInstanceIn will work.

ERXEC's auto-locking is one of the many things that does not take the 
EOSharedEditingContext into account. You will have to _manually_ lock and 
unlock all calls to the EOSharedEditingContext  except (according to the 
documentation):
objectsWithFetchSpecification 
bindObjectsWithFetchSpecification
faultForGlobalID 
objectForGlobalID 
Do yourself a HUGE favor and use EREnterpriseObjectCache instead 
(http://jenkins.wocommunity.org/job/Wonder/lastSuccessfulBuild/javadoc/er/extensions/eof/ERXEnterpriseObjectCache.html).
 It is much, much, much better. It has a few flaws as well, but an EO that came 
out of the EREnterpriseObjectCache is a regular EO and can be passed around and 
edited the same as any other EO, which is absolutely NOT the case with an EO 
that is in an EOSharedEditingContext.

Do not use it! You will spend a huge amount of time writing extra code to make 
it work.

What? Still here? You have a strong masochistic streak? Well, okely dokely 
then, here we go:

I have a patch but unfortunately it's really not ready for prime-time, but I've 
included the code (as-is) below. 

The core piece of it is to modify ERXApplication#migrationsWillRun(ERXMigrator) 
and ERXApplication#migrationsDidRun(ERXMigrator) as follows:

        private boolean _isSharedObjectLoadingEnabledCachedValue;

        protected void migrationsWillRun(ERXMigrator migrator) {
                _isSharedObjectLoadingEnabledCachedValue = 
ERXDatabaseContext.isSharedObjectLoadingEnabled();
                if (EODatabaseContext.isSharedObjectLoadingEnabled()) {
                        EODatabaseContext.setSharedObjectLoadingEnabled(false);
                }
        }
        
        protected void migrationsDidRun(ERXMigrator migrator) {
                if (_isSharedObjectLoadingEnabledCachedValue) {
                        EODatabaseContext.setSharedObjectLoadingEnabled(true);
                        EOSharedEditingContext sharedEC = 
EOSharedEditingContext.defaultSharedEditingContext();
                        ERXDatabaseContext.loadSharedObjects(sharedEC);
                }
        }

But unfortunately, because the initial database access occurred while shared 
object loading was disabled, now EOF won't automatically load the shared 
objects for you. You have to manually load it. I've added the method below to 
ERXDatabaseContext. It will load/reload all the shared entities (you can see I 
call it as the last thing in the migrationsDidRun method above).

        public static final String FETCH_ALL_FETCH_SPEC_NAME = "FetchAll";

        /**
         * Method to manually load (or reload) all shared EOs by iterating 
through all the models
         * 
         * @param sharedEC
         * 
         * @author David Avendasora
         * @since Jul 13, 2012
         */
        public static synchronized void 
loadSharedObjects(EOSharedEditingContext sharedEC) {
                EOModelGroup modelGroup = EOModelGroup.defaultGroup();
                NSArray<EOModel> models = modelGroup.models().immutableClone();
                for (EOModel model : models) {
                        String modelFileName = model.name() + ".eomodeld";
                        NSArray<EOEntity> entitiesWithSharedObjects = 
model.entitiesWithSharedObjects().immutableClone();
                        for (EOEntity entity : entitiesWithSharedObjects) {
                                String entityFileName = modelFileName + 
File.pathSeparator + entity.name() + ".plist";
                                NSArray<String> sharedObjectFetchSpecNames = 
entity.sharedObjectFetchSpecificationNames();
                                if 
(sharedObjectFetchSpecNames.containsObject(FETCH_ALL_FETCH_SPEC_NAME)) {
                                        sharedObjectFetchSpecNames = new 
NSArray<String>(FETCH_ALL_FETCH_SPEC_NAME);
                                }
                                for (String fetchSpecName : 
sharedObjectFetchSpecNames) {
                                        String fetchSpecFileName = 
modelFileName + File.pathSeparator + entity.name() + ".fspec";
                                        EOFetchSpecification fetchSpec = 
entity.fetchSpecificationNamed(fetchSpecName);
                                        if (fetchSpec != null) {
                                                // no need to lock because the
                                                // 
bindObjectsWithFetchSpecification(EOFetchSpecification, String)
                                                // method is thread safe.
                                                
sharedEC.bindObjectsWithFetchSpecification(fetchSpec, fetchSpecName);
                                        }
                                        else {
                                                log.warn("Problem found in 
Entity \"" + entity.name() + "\": \"" 
                                                                + fetchSpecName 
+ "\" is listed in the \"sharedObjectFetchSpecificationNames\" element of the 
\"" 
                                                                + 
entityFileName + "\" file, but there is no corresponding \"" 
                                                                + fetchSpecName 
+ "\" element in the \"" 
                                                                + 
fetchSpecFileName + "\" file.");
                                        }
                                }
                        }
                }
        }

I'm not 100% sure I'm doing the right thing with regards to loading the 
modelGroup and models … I'm not as comfortable down at this level of EOF as I 
probably should be. It works, but it might now work for everyone.

Now if I could just scrub hard enough to get this dirty feeling to go away.

Dave

On Jul 15, 2012, at 2:30 PM, Johann Werner wrote:

> I saw a patch for exactly that problem recently in the fork of amagavi. 
> Hopefully there will be a pull request soon (hi David, are you reading this 
> ;-)
> 
> jw
> 
> 
> Am 15.07.2012 um 07:52 schrieb Mr. Robert Hanviriyapunt:
> 
>> I had some issues with Migrations just now when I made an entity Shared.  
>> The application started up and attempted to load the shared entity before 
>> Migrations could create the table for it.  Anyone else had the same problem? 
>>  My work around was to de-select Shared for the entity, start up the 
>> application, stop the application, re-select Shared for the entity, then 
>> re-start the application.  Gonna be a pain if I have to do this on for a 
>> deploy to a stage or prod environment tho.
>> 
>> = Robert =
> 
> 
> 
> _______________________________________________
> 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/webobjects%40avendasora.com
> 
> This email sent to [email protected]
> 
> 


—————————————————————————————
WebObjects - so easy that even Dave Avendasora can do it!™
—————————————————————————————
David Avendasora
Senior Software Abuser
Kaiten, Inc.




 _______________________________________________
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]

Reply via email to