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.