Just throwing this out there into the mix of replies....... this is unaltered 
copy/paste from production code ..... YMMV ...   (btw, the OptimisticLockAction 
makes sure that another thread does not create at the same time)

        /**
         * @return CTTextBlob lazily created textTemplate relationship. If
         *         mediaTemplate exists, this creates and saves the related 
initial
         *         object in an optimistic fashion.
         */
        public CTTextBlob textTemplateAutoCreate() {
                CTTextBlob textTemplate = super.textTemplateObject();
                if (textTemplate == null) {
                        if (isNewObject()) {
                                textTemplate = 
CTTextBlob.createInstance(editingContext());
                                super.setTextTemplateObject(textTemplate);
                        } else {
                                // existing Object
                                final CTMediaTemplate t = this;
                                WKEOUtils.OptimisticLockAction action = new 
WKEOUtils.OptimisticLockAction() {
                                        @Override
                                        protected Object 
doPerform(EOEditingContext ec) {
                                                CTMediaTemplate localTemplate = 
t.localInstanceIn(ec);
                                                CTTextBlob textBlob = 
CTTextBlob.createInstance(ec);
                                                
localTemplate.setTextTemplateObject(textBlob);
                                                ec.saveChanges();
                                                return 
textBlob.localInstanceIn(t.editingContext());
                                        };
                                };

                                try {
                                        textTemplate = (CTTextBlob) 
action.perform(editingContext().rootObjectStore());
                                } catch (Exception e) {
                                        throw new NestableRuntimeException(e);
                                }
                        } // ~ if (isNewObject())
                }
                return textTemplate;
        }



FYI, here is the OptimisticLockAction utility code......

        /**
         * Deals with the nitty-gritty of a critical 
<strong>short-running</strong>
         * task where we depend on optimistic locking to guarantee that another
         * process does not change optimistic locking attributes at the same 
time. To
         * understand why this is necessary, read this: 
         * {...@link http://terminalapp.net/dr-optimistic-locking/}. 
         * 
         * Wraps the actions in
         * appropriate locks. WARNING: The OSC is locked for the period of the
         * transaction. All EOF access on this OSC is blocked. Do not use this 
for
         * actions that take more than a few milliseconds on OSC's that are 
being
         * used by request threads!
         * 
         * Code design inspired by {...@link ERXEOAccessUtilities.ChannelAction}
         * 
         * Example of usage
         * 
         * <pre>
         * OptimisticLockAction action = new WKEOUtils.OptimisticLockAction() {
         *      &#064;Override
         *      protected Object doPerform(EOEditingContext 
actionEditingContext) {
         *              CTCampaign localCampaign = (CTCampaign) 
actionEditingContext.faultForGlobalID(gid, actionEditingContext);
         *              try {
         *                      // Ship it
         *                      localCampaign.shipMessages();
         *                      actionEditingContext.saveChanges();
         *              } catch (EOGeneralAdaptorException e) {
         *                      String additionalInfo = 
WKEOUtils.generalAdaptorExceptionInfo(e);
         *                      log.error(&quot;Failed to ship campaign &quot; 
+ localCampaign + &quot;. Probably another instance was sending &quot;
         *                                                      + &quot;this 
campaign to the production mail queueat the same time; AdditionalInfo: &quot;
         *                                                      + 
additionalInfo, e);
         *              }
         *              return null;
         *      }
         * };
         * 
         * try {
         *      action.perform(parentObjectStore());
         * } catch (Exception e) {
         *      throw new RuntimeException(e);
         * }
         * </pre>
         * 
         * @author kieran
         */
        public static abstract class OptimisticLockAction {

                /**
                 * This method is called in a new locked editing context that 
has been
                 * created in the osc passed in. Perform your changes in this 
editing
                 * context. Any errors will be thrown. Return any result you 
want.
                 * 
                 * @param osc
                 */
                protected abstract Object doPerform(EOEditingContext ec);

                public Object perform() throws Exception {
                        return perform(null);
                }

                /**
                 * @param osc
                 *            the root object store to be locked so that true 
optimistic
                 *            locking can be enforced.
                 * @return the result of your doPerform method implementation
                 * @throws Exception
                 */
                public Object perform(EOObjectStore osc) throws Exception {
                        osc.lock();
                        try {
                                EOEditingContext ec = 
WKEOUtils.newManualLockingEditingContext(osc);
                                ec.lock();
                                try {
                                        // Don't use stale EO's to begin with
                                        
ec.setFetchTimestamp(System.currentTimeMillis());
                                        return doPerform(ec);
                                } catch (Exception e) {
                                        throw e;
                                } finally {
                                        ec.unlock();
                                        ec.dispose();
                                }
                        } catch (Exception e) {
                                throw e;
                        } finally {
                                osc.unlock();
                        }
                }
        }


On Feb 23, 2010, at 11:55 AM, Jon Nolan wrote:

> Is this sane and safe?
> 
>   public Properties properties() {
>       Properties properties = super.properties();
>       if (properties == null) {
>           properties = Properties.createProperties(editingContext());
>           setPropertiesRelationship(properties);
>       }
>       return properties;
>   }
> 
> Seems to work fine and suits my needs perfectly but it makes me uneasy.
> 
> Thanks,
> Jon
> 
> _______________________________________________
> 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/kieran_lists%40mac.com
> 
> This email sent to [email protected]

 _______________________________________________
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