Re: How to build Exists Expression with a sub expression on the child entity?

Andrus Adamchik <[email protected]> Mon, 29 Sep 2025 14:58:47 -0400
Newsgroups gmane.comp.java.cayenne.user
Message-ID <[email protected]>
--Apple-Mail=_A98BEAAA-8A13-4DAC-AFB5-E3A8CE0B97D3
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=utf-8

Yeah, since "exists" is a fairly new feature in Cayenne, there are some =
holes. In-memory evaluation in particular:

=
https://github.com/apache/cayenne/blob/master/cayenne/src/main/java/org/ap=
ache/cayenne/exp/parser/ASTExists.java#L45

I am a big +1 to implement it in 5.0. We'll discuss with Nikita.

Thanks,
Andrus


> On Sep 28, 2025, at 12:58=E2=80=AFPM, Ricardo Parada =
<[email protected]> wrote:
>=20
> Thank you Nikita, that helps me.=20
>=20
> In EOF we use them in memory as well as for fetching from the =
database.
>=20
> In Cayenne it seems that once I call exists() then the expression =
cannot be used for filtering in memory.
>=20
> For example:
>=20
> Expression expr =3D exp("paintings.name like 'S%'").exists();
> 	=09
> List<Artist> someArtists =3D ObjectSelect
> 		.query(Artist.class)
> 		.where(expr)
> 		.select(context);
>=20
> The above matches 1 artist, e.g. =E2=80=9CVincent Van Gogh=E2=80=9D =
who has a paintings starting with the letter S, e.g. Starry Night and =
Sunflowers. But when I use that same expression against a list of all =
the artists like this:
>=20
> List<Artist> someArtists2 =3D expr.filterObjects(allArtists);
>=20
> Then someArtists2 is empty.
>=20
> However, if I rewrite the code as follows:
>=20
> Expression expr =3D exp("paintings.name like 'S%'");
> 	=09
> List<Artist> someArtists =3D ObjectSelect
> 		.query(Artist.class)
> 		.where(expr.exists())
> 		.select(context);
>=20
> // This matches 1 artist
> List<Artist> someArtists2 =3D expr.filterObjects(allArtists);
>=20
>=20
>=20
> Regards,
> Ricardo Parada
>=20
>=20
>=20
>> On Sep 27, 2025, at 12:26=E2=80=AFPM, Nikita Timofeev =
<[email protected]> wrote:
>>=20
>> Hi Ricardo,
>>=20
>> Yeah, there's not much info on that since that's a new API. =
`exists()` is a
>> terminal operator that converts the whole expression to an EXISTS =
query.
>>=20
>> So it would be something like this in your
>> example: =
Artist.PAINTINGS.dot(Painting.NAME).like("painting%").exists()
>>=20
>>=20
>> On Fri, Sep 26, 2025 at 8:31=E2=80=AFPM Ricardo Parada =
<[email protected]>
>> wrote:
>>=20
>>> Hi all,
>>>=20
>>> Another question I have is regarding EXISTS expressions.  I=E2=80=99m =
not sure if
>>> I=E2=80=99m using the API correctly, but I was thinking it would be =
something like
>>> this.  Using the entities from the Tutorial, let=E2=80=99s say I =
want to fetch the
>>> Artist=E2=80=99s that have a painting starting with the letter =
=E2=80=98G=E2=80=99:
>>>=20
>>> Expression e =3D =
Artist.PAINTINGS.exists(Painting.NAME.like(=E2=80=9CG%=E2=80=9D));
>>>=20
>>> But I=E2=80=99m getting a syntax error.
>>=20
>>=20
>>=20
>> --=20
>> Best regards,
>> Nikita Timofeev
>=20


--Apple-Mail=_A98BEAAA-8A13-4DAC-AFB5-E3A8CE0B97D3--