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

Reply via email to