Last modified by John Huss on 2012/12/08 17:26

Hide last authors
madc0w 3.1 1 == **Comparison of EOF to Cayenne** ==
2
3 **Introduction**
4
John Huss 18.1 5 EOF is the data access portion of WebObjects that provides Object-Relational Mapping (ORM). Apache Cayenne is an alternative ORM that can be used within a WebObjects app as a replacement for EOF or in any sort of Java app, like a Servlet application.
madc0w 3.1 6
7 Below is a description of the differences between EOF and Cayenne with the goal of providing information to a WebObjects/EOF developer who is curious about switching to Cayenne.
8
9 **Key Value Coding**
10
John Huss 18.1 11 Cayenne doesn't really have a KVC mechanism like EOF does. Properties of entity objects can be accessed by name by using the readProperty and writeProperty methods of CayenneDataObject, but these methods do not invoke custom getters and setters like EOF does, they simple return the value. So they are analogous to storedValueForKey and takeStoredValueForKey (however, readProperty also supports a key path, not just a simple key).
madc0w 3.1 12
John Huss 18.1 13 The closest match to KVC is found in a utility class: PropertyUtils.getProperty and PropertyUtils.setProperty. These can be leveraged to provide access to property values that go through custom getters and setters. BUT the getter methods must be prefixed with "get", following the java-beans convention.
madc0w 3.1 14
John Huss 18.1 15 It should be noted however, that complete KVC can be added on top of Cayenne by using the JavaFoundation framework in WO, or by using the custom implementation found in the NSFoundation project that is in Project Wonder. This approach would provide a completely compatible KVC implementation on top of Cayenne. An example of this is available in the ERCayenne framework in Project Wonder.
madc0w 3.1 16
17 **Concurrency**
18
John Huss 18.1 19 Cayenne has much better concurrency support that EOF. Locking the framework stack is not required as it is in EOF. Cayenne also supports jdbc connection pooling out of the box. I'm not aware of any benchmarks comparing performance, but Cayenne should be much faster at handling concurrent operations.
madc0w 3.1 20
21 **Raw Rows**
22
John Huss 18.1 23 In Cayenne raw row fetches are limited to returning columns from a single table. This differs from EOF which allows for any related key path to be fetched. In Cayenne the qualifier may still reference key paths, they just cannot be returned in the select. You could consider rewriting complex EOF Raw Row fetches with SQLTemplate in Cayenne.
madc0w 3.1 24
25 **Inheritance**
26
John Huss 16.1 27 Cayenne currently supports only single table inheritance (completely) and vertical inheritance (partially). However, horizontal inheritance is slated for implementation in the next release of Cayenne (3.2?).
madc0w 3.1 28
29 **Tooling**
30
John Huss 18.1 31 CayenneModeler is a standalone application that can be used on any platform. There is also an Eclipse plugin under development that should be viable soon. The Eclipse plugin will allow for automatically regenerating entity classes when the model is modified, but the standalone app doesn't this (not directly anyway).
madc0w 3.1 32
33 **Entity Templates**
34
35 The default entity templates in Cayenne are pretty sparse, without a lot of convenience methods like the WonderEntity template has for EOF. But this is easily remedied, and the ERCayenneExample in Wonder has and EOF-like template you can use.
36
37 **Modeler / Model API**
38
John Huss 18.1 39 In Cayenne each Entity has two parts: 1) an Object mapping and a DB mapping, referred to as ObjEntity and DbEntity. These appear separately in Modeler and are linked together within Modeler. ObjEntity contains the attribute name and java class type; DbEntity contains the column name and database type. This differs from EOF where these two concepts are combined into a single editor in the Modeler and into a single EOEntity class at runtime. Whilst I find the separation in Cayenne to be a bit cumbersome, it allows for for possibility for operations to be performed at a lower level using just the database information and bypassing the object layer. This may be useful in a small number of specific situations.
madc0w 3.1 40
41 **Deployment**
42
43 Cayenne is agnostic to the specific deployment environment, however it is almost always deployed to a standard Java Application Server (Servlet container) like JBoss or Glassfish, etc. This is an industry standard approach, which has some advantages. Personally, I quite like that the app is entirely contained in a single .war file.
44
John Huss 16.1 45 However, Cayenne can **easily be used in a WO application** as it is just another jar and doesn't have any special deployment requirements.
madc0w 3.1 46
47 **Feature Matrix**
48
John Huss 18.1 49 |=(((
50 Feature
51 )))|=(((
52 EOF
53 )))|=(((
54 Cayenne
55 )))|=(((
56 Notes
57 )))
58 |(((
59 Open Source
60 )))|(((
madc0w 3.1 61
John Huss 18.1 62 )))|(((
63 X
64 )))
65 |(((
66 Still Developed / Maintained
67 )))|(((
madc0w 3.1 68
John Huss 18.1 69 )))|(((
70 X
71 )))|(((
72 WebObjects/EOF has been given legacy status by Apple.
73 )))
74 |(((
75 Development on any Platform
76 )))|(((
madc0w 3.1 77
John Huss 18.1 78 )))|(((
79 X
80 )))|(((
81 WebObjects/EOF may only be developed on Apple hardware.
82 )))
83 |(((
84 Eclipse Integration
85 )))|(((
86 X
87 )))|(((
88 *
89 )))|(((
90 Cayenne Eclipse integration is being developed and an alpha version is available.
91 )))
92 |(((
93 Good Concurrency Support
94 )))|(((
madc0w 3.1 95
John Huss 18.1 96 )))|(((
97 X
98 )))|(((
99 EOF is single threaded and requires explicit locking, preventing concurrent operations.
100 )))
101 |(((
102 Support for all common DBs
103 )))|(((
104 X
105 )))|(((
106 X
107 )))|(((
madc0w 3.1 108
John Huss 18.1 109 )))
110 |(((
111 Primitive Attributes
112 (int, double, long, etc)
113 )))|(((
madc0w 3.1 114
John Huss 18.1 115 )))|(((
116 X
117 )))|(((
madc0w 3.1 118
John Huss 18.1 119 )))
120 |(((
121 Enum Attributes
122 )))|(((
123 X*
124 )))|(((
125 X
126 )))|(((
127 Enum attributes are supported in EOF via the javaEnum prototype in Wonder.
128 )))
129 |(((
130 Relationships with Map or Set collection types
131 )))|(((
madc0w 3.1 132
John Huss 18.1 133 )))|(((
134 X
135 )))|(((
madc0w 3.1 136
John Huss 18.1 137 )))
138 |(((
139 Custom Attribute Types
140 )))|(((
141 *
142 )))|(((
143 X
144 )))|(((
145 The ERAttributeExtension framework in Wonder can provide this support for EOF.
146 )))
147 |(((
148 Embeddable relationships
149 (related objects stored in same table as the source)
150 )))|(((
151 *
152 )))|(((
153 X
154 )))|(((
155 EOF allows mapping relationships to the same table as the parent and using the same entity class. Cayenne allows embedding objects of a different class as de-normalized relationships in a single column.
156 )))
157 |(((
158 Single Table Inheritance
159 )))|(((
160 X
161 )))|(((
162 X
163 )))|(((
madc0w 3.1 164
John Huss 18.1 165 )))
166 |(((
167 Horizontal Inheritance
168 )))|(((
169 X
170 )))|(((
171 *
172 )))|(((
173 Horizontal inheritance is being developed and targeted for the next release of Cayenne (3.1)
174 )))
175 |(((
176 Vertical Inheritance
177 )))|(((
178 X
179 )))|(((
180 *
181 )))|(((
182 Cayenne's vertical inheritance support is not yet complete
183 )))
184 |(((
185 Flattened attributes/relationships
186 )))|(((
187 X
188 )))|(((
189 X
190 )))|(((
madc0w 3.1 191
John Huss 18.1 192 )))
193 |(((
194 Automatic Bi-directional Relationship Management
195 )))|(((
196 X*
197 )))|(((
198 X
199 )))|(((
200 EOF support is optionally provided by Wonder.
201 )))
202 |(((
203 Generics support (Java 5)
204 )))|(((
madc0w 3.1 205
John Huss 18.1 206 )))|(((
madc0w 3.1 207
John Huss 18.1 208 )))|(((
209 Generics support is mostly artificial in both EOF and Cayenne (implemented by casting in entity template).
210 )))
211 |(((
212 Support Transient Objects
213 (objects not in editing context)
214 )))|(((
215 X
216 )))|(((
217 *
218 )))|(((
219 (% style="color: rgb(0,0,0);" %)Cayenne supports Transient object manipulation for attributes, but not relationships.
220 )))
221 |(((
222 Support for Generic Objects (no custom classes)
223 )))|(((
224 X
225 )))|(((
226 X
227 )))|(((
madc0w 3.1 228
John Huss 18.1 229 )))
230 |(((
231 Optimistic Locking
232 )))|(((
233 X
234 )))|(((
235 X
236 )))|(((
madc0w 3.1 237
John Huss 18.1 238 )))
239 |(((
240 Optional Editing Context Synchronization
241 )))|(((
madc0w 3.1 242
John Huss 18.1 243 )))|(((
244 X
245 )))|(((
246 EOF automatically synchronizes editing contexts which can hide Optimistic Locking problems.
247 )))
248 |(((
249 Key Value Coding
250 )))|(((
251 X
252 )))|(((
madc0w 3.1 253
John Huss 18.1 254 )))|(((
255 Cayenne has some utility methods to access bean properties, and support for raw data access like storedValueForKey provides for EOF, but no direct analog to KVC.
256 )))
257 |(((
258 Customizable entity templates
259 )))|(((
260 X
261 )))|(((
262 X
263 )))|(((
madc0w 3.1 264
John Huss 18.1 265 )))
266 |(((
267 Raw fetching (Raw Rows / Data Rows)
268 )))|(((
269 X
270 )))|(((
271 X*
272 )))|(((
273 Cayenne's raw fetching is limited to fetching attributes, not relationships (see [[here>>url:http://cayenne.apache.org/doc/data-rows.html||shape="rect"]]), but other lower level support is available without resorting to raw SQL.
274 )))
275 |(((
276 Direct SQL support
277 )))|(((
278 X
279 )))|(((
280 X
281 )))|(((
madc0w 3.1 282
John Huss 18.1 283 )))
284 |(((
285 Nested Editing Contexts
286 )))|(((
287 X
288 )))|(((
289 X
290 )))|(((
madc0w 3.1 291
John Huss 18.1 292 )))
293 |(((
294 Editing Context Undo
295 )))|(((
296 X
297 )))|(((
madc0w 3.1 298
John Huss 18.1 299 )))|(((
madc0w 3.1 300
John Huss 18.1 301 )))
302 |(((
303 Remote / Distributed Data Access (Client apps) using API directly
304 )))|(((
305 X
306 )))|(((
307 X
308 )))|(((
madc0w 3.1 309
John Huss 18.1 310 )))
311 |(((
312 Android Support
313 )))|(((
madc0w 3.1 314
John Huss 18.1 315 )))|(((
316 *
317 )))|(((
318 Android support is available with a [[patch>>url:https://issues.apache.org/jira/browse/CAY-1604||shape="rect"]] to Cayenne. EOF will run on Android, but the license does not allow it.
319 )))
320 |(((
321 Pluggable Cache Implementation
322 )))|(((
madc0w 3.1 323
John Huss 18.1 324 )))|(((
325 X
326 )))|(((
madc0w 3.1 327
John Huss 18.1 328 )))
329 |(((
330 Database Migrations
331 )))|(((
332 X
333 )))|(((
334 *
335 )))|(((
336 Migrations are available in Cayenne with a pending project in the [[sandbox>>url:http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-migrations/||shape="rect"]] and an open [[issue>>url:https://issues.apache.org/jira/browse/CAY-1633||shape="rect"]] (vote it up!). CayenneModeler has the ability to inspect schema and migrate it as an one-time Admin function; this could be extended to generate a migration upgrade classes in additional to the initial migration.
337 )))
338 |(((
339 [[EJBQL>>url:http://cayenne.apache.org/doc/ejbqlquery.html||shape="rect"]] Query support (defined by JPA spec)
340 )))|(((
madc0w 3.1 341
John Huss 18.1 342 )))|(((
343 X
344 )))|(((
madc0w 3.1 345
John Huss 18.1 346 )))
347 |(((
348 Raw SQL Templating
349 )))|(((
madc0w 3.1 350
John Huss 18.1 351 )))|(((
352 X
353 )))|(((
354 Cayenne allows SQL to be written using the velocity [[template>>url:http://cayenne.apache.org/doc/sqltemplate-query.html||shape="rect"]] language and stored in the model so it can support multiple database types.
355 )))
356 |(((
357 Batch Querying
358 )))|(((
madc0w 3.1 359
John Huss 18.1 360 )))|(((
361 X
362 )))|(((
363 Cayenne provides this using [[QueryChain>>url:http://cayenne.apache.org/doc/querychain.html||shape="rect"]]
364 )))
365 |(((
366 Documentation in the model (EO model doc)
367 )))|(((
368 X
369 )))|(((
madc0w 3.1 370
John Huss 18.1 371 )))|(((
madc0w 3.1 372
John Huss 18.1 373 )))
374 |(((
375 Default values defined in the model (for migrations and in entity objects)
376 )))|(((
377 X
378 )))|(((
madc0w 3.1 379
John Huss 18.1 380 )))|(((
381
382 )))
383 |(((
384 Servlet Deployment
385 )))|(((
386 X
387 )))|(((
388 X
389 )))|(((
390
391 )))
392 |(((
393 JavaMonitor / wotaskd Deployment
394 )))|(((
395 X
396 )))|(((
397 X
398 )))|(((
399
400 )))
401 |(((
402 Incredible Community and Conferences
403 )))|(((
404 X
405 )))|(((
406
407 )))|(((
408
409 )))
410
411 **API Comparison**
412
413 For EOF users wanting to use Cayenne there is very little to learn to get started. The frameworks are conceptually very similar at the user level, so you just have to translate your EOF knowledge to some new method and class names.
414
415 |=(((
416 EOF
417 )))|=(((
418 Cayenne
419 )))
420 |(((
421 **EOEditingContext**\\
422 )))|(((
423 **DataContext**\\
424 )))
425 |(((
426 .objectWithFetchSpecification\\
427 )))|(((
428 .performQuery\\
429 )))
430 |(((
431 .saveChanges\\
432 )))|(((
433 .commitChanges\\
434 )))
435 |(((
436 .revert\\
437 )))|(((
438 .rollbackChanges\\
439 )))
440 |(((
441 .lock\\
442 )))|(((
443 Locking is not necessary in Cayenne!\\
444 )))
445 |(((
446 .unlock\\
447 )))|(((
448 Locking is not necessary in Cayenne!\\
449 )))
450 |(((
451 .insertObject\\
452 )))|(((
453 .registerNewObject\\
454 )))
455 |(((
456 .deleteObject\\
457 )))|(((
458 .deleteObject\\
459 )))
460 |(((
461 .undo\\
462 )))|(((
463 No analog in Cayenne\\
464 )))
465 |(((
466
467 )))|(((
468
469 )))
470 |(((
471 **EOGenericRecord**\\
472 )))|(((
473 **CayenneDataObject**\\
474 )))
475 |(((
476 .storedValueForKey\\
477 )))|(((
478 .readProperty\\
479 )))
480 |(((
481 .takeStoredValueForKey\\
482 )))|(((
483 .writeProperty\\
484 )))
485 |(((
486 .valueForKey\\
487 )))|(((
488 PropertyUtils.getProperty (sort of, see KVC section above)\\
489 )))
490 |(((
491 .takeValueForKey\\
492 )))|(((
493 PropertyUtils.setProperty (sort of, see KVC section above)\\
494 )))
495 |(((
496 .~_~_globalID\\
497 )))|(((
498 .getObjectId\\
499 )))
500 |(((
501 .entity()\\
502 )))|(((
503 Cayenne.getObjEntity(eo)\\
504 )))
505 |(((
506 .validateForSave\\
507 )))|(((
508 .validateForSave\\
509 )))
510 |(((
511 .validateForInsert\\
512 )))|(((
513 .validateForInsert\\
514 )))
515 |(((
516 .validateForUpdate\\
517 )))|(((
518 .validateForUpdate\\
519 )))
520 |(((
521 .validateForDelete\\
522 )))|(((
523 .validateForDelete\\
524 )))
525 |(((
526 .validateValueForKey\\
527 )))|(((
528 No analog in Cayenne\\
529 )))
530 |(((
531 .<validateSpecificAttributeViaReflection>\\
532 )))|(((
533 No analog in Cayenne\\
534 )))
535 |(((
536 .willUpdate, willInsert, etc\\
537 )))|(((
538 provided by Cayenne lifecycle callbacks\\
539 )))
540 |(((
541
542 )))|(((
543
544 )))
545 |(((
546 **EOQualifier**\\
547 )))|(((
548 **Expression**\\
549 )))
550 |(((
551 EOQualifier.qualifierWithQualifierFormat\\
552 )))|(((
553 Expression.fromString\\
554 )))
555 |(((
556
557 )))|(((
558
559 )))
560 |(((
561 **ERXKey**\\
562 )))|(((
563 **Property**
564 )))
565 |(((
566 ERXKey.eq\\
567 )))|(((
568 Property.eq
569 )))
570 |(((
571 ERXKey.ne\\
572 )))|(((
573 Property.ne\\
574 )))
575 |(((
576
577 )))|(((
578
579 )))
580 |(((
581 **EOFetchSpecification**\\
582 )))|(((
583 **SelectQuery**\\
584 )))
585 |(((
586 .qualifier\\
587 )))|(((
588 .getQualifier\\
589 )))
590 |(((
591 .setSortOrderings\\
592 )))|(((
593 .addOrderings\\
594 )))
595 |(((
596 .setPrefetchingRelationshipKeyPaths\\
597 )))|(((
598 .addPrefetch\\
599 )))
600 |(((
601
602 )))|(((
603
604 )))
605 |(((
606 **EOEntity**\\
607 )))|(((
608 **ObjEntity + DbEntity**\\
609 )))
610 |(((
611 **EOModel**\\
612 )))|(((
613 **DataMap (entities) + DataNode (connection dictionary)**\\
614 )))
615 |(((
616 **EOAttribute**\\
617 )))|(((
618 **ObjAttribute + DbAttribute**\\
619 )))
620 |(((
621 **EOClassDescription**\\
622 )))|(((
623 **DataObjectDescriptor**
624 )))