blob: f6931d43ab22822b56520ab7e6e2705db1ad34d2 [file] [view]
# Apache Cayenne Upgrade Guide
> For upgrade notes for Cayenne 4.2 and older, see [UPGRADE-4.2-and-older.md](UPGRADE-4.2-and-older.md).
## What's New in 5.0
This is a high-level overview of 5.0 changes. Check the next section for milestone-by-milestone upgrade instructions.
### New Dev Versioning Scheme
Snapshot versions are now a constant value — the dev version of 5.0 will always be `5.0-SNAPSHOT`,
so you can stay at the bleeding edge of development if needed:
```xml
<dependency>
<groupId>org.apache.cayenne</groupId>
<artifactId>cayenne</artifactId>
<version>5.0-SNAPSHOT</version>
</dependency>
```
### New Class Generation UI
The new Class Generation UI in CayenneModeler simplifies configuration, allows multiple `cgen` setups
per project, and includes a template editor. Custom templates are now part of the project XML
configuration and don't require separate setup in either Modeler or Maven/Gradle plugins.
### Improved `(not)exists` Queries
`(not)exists` is now directly supported by the Expression API (including `Expression`, the expression
parser, and the Property API) — no need to construct a subquery manually. The feature can handle any
expression and spawn several sub-queries per expression if needed:
```java
long count = ObjectSelect.query(Artist.class)
.where(Artist.PAINTING_ARRAY.dot(Painting.PAINTING_TITLE).like("painting%").exists())
.selectCount(context);
```
### Improved SQL Support
`ANY` and `ALL` subqueries are now supported, as well as `case-when` expressions:
```java
import static org.apache.cayenne.exp.ExpressionFactory.*;
// ...
Expression caseWhenExp = caseWhen(
List.of(betweenExp("estimatedPrice", 0, 9),
betweenExp("estimatedPrice", 10, 20)),
List.of(wrapScalarValue("low"),
wrapScalarValue("high")),
wrapScalarValue("error"));
```
## Upgrading to 5.0-M3
* Per [CAY-2912](https://issues.apache.org/jira/browse/CAY-2912) SQL logging was redesigned to be compact and
single-line. The `JdbcEventLogger` interface and its `Slf4jJdbcEventLogger` / `FormattedSlf4jJdbcEventLogger`
implementations were removed and replaced by `org.apache.cayenne.log.SqlLogger` (default implementation
`Slf4jSqlLogger`). Log output now goes to a logger named `cayenne-sql` (previously `org.apache.cayenne.log.JdbcEventLogger`) —
update your logging configuration accordingly. Each statement is logged as one line combining the SQL, its bindings
and the result count (e.g. `... bind:[user_id:15] selected:1`); transaction boundaries moved to `DEBUG`. If you bound
a custom `JdbcEventLogger` in a DI module, rebind `SqlLogger` instead.
As part of this change the `cayenne.query_execution_time_logging_threshold` property no longer has any effect — the
slow-query threshold warning it controlled has been removed. The `Constants.QUERY_EXECUTION_TIME_LOGGING_THRESHOLD_PROPERTY`
constant is retained (deprecated) but ignored. A new `cayenne.jdbc.log.batch.threshold` property (default 3) controls how
many batch rows are logged in full before the bindings are truncated to `[first]..N..[last]`.
* Per [CAY-2954](https://issues.apache.org/jira/browse/CAY-2954) selecting queries are no longer wrapped in
transactions internally by Cayenne. Using connections in "auto-commit" mode instead has a significant positive impact
on DB performance. This should not affect manually-managed transactions. But in theory, in some rare cases this may
still change consistency behavior of disjoint prefetches (as multiple related selects will no longer be wrapped in a
single transaction). We'd like to look at the actual cases to propose a mitigation approach, but one possible
solution may be changing to "joint" prefetches.
* Per [CAY-2956](https://issues.apache.org/jira/browse/CAY-2956) the dedicated Oracle 8 adapter has been removed.
`org.apache.cayenne.dba.oracle.Oracle8Adapter` and its supporting classes no longer exist, and the
`OracleSniffer` now maps all Oracle versions to `OracleAdapter` regardless of the JDBC driver version.
If you referenced `Oracle8Adapter` explicitly (e.g. in a DataNode adapter configuration or custom DI
bindings), switch to `org.apache.cayenne.dba.oracle.OracleAdapter`.
* Per [CAY-2957](https://issues.apache.org/jira/browse/CAY-2957) the legacy HSQLDB adapter (HSQL <= 1.8) has been removed.
`org.apache.cayenne.dba.hsqldb.HSQLDBNoSchemaAdapter` no longer exists, and the `HSQLDBSniffer` now maps all. If you
happen to be on those older HSQL versions, update to the latest one.
* Per [CAY-2970](https://issues.apache.org/jira/browse/CAY-2970) deferred batch parameter values (e.g. a generated PK
propagated to a dependent PK or FK within the same transaction) are now represented by the dedicated
`org.apache.cayenne.access.DeferredValue` type instead of a bare `java.util.function.Supplier`. Cayenne now resolves
only its own `DeferredValue` instances, leaving user-supplied `Supplier` attribute values untouched. If you have
custom code that fed deferred values into batch bindings or `ObjectId` snapshots via `Supplier`, implement
`DeferredValue` instead — it is a `@FunctionalInterface`, so an existing lambda or `Supplier` implementation can
usually be adapted with a minimal change.
* Per [CAY-2985](https://issues.apache.org/jira/browse/CAY-2985) `DataDomain` became mostly immutable. The `DataDomain(String)` constructor and all the setters
below were removed in favor of a single full constructor that takes every collaborator and setting. Only DataNodes,
DataMaps, filters and listeners can still be added (and removed) after creation. Replacements for the removed setters:
- `setName(String)` — the name comes from the project XML, and can be overridden with the
`cayenne.domain.name` property (`Constants.DOMAIN_NAME_PROPERTY`).
- `setEntityResolver(EntityResolver)` — keep using `addDataMap(..)` / `removeDataMap(..)` to change resolver contents.
- `setEntitySorter(EntitySorter)` — the sorter is produced by the new `EntitySorterFactory` DI service. Bind your
own `EntitySorterFactory` to replace it.
- `setEventManager(EventManager)` — bind `EventManager` in a DI module instead.
- `setQueryCache(QueryCache)` — bind `QueryCache` in a DI module instead.
- `setSharedSnapshotCache(DataRowStore)`, `setDataRowStoreFactory(DataRowStoreFactory)` and
`getDataRowStoreFactory()` — bind `DataRowStoreFactory` in a DI module to customize the cache.
- `setSharedCacheEnabled(boolean)` — use the "Shared Cache" checkbox in the Modeler.
- `setValidatingObjectsOnCommit(boolean)` — use the "Object Validation" checkbox in the Modeler.
- `setMaxIdQualifierSize(int)` — use the `cayenne.max_id_qualifier_size` property
(`Constants.MAX_ID_QUALIFIER_SIZE_PROPERTY`).
## Upgrading to 5.0-M2
* Per [CAY-2947](https://issues.apache.org/jira/browse/CAY-2947) the `cayenne-commitlog` artifact has been removed. Commit log support is now part of the
core `cayenne` artifact — no extra dependency needed. Migrate as follows:
- Remove the `cayenne-commitlog` dependency from your build.
- Replace `CommitLogModule.extend(binder).addListener(l)` with:
```java
CoreModule.extend(binder).addCommitLogListener(l)
```
- `excludeFromTransaction()` is now `excludeCommitLogFromTransaction()` on `CoreModuleExtender`.
- Replace `@org.apache.cayenne.commitlog.CommitLog` on entity classes with
`@org.apache.cayenne.annotation.CommitLog`.
- The `CommitLogListener`, `ChangeMap`, `ObjectChange` and related model classes remain in the
`org.apache.cayenne.commitlog` package (now part of the core artifact).
* Per [CAY-2935](https://issues.apache.org/jira/browse/CAY-2935) Minimum required Java version for Apache Cayenne 5.0 is 21.
* Per [CAY-2937](https://issues.apache.org/jira/browse/CAY-2937) the visual graph feature (entity layout diagrams) has been removed from CayenneModeler.
Existing `.graph.xml` files will be automatically deleted and their references removed from
`cayenne-project.xml` when a project is opened in the Modeler and upgraded to the newest format.
* Per [CAY-2859](https://issues.apache.org/jira/browse/CAY-2859) `SelectById` query factory methods are redesigned with a bunch of old methods deprecated —
update your calls accordingly.
* Per [CAY-2917](https://issues.apache.org/jira/browse/CAY-2917) joins are generated in a different order in the Select SQL. This should not affect any
logic except if your code relies on the generated SQL in any way.
* Per [CAY-2924](https://issues.apache.org/jira/browse/CAY-2924) the `org.apache.cayenne.map.event` package (mapping events and listener interfaces) was
moved from the core to the CayenneModeler module — these events are not used at runtime. As part of this:
- `DbEntity`, `ObjEntity` and `DataMap` no longer implement the `*Listener` interfaces and no longer
expose the internal event-consumer methods (`dbEntityChanged`, `objEntityChanged`, `dbAttributeAdded`,
`handleAttributeUpdate`, etc.).
- New public rename APIs replace the previous "set name + fire change event" pattern:
`DataMap.renameDbEntity(DbEntity, String)`, `DataMap.renameObjEntity(ObjEntity, String)`,
`DbEntity.renameAttribute(DbAttribute, String)` and `DbEntity.renameRelationship(DbRelationship, String)`.
Prefer these over `setName(...)` for renames, as they re-key the parent maps and update dependent
references.
- `DbAttribute.setPrimaryKey(boolean)` and `DbAttribute.setGenerated(boolean)` no longer fire events;
they update their parent `DbEntity`'s cached collections via direct method calls, behavior-equivalent
to before. If your application code subscribed to these mapping events at runtime, migrate to direct
calls or to the Modeler.
* Per [CAY-2925](https://issues.apache.org/jira/browse/CAY-2925) the `cayenne-modeler-maven-plugin` was removed. Launch CayenneModeler from the downloaded
distribution instead. A CLI option also exists for all platform flavors:
```
java -jar CayenneModeler.jar path/to/cayenne-project.xml
```
or on macOS:
```
open CayenneModeler.app --args path/to/cayenne-project.xml
```
* Per [CAY-2955](https://issues.apache.org/jira/browse/CAY-2955) the obsolete `QueryEngine` abstraction (`org.apache.cayenne.access.QueryEngine`) has been removed.
`DataNode` is now used directly wherever `QueryEngine` was previously referenced. So you must subclass `DataNode`
and override `performQueries()` if you previously implemented a custom `QueryEngine`.
## Upgrading to 5.0-M1
* Per [CAY-2737](https://issues.apache.org/jira/browse/CAY-2737) All code deprecated in Cayenne 4.1 and 4.2 was deleted — please review your code before
upgrading. Most notable removals are `SelectQuery` and these Cayenne modules:
- `cayenne-dbcp2`
- `cayenne-joda`
- `cayenne-client`
- `cayenne-client-jetty`
- `cayenne-protostuff`
- `cayenne-rop-server`
- `cayenne-web`
- `cayenne-jgroups`
- `cayenne-jms`
- `cayenne-xmpp`
* Per [CAY-2742](https://issues.apache.org/jira/browse/CAY-2742) Minimum required Java version for Apache Cayenne is 11.
* Per [CAY-2747](https://issues.apache.org/jira/browse/CAY-2747) Cayenne XML schemas are updated — update your projects by opening them in the Modeler or
using the `cayenne-project-compatibility` module.
* Per [CAY-2751](https://issues.apache.org/jira/browse/CAY-2751) There is no more JNDI DataSource provided by Cayenne, nor password encoding capabilities.
If you need these, provide your own custom DataSource.
* Per [CAY-2752](https://issues.apache.org/jira/browse/CAY-2752) Code generation configuration has minor changes — review and update Maven, Gradle and Ant
configs accordingly.
* Per [CAY-2772](https://issues.apache.org/jira/browse/CAY-2772) Module extension is done differently. This may result in compile errors in some module
extensions. If you encounter those, change how you configure the modules, following this general pattern
(using `CacheInvalidationModule` as an example):
```java
CayenneRuntime.of(..)
.addModule(b -> CacheInvalidationModule.extend(b).addHandler(MyHandler.class))
.build();
```
Two things to note: (1) a module-specific extender is created using an `extend(Binder)` method of the
module, and (2) an extender does not produce a `Module` — instead it adds services directly to the
`Binder`. So it is usually invoked within a lambda that produces a `Module`, or within an app `Module`.
* Per [CAY-2822](https://issues.apache.org/jira/browse/CAY-2822) `cayenne-server` module is renamed to `cayenne` — update your build scripts accordingly:
```xml
<dependency>
<groupId>org.apache.cayenne</groupId>
<artifactId>cayenne</artifactId>
<version>{version}</version>
</dependency>
```
* Per [CAY-2823](https://issues.apache.org/jira/browse/CAY-2823) `ServerRuntime` is deprecated. Use `org.apache.cayenne.runtime.CayenneRuntime` instead.
* Per [CAY-2824](https://issues.apache.org/jira/browse/CAY-2824) `CayenneServerModuleProvider` was renamed to `CayenneRuntimeModuleProvider` and moved to
the `org.apache.cayenne.runtime` package. If you are using the auto-loading mechanism for your custom
modules, update your `META-INF/services` reference accordingly.
* Per [CAY-2825](https://issues.apache.org/jira/browse/CAY-2825) Package `org.apache.cayenne.configuration.server` was renamed to
`org.apache.cayenne.configuration.runtime` — fix your imports accordingly.
* Per [CAY-2826](https://issues.apache.org/jira/browse/CAY-2826) `ServerModule` renamed to `CoreModule`. The new builder pattern combining both changes:
```java
CayenneRuntime runtime = CayenneRuntime.of()
.addConfig("cayenne-project.xml")
.module(b -> CoreModule.extend(b).setProperty("some_property", "some_value"))
.build();
```
* Per [CAY-2828](https://issues.apache.org/jira/browse/CAY-2828) The `server` prefix was removed from the names of runtime properties and named collections
defined in `org.apache.cayenne.configuration.Constants`. Update references in code and in any scripts
that use them as system properties.
* Per [CAY-2845](https://issues.apache.org/jira/browse/CAY-2845) `DataObject` interface and `BaseDataObject` class were deprecated and all logic moved to
the `Persistent` interface and `PersistentObject` class. Regenerate model classes via the cgen tool in
CayenneModeler or Maven/Gradle plugins.