I have implemented a PreUpdateEventListener to deny updates to a particular property under certain conditions.
I am unsatisfied with my current approach. I would be very grateful if somebody would suggest a more elegant approach for detecting exactly which properties are dirty in a PreUpdateEventListener (or an entirely different strategy for doing this kind of thing).
Code:
public class PreUpdateEventListener extends DefaultPreUpdateEventListener {
    public boolean onPreUpdate(PreUpdateEvent e) {
        // for a particular SMDP_TEMPLATE_COURSE, course_number updates are not
        // allowed if SMDP_RATE_CREDIT_COURSE records are present; the
        // course_number is at property index 1
        if(
            e.getEntity() instanceof TemplateCourse
            && ((TemplateCourse)e.getEntity()).getRateCreditCourses().size() > 0
            && !e.getPersister().getDatabaseSnapshot(e.getId(), e.getSession())[1]
                .equals(((TemplateCourse)e.getEntity()).getCourseNumber())
        ) {
            throw new RateCreditMaintenanceNotAllowedException();         
        }
            
        return super.onPreUpdate(e);
    }
}