Wiki source code of Programming__WebObjects-EOF-Using EOF-Problems
Version 1.1 by smmccraw on 2007/07/08 09:44
Show last authors
author | version | line-number | content |
---|---|---|---|
1 | = Problems = | ||
2 | |||
3 | This section describes some problems and bugs that sometimes occur when using //Enterprise Objects Framework//. | ||
4 | |||
5 | == EOF fails to initialize models when not specifically ordered == | ||
6 | |||
7 | **Authors:** Francis Labrie | ||
8 | |||
9 | **Affected products:** //WebObjects// 5.2.x, 5.3.x | ||
10 | |||
11 | **Bug reference:** rdar:~/~/4571773 | ||
12 | |||
13 | === Problem: === | ||
14 | |||
15 | Sometimes when having several data models using shared objects in a //WebObjects// application, models load, initialization and connection simply fail with strange and unexpected exceptions. Typical exceptions are: | ||
16 | |||
17 | * {{code}}java.lang.IllegalStateException: registeredDatabaseContextForModel() Cannot register the database context for the model {{/code}}//<Model name>// | ||
18 | |||
19 | {{code}}at com.webobjects.eoaccess.EODatabaseContext.registeredDatabaseContextForModel(EODatabaseContext.java:1145) {{/code}} | ||
20 | |||
21 | ... | ||
22 | |||
23 | * {{code}}java.lang.IllegalStateException: addOrderByAttributeOrdering: attempt to generate SQL for com.webobjects.eocontrol.EOSortOrdering <class com.webobjects.eocontrol.EOSortOrdering({{/code}}//<Attribute Name>//{{code}} compareAscending)> failed because attribute identified by key '{{/code}}//<Attribute Name>//{{code}}' was not reachable from from entity '{{/code}}//<Entity Name>//{{code}}'{{/code}} | ||
24 | |||
25 | {{code}}at com.webobjects.eoaccess.EOSQLExpression.addOrderByAttributeOrdering(EOSQLExpression.java:1803) {{/code}} | ||
26 | |||
27 | ... | ||
28 | |||
29 | * //etc.// | ||
30 | |||
31 | I saw several report of this bug in various mailing list, but no one leads to a right solution or a good explanation: | ||
32 | |||
33 | http:~/~/lists.apple.com/archives/webobjects-dev/2005/Aug/msg00295.html | ||
34 | http:~/~/www.wodeveloper.com/omniLists/webobjects-dev/2004/September/msg00255.html | ||
35 | |||
36 | === Solution: === | ||
37 | |||
38 | I've finally found that this problem is related to the models load and initialization order. Most of the time, EOF is able to initialize a group of models flawlessly. But in some circumstances, it just fails. | ||
39 | |||
40 | The best fix would be to make EOF dynamically analyse models groups, building a graph of dependancy with all entities for each group and ordering the models and the entities initializations according to this graph. But a such solution is a little bit more complex and should typically be integrated directly into the EOAccess layer. | ||
41 | |||
42 | To work around this bug with a simpler solution, you can add in the {{code}}userInfo{{/code}} dictionary of each model the {{code}}priority{{/code}} key assigned to a value of four digit, example: {{code}}0100{{/code}}, {{code}}0500{{/code}}, {{code}}2000{{/code}}, //etc.// You must use priority values with the same number of digit, because these will be converted to strings, and if you set a priority of {{code}}500{{/code}}, the string value will be considered as higher than a priority of {{code}}1000{{/code}}. | ||
43 | |||
44 | Then create a static method that perform an {{code}}assertConnectionDictionaryIsValid(){{/code}} with each model of the group sorted by priority: | ||
45 | |||
46 | {{code}} | ||
47 | |||
48 | private static final NSArray _PriorityDescendingModelSortOrdering = new NSArray(new Object[] { | ||
49 | EOSortOrdering.sortOrderingWithKey("userInfo.priority", EOSortOrdering.CompareDescending), | ||
50 | EOSortOrdering.sortOrderingWithKey("name", EOSortOrdering.CompareAscending) | ||
51 | }); | ||
52 | |||
53 | ... | ||
54 | |||
55 | public static void assertModelGroupConnectionDictionariesAreValid(EOEditingContext editingContext, EOModelGroup modelGroup) { | ||
56 | Enumeration models; | ||
57 | EOAdaptor adaptor; | ||
58 | EODatabaseContext databaseContext; | ||
59 | EOModel model; | ||
60 | |||
61 | // Get models enumerator from default group | ||
62 | models = EOSortOrdering.sortedArrayUsingKeyOrderArray(modelGroup.models(), | ||
63 | _PriorityDescendingModelSortOrdering).objectEnumerator(); | ||
64 | |||
65 | while(models.hasMoreElements()) { | ||
66 | model = (EOModel)models.nextElement(); | ||
67 | NSLog.debug.appendln(" Connecting " + model.name() + " model, userInfo = " + model.userInfo() + "..."); | ||
68 | databaseContext = EODatabaseContext.registeredDatabaseContextForModel(model, editingContext); | ||
69 | adaptor = databaseContext.adaptorContext().adaptor(); | ||
70 | |||
71 | // Test connection dictionary | ||
72 | adaptor.assertConnectionDictionaryIsValid(); | ||
73 | NSLog.debug.appendln(" The \"" + model.name() + "\" model is connected."); | ||
74 | } // while | ||
75 | } // assertConnectionDictionariesAreValid | ||
76 | |||
77 | {{/code}} | ||
78 | |||
79 | The sort ordering here sort by descending model priority and ascending model name to ensure constancy on sort result. | ||
80 | |||
81 | You'll have to find the right model order: you can deduce it with logic drawing a dependency graph, or you can find it with tests and errors. Typically, when an exception has above is thrown, it's because the model initialization was done too late. I usually set priority to framework models from {{code}}1000{{/code}} (low) to {{code}}9000{{/code}} (high), and application models from {{code}}0100{{/code}} (low) to {{code}}0900{{/code}} (high). | ||
82 | |||
83 | === Exception: === | ||
84 | |||
85 | For some cases, this solution still does't help (see [[this message>>http://lists.apple.com/archives/Webobjects-dev/2006/Oct/msg00000.html]]). I suspect the entities ordering in model to be the problem (see [[||anchor="EOF fails to fetch or save entities when not correctly ordered in model"]] below). If it's still not the case, you can try to use the [[ERXSharedEOLoader>>http://wonder.cvs.sourceforge.net/wonder/Wonder/Common/Frameworks/ERExtensions/Sources/er/extensions/ERXSharedEOLoader.java?revision=1.9&view=markup]] class in [[Project Wonder>>http://wonder.sourceforge.net]]. | ||
86 | |||
87 | == EOF fails to fetch or save entities when not correctly ordered in model == | ||
88 | |||
89 | **Authors:** Francis Labrie | ||
90 | |||
91 | **Affected products:** //WebObjects// 5.2.x, 5.3.x | ||
92 | |||
93 | **Bug reference:** | ||
94 | |||
95 | === Problem: === | ||
96 | |||
97 | Sometimes when using inherritance with entities in a data model in a //WebObjects// application, fetching or saving data may simply fails with strange and unexpected exceptions. Typical exception is: | ||
98 | |||
99 | * {{code}} com.webobjects.eoaccess.EOGeneralAdaptorException: sqlStringForKeyValueQualifier: attempt to generate SQL for {{/code}}//<Qualifier Class>//{{code}} ({{/code}}//<Qualifier Expression>//{{code}}) failed because attribute identified by key 'NeededByEOF0' was not reachable from from entity {{/code}}//<Entity Name>// | ||
100 | |||
101 | {{code}} at com.webobjects.eoaccess.EODatabaseContext._exceptionWithDatabaseContextInformationAdded(EODatabaseContext.java:4685) {{/code}} | ||
102 | |||
103 | ... | ||
104 | |||
105 | * //etc.// | ||
106 | |||
107 | === Solution: === | ||
108 | |||
109 | Typically, this kind of error occurs when the parent entity is in an another model which was initialized after the current entity model one (see [[||anchor="EOF fails to initialize models when not specifically ordered"]] above) or when the parent entity is coming after the current entity in the alphabetically ordered list of entities of the current model. To illustrate the latter case: if your abstract parent entity name is "Flower" and you are fetching the concrete sub-entity "Anemone" while both entities are part of the same model, you can get this kind of exception on the first "Anemone" fetch. | ||
110 | |||
111 | To avoid this exception, simply edit the "index.eomodeld" file in a text editor and reorder the entities references in the array, putting parent entities above sub-entities. But you should then take care with the //EOModeler//: you'll have to reorder these entities references each time you modify and save the model. | ||
112 | |||
113 | == New sub-entity insertion fails because primary key is null == | ||
114 | |||
115 | **Authors:** initially reported by Chuck Hill | ||
116 | |||
117 | **Affected products:** //WebObjects// 5.2.x, 5.3.x | ||
118 | |||
119 | **Bug reference:** | ||
120 | |||
121 | === Problem: === | ||
122 | |||
123 | When a sub-entity have a parent entity with a relationship set to //propagate primary key//, any new sub-entity insertion when saving changes from an editing context will throw an integrity violation exception because the primary key column is set to {{code}}null{{/code}}. | ||
124 | |||
125 | === Solution: === | ||
126 | |||
127 | To avoid this bug, uncheck the //Propagate primary key// relationship property of the parent entity. Unfortunately, if the parent entity is not abstract, this solution will not be applicable: you'll probably have to modify the relationship modeling itself. | ||
128 | |||
129 | Category:WebObjects |