Jpa joins (#1085) * JPQLSelectVisitor: Implicit joins should be LEFT OUTER.
Implicit joins are those where the synthesized foreign key is selected from a table. At the JPA level this requires navigating the relationship to the related entity and getting its id. Existing behavior does an inner join which means any case where the relation is null would simply exclude that row from results. This is incorrect behavior. It should instead allow the null value to be returned. Hence left outer join.
Inner join behavior can be had by explicitly specifiying the join in the SQL.
The names customer/address were messing with my head when trying to reason about this code. My guess is the customer/address names leaked from the test case ddl.
* JPAMetadataProcessor: Removed addForeignKeys.
It's not clear to me what this is trying to accomplish. The *ToOne side of a relationship is handled by addSingularAttributes. The ManyToMany case would surely need a join table created, which this method does not do. The OneToMany which this method tries to do something with is unnecessary as far as I can reason, and it results in an explosion of row results because of joining the relationship in even the simplist of query (select * from entity).
* JPAMetadataProcessor: Avoid PK/FK name collisions.
Old behavior uses a relation's PK as the name of the FK column in the parent. If the entities happen to use the same name for their IDs you get a collision and only one column ends up exposed. I for one always name my entity ids 'id'.
This change instead names the FK column(s) $parentAttribute_$childIdProperty.
* JPAMetadataProcessor: Added RELATION_PROPERTY and RELATION_KEY properties.
These properties are added to FK columns so downstream processing knows the parent attribute and the child id property associated with the column. This is necessary for disambiguating joins.
* JPQLSelectVisitor: Disambiguate joins.
Old behavior matches up joins based table names or table metadata matching. This does not work when the same entity is joined multiple times. Eg, two properties have the same entity type or a parent->child relationship is joined.
Instead, the RELATION_* properties are used to match joins up by parent attribute names and child id.