> ## Documentation Index
> Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Migration notes

# Migrate to 6.2

This page describes the best strategy to upgrade to 6.2.
Read the [Release notes](whats_new) to get familiar with major changes for this release.
This guide refers to changes in migration order.
The [Release notes](whats_new) refers to the changes based on their importance or significance.

For this migration, an [automated OpenRewrite migration recipe](#automated-openrewrite-migration-recipe) is provided.
Run it at the specified step of the migration process.

## Packaging changes

All the artifacts are available on [JFrog Artifactory](https://activeviam.jfrog.io/artifactory).

There are two client-facing entrypoints:

* [https://activeviam.jfrog.io/artifactory/mvn/](https://activeviam.jfrog.io/artifactory/mvn/)
* [https://activeviam.jfrog.io/artifactory/mvn-prod/](https://activeviam.jfrog.io/artifactory/mvn-prod/)

Read the [download page](../start/download) to see how to configure those entry points.

The channel `mvn` includes `mvn-prod` and also includes pre-release (alpha, beta, milestone, release candidate) and continuous builds.
Visibility of Maven artifacts depends on the access rights of the account.
Some artifacts, such as continuous build, may not be accessible if the required permissions are not granted.

Atoti is not distributed on `artifacts.activeviam.com`.

## Preparatory work

* Upgrade to the latest 6.1
* Check for use of `avinternal`/`internal`/`private_` in imports and replace them. Do not hesitate to fill a support ticket to seek for an alternative
* Fix Spring deprecations, follow Spring guide
* Try building the project with JDK 25. Some dependencies may require an upgrade for the build to succeed — for example, Lombok must be upgraded to a JDK 25-compatible version (**1.18.40+**).
* Check for use of [removed features](whats_new.md#removed-features)

## Upgrade

* Run the [automated OpenRewrite migration recipe](#automated-openrewrite-migration-recipe)
* Update the poms to the new Java version, Spring Boot version and Atoti version
* Atoti Server 6.2 moves to **Spring Boot 4**, which brings **Jackson 3** (`com.fasterxml.jackson.*` → `tools.jackson.*`). Migrate your Jackson usage with OpenRewrite's [`UpgradeJackson_2_3`](https://docs.openrewrite.org/recipes/java/jackson/upgradejackson_2_3) recipe.
* If you overrode the `admin-ui.version` Maven property to pin the Atoti Admin UI version, this property is removed: all Atoti UI artifacts (`atoti-ui`, `atoti-ui-initial-content`, `atoti-admin-ui`) are now versioned by the single `atoti-ui.version` property
* Logging configuration
  * If JUL is used for logging, add a dependency to `org.slf4j:slf4j-jdk14`
  * If a different logging framework is used, remove the dependency to `org.slf4j:jul-to-slf4j`
* Compile and test

If the code does not compile automatically after these steps, please file a ticket with the code that failed to be migrated, as it should have been handled by the migration recipes.

## Post-upgrade

As part of the migration, the name of some loggers and JVM property may have changed.
Warnings will be logged at runtime when using the legacy names in order to allow to identify the ones to migrate.
Monitor the logs for these warnings.

## Manual changes

The following changes are not handled by the automated recipe and must be applied manually.

* `IActivePivotContentServiceConfig` is deprecated.
  If you implement this interface, the `@Bean` annotation is not inherited from the interface for `activePivotContentService()`.
  Add `@Bean` explicitly to your implementing method, or migrate to declaring `IActivePivotContentService` as a standalone `@Bean`.

* Several methods of the Datastore transaction API (package `com.activeviam.database.datastore.api.transaction`) no longer declare `throws DatastoreTransactionException`, because they could never actually throw it.
  The affected methods are:

  * `ITransactionalWriter#remove(String, Object...)`
  * `ITransactionalWriter#removeAll(String, Collection)`
  * `IOpenedTransaction#updateWhere(ISelection, ICondition, IUpdateWhereProcedure)`
  * `IOpenedTransaction#rollback()`
  * `ITransactionManager#rollbackTransaction()`
  * `ITransactionManager#stop()`

  Since `DatastoreTransactionException` is a checked exception, a `try` block wrapping only calls to these methods with a `catch (DatastoreTransactionException e)` clause will no longer compile.
  Remove the now-dead `catch` clause, or the entire `try` if it was the only catch. In a multi-catch such as `catch (DatastoreTransactionException | SomeOtherException e)`, remove only the `DatastoreTransactionException` alternative.
  Methods that still throw it, such as `commitTransaction()`, `startTransaction(...)` and `removeWhere(...)`, are unaffected, so a `catch` that also wraps one of those stays as-is.

* The `String`-based distributing level APIs have been removed. Replace usages as follows, converting each former `String` level name to a `LevelIdentifier` (constructed with dimension name, hierarchy name, and level name):
  * `IApplicationDescriptionBuilderWithId#withDistributingFields(String...)` → `withDistributingLevels(LevelIdentifier...)`
  * `QueryClusterDefinition.DistributedApplicationDefinition(String, List<String>)` → `QueryClusterDefinition.DistributedApplicationDefinition(String, List<LevelIdentifier>)`

* `IDistributedApplicationDefinition#getDistributingFields()` has been removed. Use `getDistributingLevels()` instead, which returns a `List<LevelIdentifier>`.

- `com.activeviam.database.api.schema.DataTable` has been removed.
  This change is not handled by the automated migration recipe — replace constructor calls manually with the description API matching your stack:
  * **Datastore tables**: `new DataTable(name, keyFieldNames, fields)` becomes `StoreDescription.simpleBuilder().name(name).keyFieldNames(keyFieldNames).fields(fields).build()`.
    The `fields` list should now contain `IFieldDescription` instances (from `com.activeviam.database.datastore.api.description`) instead of `IDataTableField`.
    Replace `new DataTableField(...)` with `FieldDescription.builder()…build()` from the same package.
  * **DirectQuery tables**: `new DataTable(name, keyFieldNames, fields)` becomes `TableDescription.builder().externalTable(...).withSameLocalName().fields(fields).keyFieldNames(keyFieldNames).build()`,
    supplying the appropriate `ExternalTable`. The `fields` list should now contain `AFieldDescription` instances (from `com.activeviam.directquery.api.schema`) instead of `IDataTableField`.
    Replace `new DataTableField(...)` with `FieldDescription.builder()…build()` from the same package.

* `IActivePivotBranchPermissionsManagerConfig` has been deprecated and no longer carries `@Configuration` or `@Bean`. Implementing it no longer exposes a branch permissions manager bean. Stop implementing this interface and expose `IBranchPermissionsManager` as a `@Bean` from a `@Configuration` class directly.
* `IActivePivotConfig` has been deprecated and no longer carries `@Configuration` or `@Bean`. Implementing it no longer exposes a branch permissions manager bean. Stop implementing this interface and expose `IActivePivotManager` as a `@Bean` from a `@Configuration` class directly.

## Automated OpenRewrite Migration Recipe

The automated OpenRewrite migration recipe handles the following API changes from 6.1.20 to 6.2.0.
Run it during the [Upgrade](#upgrade) step.

The recipe is published to JFrog as the artifact `com.activeviam.migration:6_1-to-6_2:<version>`.

### How to run

From your project root, preview the changes first:

```bash theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
mvn -U org.openrewrite.maven:rewrite-maven-plugin:5.45.0:dryRun \
  -Drewrite.recipeArtifactCoordinates=com.activeviam.migration:6_1-to-6_2:<version> \
  -Drewrite.activeRecipes=com.activeviam.migration.v6_1_to_6_2
```

Then apply them by replacing `dryRun` with `run`

```bash theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
mvn -U org.openrewrite.maven:rewrite-maven-plugin:5.45.0:run \
  -Drewrite.recipeArtifactCoordinates=com.activeviam.migration:6_1-to-6_2:<version> \
  -Drewrite.activeRecipes=com.activeviam.migration.v6_1_to_6_2
```

### Running a subset of the migration

The aggregator recipe `com.activeviam.migration.v6_1_to_6_2` runs everything. Each migration is split into three phases so you can adopt it gradually. Swap
`-Drewrite.activeRecipes=` for one of the phase recipes instead of the aggregator:

| Phase  | Recipe name                                   | When to run                                                                      |
| ------ | --------------------------------------------- | -------------------------------------------------------------------------------- |
| Before | `com.activeviam.migration.v6_1_to_6_2_before` | On the 6.1 code base, before upgrading. The old code still compiles.             |
| During | `com.activeviam.migration.v6_1_to_6_2_during` | Together with the upgrade to 6.2. The old code cannot accommodate these changes. |
| After  | `com.activeviam.migration.v6_1_to_6_2_after`  | Once the project runs on 6.2, to clean up deprecated API usages.                 |

### Change of behavior

* The query-service monitoring previously provided by the APM module is now built into Atoti Server: query counters are always recorded, and exceptions thrown during query processing are always logged. The single `name=QueriesService,type=Monitoring` MBean previously registered by the APM module is replaced by two MBeans: `name=QueriesServiceStatistics,type=Monitoring` (query counters) and `name=QueriesServiceLogging,type=Monitoring` (runtime logging toggles). The per-query report logs (query/result description, completion time, optional memory statistics) are now **disabled by default**. If you relied on the APM module to produce these logs, enable them with the `activeviam.queries.service.logging=true` application property (and optionally `activeviam.queries.service.detailed-logging` and `activeviam.queries.service.log-memory-stats`), or at runtime through the `QueriesServiceLogging` MBean. These logs are now emitted on the `atoti.server.query.service` logger.

### Removed features

#### No longer supported

* `SnowflakeDialectSettings#SnowflakeDialectSettingsBuilder#arrayAggWrapperFunctionName(String)` has been removed. The built-in SQL function from Snowflake is now faster.
* `DatabricksDialectSettings#DatabricksDialectSettingsBuilder#xxxNativeArrayUdafName(String)` have been removed. Databricks has deprecated the use of Spark UDAFs. Review your database schema to use [emulated vectors](../directquery/databases/databricks#vectors-support) (multi-row or multi-column) instead.
* The concealed measures feature has been removed from the distributed data cluster definition. The `withConcealedMeasures(...)` builder methods, `IDataClusterDefinition#getConcealedMeasures`/`setConcealedMeasures`, and the now-redundant `withAllMeasures()` builder step no longer exist. Remove any call to `withAllMeasures()` from data cluster definitions; the builder now goes straight from the hierarchy concealment step to branch concealment. Concealing hierarchies and branches remains available.

#### With alternatives

* `IApplicationDescriptionBuilderWithId#withoutDistributingFields()` has been renamed to `withoutDistributingLevels()`.
* `QueryClusterDefinition.DistributedApplicationDefinitionV2` has been renamed to `QueryClusterDefinition.DistributedApplicationDefinition`.
* `IJdbcSource` has been removed. Replace all usages with the concrete `JdbcSource` class.
* Deprecated method `IQueryExecution#shouldBypassNonJitProviders` has been removed. Use `IQueryExecution#skipNonJitProviders` instead.
* Deprecated method `IMultiVersionDistributedActivePivot#unloadMembersFromDataNode` has been removed, along with the `IMessengerDefinition#UNLOAD_MEMBERS_MESSAGE_TIMEOUT` property and the `distribution.unload_members_from_data_node.*` metrics. Use `IMultiVersionDataActivePivot#maskMembers` instead.
* `ClickhouseProperties` has been deprecated. Use `ClickhousePropertiesV2` instead, as the ClickHouse connector has been upgraded to use a new client.
* The Maven modules `com.activeviam.activepivot:activepivot-impl` and `com.activeviam.activepivot:activepivot-intf` have been merged into `com.activeviam.activepivot:core`, use it directly.
* The empty Maven module `com.activeviam.activepivot:activepivot-copper` has been removed. Import `com.activeviam.activepivot:core` and optionally `com.activeviam.activepivot:activepivot-dist-impl` instead.
* The empty Maven module `com.activeviam.activepivot:activepivot-ext` has been removed. Import `com.activeviam.activepivot:core` and optionally `com.activeviam.activepivot:activepivot-dist-impl` instead.
* The empty Maven module `com.activeviam.springboot:atoti-runtime-starter`, kept as an alias since it was renamed in 6.1, has been removed. Use `com.activeviam.springboot:atoti-server-application-starter` instead.
* Memory sampling (activated via the property "activeviam.mmap.tracking", and triggered via JMX operations) has been removed. You should now rely on a JFR instead of JMX operations, as those include dedicated JFR events for memory operations. The associated properties "activeviam.mmap.sampling.depth", "activeviam.mmap.sampling.start" and "activeviam.mmap.sampling.percent" have been removed.
* `MDXQuery` is now immutable and the constructors should be used.
* The `activeviam.jwt.*` application properties, deprecated since 6.1, have been removed. Use the `atoti.jwt.*` equivalents instead.

| Previous name                          | New name                          |
| -------------------------------------- | --------------------------------- |
| `activeviam.jwt.expiration`            | `atoti.jwt.expiration`            |
| `activeviam.jwt.key.private`           | `atoti.jwt.key.private`           |
| `activeviam.jwt.key.public`            | `atoti.jwt.key.public`            |
| `activeviam.jwt.claim_key.authorities` | `atoti.jwt.claim_key.authorities` |
| `activeviam.jwt.claim_key.principal`   | `atoti.jwt.claim_key.principal`   |
| `activeviam.jwt.enabled`               | `atoti.jwt.enabled`               |
| `activeviam.jwt.check_user_details`    | `atoti.jwt.check_user_details`    |

<Warning>
  The `expiration` property is now a Spring `Duration`. The available formats are described in [Spring's documentation](https://docs.spring.io/spring-boot/reference/features/external-config.html#features.external-config.typesafe-configuration-properties.conversion.durations).
  For this property, a unitless integer will represent Seconds.
  In 6.1, a unitless integer would represent:

  * milliseconds for `atoti.jwt.expiration`
  * seconds for `activeviam.jwt.expiration`

  If you're migrating to 6.2 and just changed from `activeviam.jwt.expiration: int` to `atoti.jwt.expiration: int`, you need to modify that value accordingly.
  Adding the unit suffix, such as `atoti.jwt.expiration: 12000s` is the safest way to configure this property.
</Warning>

* The deprecated ActiveViam Property `activeviam.contentService.nameGenerator.defaultSize` has been removed, use `activeviam.contentService.nameGenerator.size` instead. See the [Properties page](../properties/Properties.md) for its definition.

* Deprecated method `StartBuilding.Builder#withEpochManager(IEpochManager)` has been removed. Use `StartBuilding.Builder#withEpochPolicy(IEpochManagementPolicy)` instead, passing the epoch policy directly rather than wrapping it in an `EpochManager`.

* Deprecated method `PersistedBuilder#lockOptions(boolean)` has been removed. Use `PersistedBuilder#databaseLocks(LockOptions)` instead. `lockOptions(true)` becomes `databaseLocks(LockOptions.defaultOptions())` and `lockOptions(false)` needs no call.

* The deprecated duplicate types under `io.atoti.runtime.api.measures` and `io.atoti.server.common.api.plugins` have been removed. Use the identically named types under `com.activeviam.atoti.application.api.measures` and `com.activeviam.atoti.server.common.api.plugins`. The automated recipe rewrites these package references.

* The deprecated 4-argument constructor of `ActivePivotTransactionCommittedEvent` has been removed. Use the 6-argument constructor, passing `-1, -1` for the start and commit timings when they are unknown.

* The deprecated `IGenericAggregationFunction.SUM_PRODUCT_FUNCTION_PLUGIN_KEY` constant has been removed. Use `IMultiSourceAggregationFunction.SUM_PRODUCT_FUNCTION_PLUGIN_KEY` instead, which is the canonical home for the multi-source sum-product key. The automated recipe rewrites these references.

* The deprecated `integer` and `integer[]` parser type keys (including sized and delimited variants such as `integer[10]` and `integer[][:]`) are no longer recognized. Replace them with the canonical `int` and `int[]` (and their sized and delimited variants).

### API syntax changes

* `CsvParserConfiguration` constructors are replaced by a new builder:
  * `new CsvParserConfiguration()` → `CsvParserConfiguration.builder().withColumnCount(0).build()`
  * `new CsvParserConfiguration(int)` → `CsvParserConfiguration.builder().withColumnCount(n).build()`
  * `new CsvParserConfiguration(List<String>)` → `CsvParserConfiguration.builder().withColumnNames(names).build()`
  * `new CsvParserConfiguration(Map<Integer, String>)` → `CsvParserConfiguration.builder().withColumnNamesMapping(map).build()`
  * Full constructors (7-param and 8-param) are migrated using the builder.
  * Setter calls (e.g. `config.setSeparator(';')`) are replaced by the corresponding builder methods (e.g. `.separator(';')`).
  * `createCharset` method has been removed

<Warning>
  ### Mutable configuration passed as method argument

  The OpenRewrite recipe cannot correctly migrate setter calls on a configuration object received as a method parameter. For example:

  ```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
  // Before
  void configure(ICsvParserConfiguration config) {
      config.setSeparator(';');
  }
  ```

  The recipe will produce:

  ```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
  // After (INCORRECT — the new object is never returned or used)
  void configure(CsvParserConfiguration config) {
      config = config.toBuilder().separator(';').build();
  }
  ```

  Because these configuration classes are now immutable, the reassignment to the local variable has no effect on the caller. Review such methods manually and refactor them to return the updated configuration instead:

  ```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
  // Correct
  CsvParserConfiguration configure(CsvParserConfiguration config) {
      return config.toBuilder().separator(';').build();
  }
  ```
</Warning>

* `CsvSourceFactory.create()` static methods are replaced by `ICsvSource.builder()`:
  * `CsvSourceFactory.create()` → `ICsvSource.builder().build()`
  * `CsvSourceFactory.create(name)` → `ICsvSource.builder().name(name).build()`
  * `CsvSourceFactory.create(closeCallback)` → `ICsvSource.builder().closeCallback(closeCallback).build()`
  * `CsvSourceFactory.create(name, closeCallback)` → `ICsvSource.builder().name(name).closeCallback(closeCallback).build()`
* The `ICsvParserConfiguration` interface has been removed; replace all usages (return types, variable declarations, and parameter types) with the concrete `CsvParserConfiguration` class.
* The `IFileParserConfiguration` interface has been removed; replace all usages (return types, variable declarations, and parameter types) with the concrete `CsvParserConfiguration` class.
* The concrete `FileParserConfiguration` class has been removed; replace all usages (return types, variable declarations, and parameter types) with the concrete `CsvParserConfiguration` class.
* `CsvSourceConfiguration` and `CsvSourceConfigurationBuilder` constructors are replaced by the builder:
  * `new CsvSourceConfiguration(int, int, boolean, IComparator)` → `CsvSourceConfiguration.builder().parserThreads(t).bufferSize(b).synchronousMode(s).fileComparator(c).build()`
  * `new CsvSourceConfigurationBuilder()` → `CsvSourceConfiguration.builder()`
  * `CsvSourceConfigurationBuilder.DEFAULT_PARSER_THREADS` is deprecated; use `CsvSourceConfiguration.getDefaultParserThreads()` instead.
* The `ICsvSourceConfiguration` interface has been removed; replace all usages (return types, variable declarations, and parameter types) with the concrete `CsvSourceConfiguration` class.
* `SnowflakeProperties#SnowflakePropertiesBuilder#additionalOption(SFSession, String)` is replaced by `SnowflakeProperties#SnowflakePropertiesBuilder#additionalOption(String, String)`. Inline the former call using `SFSession#getPropertyKey()`.
* `IParquetReaderFactory#create(InputFile, ReadSupport<IParquetRecord>, Configuration)` is replaced by `IParquetReaderFactory#create(InputFile, ReadSupport<IParquetRecord>, ParquetConfiguration)`. Wrap the former `Configuration` argument using `new HadoopParquetConfiguration(configuration)`.
* The three `IParquetParser#parse` overloads that take a Hadoop `org.apache.hadoop.fs.Path` have been removed:
  * `parse(org.apache.hadoop.fs.Path, IStoreToParquetMapping, IStoreToParquetMapping...)` → `parse(java.nio.file.Path, IStoreToParquetMapping, IStoreToParquetMapping...)`
  * `parse(org.apache.hadoop.fs.Path, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)` → `parse(java.nio.file.Path, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)`
  * `parse(org.apache.hadoop.fs.Path, Configuration, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)` → `parse(java.nio.file.Path, ParquetConfiguration, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)`. Wrap the former Hadoop `Configuration` argument with `new HadoopParquetConfiguration(configuration)`.
* The `factory` parameter type in four `IParquetParser#parse` overloads changed from `Function<ICloudEntityPath<EntityT>, ? extends SeekableByteChannel>` to `ICloudEntityChannelFactory<EntityT>`. The affected overloads are:
  * `parse(ICloudDirectory<EntityT>, Function<ICloudEntityPath<EntityT>, ? extends SeekableByteChannel>, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)`
  * `parse(ICloudDirectory<EntityT>, ParquetConfiguration, Function<ICloudEntityPath<EntityT>, ? extends SeekableByteChannel>, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)`
  * `parse(ICloudEntityPath<EntityT>, Function<ICloudEntityPath<EntityT>, ? extends SeekableByteChannel>, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)`
  * `parse(ICloudEntityPath<EntityT>, ParquetConfiguration, Function<ICloudEntityPath<EntityT>, ? extends SeekableByteChannel>, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)`
* `IAgent` no longer extends `IExtendedPluginValue`. Implementations of `IAgent` should now also explicitly implement `IExtendedPluginValue` if needed.
* The three Logback conversion-rule converters have been moved out of the `apm` module into dedicated logging artifacts. Update the fully-qualified class names referenced in your `logback.xml`/`logback-spring.xml` `<conversionRule>` declarations:
  * `com.activeviam.apm.api.logging.LogInstanceConverter` → `com.activeviam.tech.logging.logback.api.LogInstanceConverter` (artifact `com.activeviam.tech:logging-logback`)
  * `com.activeviam.apm.api.logging.LogThreadConverter` → `com.activeviam.tech.logging.logback.api.LogThreadConverter` (artifact `com.activeviam.tech:logging-logback`)
  * `com.activeviam.apm.api.logging.LogUserConverter` → `com.activeviam.tech.logging.logback.spring.api.LogUserConverter` (artifact `com.activeviam.tech:logging-logback-spring`)
* The `IMultiVersionDataActivePivot` interface has been moved from package `com.activeviam.activepivot.dist.impl.api.cube` to `com.activeviam.activepivot.dist.datanode.impl.api.cube`.
* `NoTransactionException` has been moved in the public API, from package `com.activeviam.database.datastore.internal` to `com.activeviam.database.datastore.api.transaction`.
* `GetAggregatesQuery` constructors are replaced by `GetAggregatesQuery.builder()`. Use the builder methods corresponding to the fields you were passing to the constructor, then call `.build()`.
* `DrillthroughQuery` constructors are replaced by `DrillthroughQuery.builder()`. Use the builder methods corresponding to the fields you were passing to the constructor, then call `.build()`.
