Vitaliy,

Thank you very much for the working sample - I really appreciate it!!  In the end I decided to go with the approach of just projecting the property from the container into the embedded obj because it ended up being better for my particular project.  If I have to revisit this in the future because I need more than just that one property, I will definitely try out your example!

Thanks again,

Ben

Thank you all ... sometimes all it takes is a good night sleep :)

I figured out to avoid recursively updating the value via the trigger .... don't update it if I don't need to :)

Here is my code - it now works like a charm!

Trigger TUpdateFoobar [ Event = INSERT/UPDATE, Foreach = row/object, Time = AFTER ] 

  {

    Try { 

      // get value of Foobar 

      NEW fb 

      SET fb= {Foobar} 

      // INSERT value into embedded foobar, *only* if it differs from Container value

      If (fb'={InnerObj_Foobar}) {   

        &sql(UPDATE ContainerObj (InnerObj_Foobar) 

            VALUES (:fb) 

            WHERE %ID=:{ID})           

        }        

    } Catch tError {             

      Do LOG^%ETN             

      Throw tError        

    }

  }

I have been trying this approach but I am hitting a wall. It appears that because I am inserting the value into the embedded object in the container, it is seeing this as an additional UPDATE and calling the TRIGGER again, resulting in a <FRAMESTACK>.  Any ideas on how to prevent the <FRAMESTACK> error? 

Here is my simplified code:
 

Trigger TUpdateFoobar [ Event = INSERT/UPDATE, Foreach = row/object, Time = AFTER ]
{
  Try {
    // get value of Foobar
    NEW fb
    SET fb= {Foobar}

    // INSERT value into embedded Primary Environments
    &sql(UPDATE ContainerObj (InnerObj_Foobar)
     VALUES (:fb)
     WHERE %ID=:{ID})

Catch tError {
Do LOG^%ETN
Throw tError
}
}

Also, Classes lend themselves much better to programmatic access and manipulation of their content (you can do this with routines too but it is harder to do so due to their unstructured nature).

For example, the server-side Source Control hooks we use can programmatically insert an RCS Keyword as a class parameter ("SrcVer") into any class which doesn't already have it defined.   This is extremely powerful because it allows source control to create an automatic 'watermark' in every class created for our internal applications which can be programmatically access or from terminal:

SSO>write ##class(AppS.WebClient).#SrcVer
$Id: //custom_ccrs/us/ISCX/SSO/BASE/cls/AppS/WebClient.xml#6 $

This would require much more plumbing to do automatically with a routine!

Kumar,

It sounds like you are trying to use Atelier with client-side source control hooks against a shared development instance - is this correct?  If so, you are bound to experience frustration with this due to consistency issues.

Please review https://learning.intersystems.com/course/view.php?id=713 which discussed the 4 modes of development, which are to be avoided, and options available to you in a summary graphic from the training:

If you are going to be using Atelier with client-side hooks, I *strongly* recommend you move to giving each developer their own private instance to test against.

Kumar,

If you are using CCR then there are very specific  requirements in terms of development workflow which will provide assurances of no source loss, etc.  Please open a ticket with Support to discuss these specific concerns and considerations.

In summary, there can only be a single Disconnected BASE environments for each System, because the CCR Client Tools manage source concurrency within the Namespace, and if you have multiple BASE namespaces you have lost concurrency and therefore can lose source.  Atelier will work the same as Studio - you need a single Shared Dev Namespace using the CCR Client Tools (aka server-side source hooks) and at that point you can use either Atelier or Studio to edit the source in BASE.

IMPORTANT NOTE:  Server-side hooks will only work properly with Atelier if you are running a database version that includes CDS2924.  This is included in 2016.2.3+, 2017.1.2+ and 2017.2.0+ only.  If you are not sure if you have CDS2924 or not, please contact Support (if you use Atelier against a Shared Dev instance that doesn't have CDS2924 you don't have concurrency and therefore can lose source).

Hope that helps to get you started in the right direction :)