On May 9, 2008, at 10:08 AM, Florijan Stamenkovic wrote:
I dealt with this issue by adding the following code in my abstract root... It avoids the pitfall you mention. One must be careful however that *every* subclass implements _getType() because the compiler will not complain as long as any of the super-classes have this.
public void awakeFromInsertion(...){
super...
setType(_getType());
}
public abstract Integer _getType();
Now, they don't explain why it's important for JC, but I _think_ the client-side EditingContext acts something like a nested EC to the server EC, so when you copy the client-side EC back to the server, the EO is getting "inserted" again into the server-side EC, and _I believe_ awakeFromInsertion gets called on the server again. If you've already set the value of the attribute on the client (and not necessarily to what awakeFromInsertion will set) then when it shows up on the server, it gets overridden by the server-side awakeFromInsertion. Yuck.
As far as the weirdness goes, other than values getting overridden unintentionally, the problems that I ran into were errors with the Undo Manager any time I tried to delete an instance of a class that had awakeFromInsertion called without first checking if the value was null.
I've also been thinking about what you say below, adding awakeFromInsertion(...) both on the client and the server, and that makes no sense to me. I mean, I only insert EOs on the client, which then get transferred to the server. In what kind of a setup did you experience this weirdness?
If you only insert on the client, then you're probably fine, but that seems pretty short-term because the whole idea of the client-server nature of JC is that some things you do on the client, some things you do on the server and eventually you'll be inserting something on the server-side first and you want to make sure you are initializing things the same way in both places and not overriding what one sets with values from the other, so I consider it a JC best-practice to always have the awakeFromInsertion methods match on the client and server, and only call the setters if they are currently null (or were set incorrectly in the super).
Along these lines, I have some complicated functions that instead of moving large amounts of EOs down to the client and performing the function there, I run them on the server-side where EOF has easy access to the DB and EOF automatically pushes any updates down to the client. Any new instances that were created on the server will then be copied down to the client, and _I think_ get awakeFromInsertion called on them again.
Now, If I had a common class that both the Server and Client classes extended I'd put it there so I wouldn't have duplicate code, but until Mike gets off his lazy butt and finishes adding support for a common parent class to EntityModeler and Veogen I have to put the same awakeFromInsertion call on both sides. ;-)
Again, I'm not 100% certain about the way in which EOF manages the object graph and EditingContexts across the server-client gap, but these are my best guesses to date.