Guide to 4.2 Features

1. Java Version

Minimum required JDK version is 8 or newer. Cayenne 4.2 is fully tested with Java 8, 11 and 17.

2. New Features

2.1. Subqueries

Expressions are now support subqueries.

ColumnSelect<Long> subQuery = ObjectSelect
        .columnQuery(Artist.class, Artist.ARTIST_ID_PK_PROPERTY)
        .where(...);
List<Artist> artists = ObjectSelect.query(Artist.class)
        .where(Artist.ARTIST_ID_PK_PROPERTY.in(subQuery))
        .select(context);

2.2. New Property API

Property API are greatly revised. This API allows to use type aware expression factories aka Properties. These properties are normally generated as static constants in model classes, but they can also be created manually by PropertyFactory if needed. New API provides designated properties for different datatypes and relationships, including special variant that represents primary keys.

Usage example in ObjectSelect query:

Painting painting = //...
Artist artist = ObjectSelect.query(Artist.class)
        .where(Artist.PAINTING_ARRAY.contains(painting))
        .and(Artist.DATE_OF_BIRTH.year().gt(1950))
        .and(Artist.ARTIST_NAME.lower().like("pablo%"))
        .selectOne(context);

See JavaDoc for details.

2.3. New types support

Cayenne 4.2 brings support for the Json and Geo types that are common now in RDBMS, see this demo for the usage example. Additionally, Cayenne now supports java.time.Duration and java.time.Period out of the box.

3. Deprecations and API incompatibilities

For the full list of deprecations refer to UPGRADE.txt. Here’s the most important changes.

3.1. SelectQuery

SelectQuery is deprecated in favour of ObjectSelect. It’s still fully functional and could be used, but it will be removed in a future.

3.2. Obsolete modules

There are several modules that are deprecated in Cayenne 4.2 and will be removed in a later version:

  • Cayenne ROP

  • Cayenne Web

  • Event bridges: XMPP, JMS and JGroups

These modules could be still safely used in 4.2.

3.3. ObjectId

ObjectId can’t be instantiated directly, ObjectId.of(..) factory methods should be used. E.g. ObjectId.of("Artist", 1) instead of new ObjectId("Artist", 1).