I don't think we had a discussion. We can have it now.
Nice - the "that's by design" bit made me fear it's not negotiable anymore.
In this particular case my thinking is that relationship
itself does not have any particular "join semantics"...
It is always a match between two keys. If you just need
to find objects related to a given object, using outer
join never makes sense.
Hmm... that's interesting.
I had thought that OF COURSE you need to specify optionality on relationships, but it seems to be far less a case than I thought.
Let's enumerate use cases where the optionality of a relationship's side might be relevant.
For automatic SELECTs by Cayenne, I see one use case: if the application holds a record that's a grandchild, and you access the grandparent, Cayenne could optimize the outer join between parent and grandparent table into an inner join if it knew that the to-1 relationship from parent to grandparent is mandatory. (Inner joins give the query planner of the database more options. More options means better plans, but maybe also more fruitless optimization planning, so it's a mixed blessing - also, grandchild-to-grandparent selects tend to not be bulk transfers, so this use case is a rather weak argument.)
What's the case for write access? I.e. INSERT/UPDATE/DELETE?
Here, optionality information is very relevant for determining action order: you delete the optional record before you delete the nonoptional one, and you create the nonoptional record before creating the optional one.
However, for a 1:N relationship, the N side is always optional, so there is a valid ordering available. Telling Cayenne that the 1 side is optional as well would give it more freedom to reorder writes, but it already has a valid order and doesn't need an additional one.
Then there's 1:1 relationships. If one side is optional, then it's just a case of 1:N with the additional constraint N<=1. If both sides are mandatory, we're in trouble - Cayenne does not know in which order to do the updates (and most databases will complain, since they do their consistency checks immediately instead of at end-of-transaction, so you can't INSERT into the left table because there is no record in the right table yet, and vice versa).
The other point for optionality information is that Cayenne could do consistency checks before writing to the database.
(I don't know whether Cayenne does.)
If Cayenne knows, it can avoid getting hit by SQLExceptions from constraint violations. This could help Cayenne if it does exception analysis, such as would be needed to activate the various workarounds needed as Oracle reports rollback segment problems.
On the con side, for the application, it doesn't matter much to the application whether it gets hit by an SQLException or a Cayenne-generated consistency exception.
Where it does make sense is in
qualifiers. But this makes it a property of a qualifier,
not the relationship.
It makes it a property of the qualifier, but per se, that does not preclude it as a property of the relationship.
In generally it is often hard to find such single place
for many ORM properties. There's always a concern that
anything beyond basic DB mapping is really a property of
the execution context (e.g. it is different per-application,
per-session, per-query, etc. - a good example is entity
callbacks/listeners adding behavior to the mapping). So
this often becomes a question of whether "one size fits all".
I fully agree with that point of view.