Version 5.1 by smmccraw on 2007/07/08 09:44

Show last authors
1 == Overview ==
2
3 http:~/~/developer.apple.com/documentation/WebObjects/Enterprise_Objects/BusinessLogic/chapter_4_section_4.html
4
5 mmalcolm's StepWise article entitled "Data validation with WebObjects 5": http:~/~/www.stepwise.com/Articles/Technical/2001-06-13.01.html
6
7 === Jerry W. Walker ===
8
9 WO and EOF have an incredible array of validation mechanisms. Here are some notes you might find helpful:
10
11 * User interface:
12 ** prevent/discourage user from entering inappropriate data
13 * Formatters:
14 ** formatting
15 *** Only accepts data with valid format
16 ** type coercion
17 *** bad type raises exception
18 ** simple validation
19 *** raises exception and ignores value
20 *** must be different from current value or not assigned
21 *** WOComponent's validationFailedWithException(Throwable t, Object value, String keyPath)
22 **** Called when an Enterprise Object or formatter failed validation during an assignment.
23 **** The default implementation ignores the error.
24 **** Subclassers can override to resolve the error.
25 * Model
26 ** attribute constraints
27 *** checks for:
28 **** allows null
29 **** string length
30 **** numeric precision
31 **** relationship integrity
32 *** checks these before going to DB
33 ** relationship integrity constraints
34 *** optionality
35 **** for both to-one & to-many
36 *** delete rule
37 **** if source deleted, then what
38 *** ownership, owned object is:
39 **** deleted if relationship broken
40 **** created if relationship added
41 *** delete rules (if user tries to delete relationship source):
42 **** cascade - delete all destination objects too
43 **** nullify - nullify back references
44 **** deny - prohibit delete if there are destination objects
45 **** nothing - delete and ignore destination objects
46 * EO
47 ** property-level (or key-level) validation
48 *** called when a value changes
49 *** default methods in superclass check model based constraints
50 *** can be overridden for custom validation
51 *** called BEFORE EO's properties have changed
52 *** validation methods throw exception on failure
53 **** validateValueForKey("weight") triggers: public <type> validateWeight(Object newWeight) throws NSValidation.ValidationException {
54 ** object-level validation
55 *** called when saving insert/delete/update changes
56 **** public void validateForInsert() throws NSValidation.ValidationException
57 **** public void validateForUpdate() throws NSValidation.ValidationException
58 **** public void validateForDelete() throws NSValidation.ValidationException
59 *** all above in superclass by default call:
60 **** public void validateForSave() throws NSValidation.ValidationException
61 *** super's implementation calls key-level validation
62 *** called AFTER EO's properties have changed
63 ** validation performed when:
64 *** form values are pushed into EO attributes through bindings
65 *** saving changes in the editing context
66 *** called programmatically
67
68 == Changing an EO after Validation ==
69
70 Question: I would like to make a change to an EO after it has validated but before it has saved to the graph/DB. Is this possible?
71
72 === Chuck Hill ===
73
74 You don't want to do this, you should not want to do this, and the frameworks will fight you tooth and nail if you try. validateForSave is the gatekeeper for the object store. Its job is to ensure that nothing gets saved unless it has validated it. Modifying the object graph after validateForSave() finished would violate its very reason for existence.
75
76 As I see it, you have three options:
77
78 1. Do it in the component
79 1. Do it in the EO
80 1. Do it in another object
81
82 I agree that the component might not be the place to do this and I also don't like to have my EOs call saveChanges(). You might want to think of the third option, having some sort of ShiftManager object that is responsible for overseeing the closing and opening of shifts. It can provide information to the page on what is valid and what options there are and it can handle the two phase save.
83
84 Before I did that, I would consider some other options. Here are some ideas that might spark some of your own:
85
86 * Defer reseting the cash box balance until the //start// of the next shift. The last time I was a cashier (thankfully long ago) that is how it worked. You handed in your cash tray and discrepancy notes, the boss shook his head and muttered. He then recorded all that information. For the next worker, he then restocked the cash drawer. Often that did not happen until the next morning.
87
88 * Add a method to Shift like this:
89
90 {{panel}}
91
92 public void close() throws ValidationException {
93 validateForSave();
94 cashBox().resetBalance();
95 }
96
97 {{/panel}}
98
99 and in your component
100
101 {{panel}}
102
103 try {
104 shift().close();
105 ec().saveChanges();
106 }
107 catch (ValidationException v) {
108 // do the right thing
109 }
110 catch (EOGeneralAdaptorException e) {
111 // do the right thing
112 }
113
114 {{/panel}}
115
116 * I had another one, but it has slipped my mind. :-)
117
118 Category:WebObjects