Hi, Cayenne is now getting nearer to "we may actually try this" status here, mostly because Hibernate keeps making things complicated. Which means I'm going to ask some rather specific and convoluted questions; please feel free to answer just some of them.
1) Does anybody have concrete advice about using Cayenne without Modeler? Background: I see Modeler is one of the major sources of "huh?" moments on the list. It's an additional layer of abstraction between what Cayenne does and what the developer sees, meaning it can introduce problems (and occasionally does); I'd want to get my feet wet with Cayenne without that complication. I also see it's the one part that you actually can avoid using - the XML can be edited by hand. Now the potential problems I see with hand-editing the XML: 1a) Is there a DTD? Without a DTD, hand editing becomes too cumbersome and error-prone. 1b) Does Cayenne offer a way to check consistency between XML and a database? (I wouldn't object to using Modeler for that limited purpose. That might even be a good way to getting used to Modeler's view of the data model. I guess the answer is "yes", the modeler docs talk about "Validation of created mappings", but it would be nice to confirm I'm not misunderstanding something here.) 1c) If there's a way to check consistency, are inconsistencies reported in a way that a Cayenne newbie would understand? Such error messages can be difficult to generate, they'd need to detail both the involved RDBMS concepts (tables, fields, lengths, precisions, FKs etc.) and the involved Cayenne concepts (class definitions, associations). And since an error means these are out of sync, the error message would need to be as precise as possible about the nature of the inconsistency, which is no mean feat. 2) How would one assign a "field type" with a field in a Cayenne Pojo? With "field type", I mean things like 123456789012345678901234567890123456789012345678901234567890123456789012 - Associating textual representation with field contents, such as -- shorthands in the database table, Java enums internally, longer texts on display -- or maybe shorthands in the database table, Java Strings internally, longer texts on display - What Swing controls to use for displaying this data ("Renderer" in Swing terminology) - What Swing controls to use for editing this data ("Editor" in Swing terminology) - Validation info: valid ranges; probably a Java interface with implementations that may or may not use RDBMS length/precision info - Possibly association with more than one field (date/time in two fields but merged into one Java property) (or still two Java properties, but validation etc. spans all of them) I see various possible approaches: 2a) The traditional Cayenne approach. Make the entity class a superclass, the business class a subclass. Entity class properties would have private members and protected getters/setters, the business class would then use a FieldType object to delegate public getters/setters to the protected getters/setters. (FieldType objects would be static and accept entity objects as parameters, so memory bloat isn't an issue. I'm using a similar construction in my current Hibernate infrastructure.) I'm a bit worried about the amount of boilerplate needed in the business class. In particular for the trivial cases where the DB field is simply handed through to the business logic (e.g. address fields where the end user should be able to put in pretty anything they choose as long as it fits the database field). 2b) Use delegation instead of subclassing. The issues are essentially the same, except the getters/setters of the entity class wouldn't have to be package-private or public instead of protected. Are there other issues that I should be aware of? 2c) Since I'm not too dependent on Modeler, I might merge entity and business class. I'm not sure that such a merge has any advantages; does anybody have seen this tried? Stories of failure and success equally interesting here. I have to admit I don't expect success, merging abstractions usually doesn't work well in the long term; losing the option to use Modeler's code generation later when we're more confident in it is a strong point agains that route, too. Still, I'd like to know how much water this assessment holds. 2d) Anything I haven't thought of. Different ways to use Java reflection, a Modeler option I'm not aware of that does all these things out of the box, whatever. 3) How do I do cascading? I have seen some mention of this in the docs but haven't found a comprehensive description. 3a) Less is more. Abstract is better than concrete. Hibernate shows how not do do this: theres roughly half a dozen cascale options for each association, each labelled with the name of one database-level operation, but little or no documentation on what high-level operation invokes which database-level cascade. How's this done in Cayenne? 3b) Is there a way to do a cascading "check for inconsistencies between entity objects in the persistence context and database rows"? One approach to that might be a full reload of all objects and reporting back if there are inconsistent updates. Another might be some forced update on the dependent object, so only the master objects "above" a changed object need to be checked, then updated. The background is that we want to allow the occasional inconsistency introduced via manual updates, but not via the application. We do have consistency conditions that aren't easily enforced using database constraints or update triggers (besides, an update trigger would require a reload from the application, so now I have to do the are-we-still-in-sync check anyway). 4) Can I do mixed scalar/object queries? I need to retrieve a list of entities, plus some statistical data. In SQL terms, this might look like SELECT orders.*, SUM(detail.itemprice * detail.quantity), COUNT(detail.id) GROUP BY <all fields of table "orders" here> Yes, I want to keep the detail counting, multiplying and sorting on the database server, to keep network traffic down. I'd also want to get all fields of the "orders" table in an Orders Pojo. The result of the query would either be an Object[], or a Javabean with fields for the Orders object, a BigDecimal for the total price and a BigInteger for the detail count. (I haven't found a way to do this efficiently in Hibernate. I have spent more than a week on this and am approaching the point where switching to Cayenne would have been less work. Presumably ;-/ ) http://cayenne.apache.org/doc30/sqltemplate-result-mapping.html indicates that this is indeed possible - is that correct? Did somebody use it in anger already? Any feedback welcome :-) Regards, Jo