Converting child expression to be used on parent entity
Ricardo Parada <[email protected]> Sun, 28 Sep 2025 13:52:37 -0400
| Newsgroups | gmane.comp.java.cayenne.user |
|---|---|
| Message-ID | <[email protected]> |
--Apple-Mail=_B4CC9112-4740-4A1A-9788-BAA1A4F6976A
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=utf-8
Hi all,
Another use case we have is as follows. We have an expression for the =
child entity. For example:
Expression paintingExpression =3D exp("name like 'G%' or name like =
'A%'");
Now, I want to use that to fetch the artists that have paintings that =
match that expression. I have to prefix each key with =E2=80=9Cpaitings."=
in order to use it to fetch those artists. The expression would then =
become =E2=80=9Cpaintings.name like 'G%' or paintings.name like =
'A%=E2=80=99=E2=80=9D.
Is there something in Cayenne already to convert an expression by =
prefixing every key path in the expression? =20
For example, not knowing much about Cayenne, I wrote the following =
utility method that seems to do the job:
public static <T> Expression prefix(BaseProperty<T> rel, Expression =
subExpression) {
return
subExpression.transform(o -> {
if (o instanceof CayennePath path) {
// e.g. Turn name path into paintings.name
return rel.getPath().dot(path);
}
return o;
});
}
Then I use it as follows:
Expression paintingsExpr =3D exp("name like 'G%' or name like 'A%'=E2=80=9D=
);
// This returns expression for "paintings.name like 'G%' or =
paintings.name like 'A%'"
Expression expr =3D prefix(Artist.PAINTINGS, paintingsExpr);
// Artists with paintings starting with letter G or A
List<Artist> someArtists =3D ObjectSelect
.query(Artist.class)
.where(expr.exists())
.select(context);
Generates the following SQL (formatted by me for readability):
INFO: --- transaction started.
INFO: SELECT t0.DATE_OF_BIRTH, t0.NAME, t0.ID FROM ARTIST t0=20
WHERE EXISTS (
SELECT t1.ID FROM PAINTING t1=20
WHERE ( t1.NAME LIKE ? OR t1.NAME LIKE ? )=20
AND ( t1.ARTIST_ID =3D t0.ID )
)=20
[bind: 1->NAME:'G%', 2->NAME:'A%']
INFO: =3D=3D=3D returned 1 row. - took 1 ms.
INFO: +++ transaction committed.
Summary
Am I reinventing the wheel by writing this prefix() utility method? Does =
Cayenne have something like that already?
Thank you
--Apple-Mail=_B4CC9112-4740-4A1A-9788-BAA1A4F6976A--