Project Wonder is chocked so full of WebObjects goodness that it is hard to envision developing a project without it. Here are three bits that I use all the time.
Autolocking EditingContexts
Step one: Learn WebObjects
Step two: Realize that using the session().defaultEditingContext() exclusively is bad.
Step three: Start using multiple EOEditingContexts.
Step four: Read, re-read, then read again the documentation on EC locking.
Step five: Encounter production deadlocks.
Step six: Cry.
Thankfully Project Wonder provides an amazing solution in the form of autolocking EditingContexts. Enabling them is simple. Set some properties for your project:
er.extensions.ERXApplication.useEditingContextUnlocker=true er.extensions.ERXEC.defaultAutomaticLockUnlock=true er.extensions.ERXEC.useSharedEditingContext=false er.extensions.ERXEC.defaultCoalesceAutoLocks=true
There is an email from Mike Schrag with some juicy details here.
Change your code so that you never call new EOEditingContext();
instead use the ERXEC.newEditingContext()
factory method.
ERXThreadStorage
Problem: You need access to an object in your session from an EO. Maybe you want to set a “createdBy” value to the current user in awakeFromInsertion
Adding a reference to the Session in your EOs would be bad so what are you going to do?
Solution: Use ERXThreadStorage to store a reference to the current user and access that from your EO.
In your Session.java:
public User currentUser; // assume exists public void awake() { super.awake(); ERXThreadStorage.takeValueForKey(currentUser, "currentUser"); }
In your EO.java:
public void awakeFromInsertion(EOEditingContext ec) { super.awakeFromInsertion(ec); User user = ERXThreadStorage.valueForKey("currentUser")); if (user != null) { setCreatedBy(user.userName); } }
ERXGenericRecord
ERXGenericRecord is another Project Wonder class that is full of yumminess. Please read the API docs for the full details, but here are a few of my favorites:
willUpdate(); // called after saveChanges() but before validation // so it is safe to make changes. See the rest of // will* and did* methods for more primaryKey(); // returns the primary key (null if the EO hasn't // been saved yet) primaryKeyInTransaction(); // returns the primary key as above, // but if the EO hasn't beens saved yet, it'll // figure out what the pk should be, return it, // cache it, and use it later when the EO does get // saved. Very cool.
There is much, much more: ERXLocalizer, ERJavaMail, ERExcelLook… Dive into the docs and I’m sure you’ll find something usefull.