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() {
* @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("Failed to ship campaign "
+ localCampaign + ". Probably another instance was sending "
* + "this
campaign to the production mail queueat the same time; AdditionalInfo: "
* +
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]