Release Notes
Kronos strictly adheres to the Semantic Versioning 2.0.0 specification.
- Current Version:
0.4.0
Update Logs
0.4.0
Fix the SLF4J adapter API class name and verify levels, messages, exceptions and the global switch against the real SLF4J facade and Logback backend.
Consolidate logging under
Kronos.logging: disable every Kronos logger withenabled = false, retain the default["console"]destination, removeKLoggerType.NONE, and add shared minimum-level filtering (#292).Share KPojo models, SQL construction, queries, mutations, table operations and value codecs through Kotlin Multiplatform
commonMain. Publish JVM and Kotlin/Native variants for Apple, Linux and Windows targets.Connect platform database drivers through
KronosExecutionDataSourceandKronosExecutionWrapper. Add the KMP setup and Native SQLite guides alongside the Android/JVM SQLite guide.Generate and aggregate KPojo factories and enum metadata across Native module dependencies. Initialize the final application metadata graph with
initializeKronosMetadata().Use Kotlin
2.4.21and manage test serialization dependencies with the version catalog.Add GitHub Actions gates for JVM, Android/JVM, Apple, Linux and Windows, including real SQLite execution in the reference applications.
Upgrade notes
Replace
Kronos.logPath,Kronos.loggerTypeandKronos.defaultLoggerwithKronos.logging.path,Kronos.logging.typeandKronos.logging.factory. Disable logging withKronos.logging.enabled = false.Update Kronos libraries and compiler/Gradle plugins together to
0.4.0, and use Kotlin2.4.21.Set the shared time zone with an IANA identifier, for example
Kronos.timeZone = "Asia/Shanghai". For a JVMjava.time.ZoneIdvalue, assign its.idstring.Put portable models and query code in
commonMain; keep Java and JDBC types in JVM source sets. CallinitializeKronosMetadata()in the final Kotlin application or framework before database operations.
0.3.1
- ✨ Add built-in H2 and DM8 dialects for queries, table operations, schema metadata, pagination, and upserts. Set
databaseTypetoDBType.H2orDBType.DM8; H2 usesMERGEfor upserts and DM8 supports native identity columns (#288, #289). - ✨ Add JDBC connection and result-mapping helpers:
Kronos.connect(...),DriverManagerDataSource, andKronosRow. Query results and raw SQL can be mapped one row at a time with aKronosRowlambda. - ✨ Use Kotlin
Stringexpressions such as.length,.count(),.replace(...),.substring(...),.subSequence(...),.take(...), and.takeLast(...)in projections, conditions, and insert-select expressions. - ✨ Improve built-in SQL function support across the seven built-in dialects, so common calls such as
log,trunc,right,groupConcat, andrepeatuse the SQL form supported by the selected database.
Upgrade notes
- This release is additive. Update Kronos modules and the compiler-plugin to
0.3.1together.
0.3.0
- ✨ Add a
KType-awareValueCodecpipeline for custom conversion and serialization, generated KPojo factories, and enum metadata.ValueTransformerandKronosSerializeProcessorare replaced byKronos.registerValueCodec(...)(#283). - ✨ Add
KSelectable<Selected>.filter { ... }for querying a selected result through an explicit derived-query boundary (#282). - ✨ Add Android/JVM SQLite integration through the Gradle plugin,
kronos-core, and an AndroidSQLiteDatabasewrapper. The Android SQLite guide and kronos-example-android reference application coverAndroidSQLiteDataSourceWrapper, setup, transactions, and logging (#284). - ✨ Expand condition lowering for iterable predicates and SQL string functions (#284).
- 🐛 Make
syncTable()stable across dialects by normalizing schema column types, index definitions, and default access methods. Automatically generatedLongtemporal values now bind as epoch milliseconds (#270, #276). - 🐛 Cascade inserts now carry assigned, custom, UUID, and Snowflake primary keys through child foreign keys (#274).
- 🐛 Diagnose unregistered captured KPojo fields in conditions at compile time while preserving ordinary captured Kotlin values, and add
takeUnlesscondition gates (#271, #272). - 🐛 Report unsupported generic KPojo declarations during FIR analysis instead of failing later in IR generation (#278).
- 🧩 Add opt-in source alias overrides for duplicate projection outputs and use stable
_Nnames such asid_1for mapped, generated, and derived fields (#279). - 📚 Document dialect-specific
@Defaultexpressions, logic-delete defaults (#275, #277). - 🔧 Check the external Ktor, Spring Boot, Solon, Vert.x, and Android examples against the current Maven Local artifacts in CI (#285).
Upgrade notes
- Replace
ValueTransformerandKronosSerializeProcessorregistrations withKronos.registerValueCodec(...)and theValueCodecAPIs. - A captured KPojo that is not a source of the current condition must read a Kotlin property through
.value. Generic KPojo declarations need concrete property types instead of class type parameters. - Duplicate projection outputs require
@OptIn(UnsafeProjectionOverride::class). Automatically disambiguated output names now use_N, so code that reads keys such asid@1should useid_1or an explicit alias.
0.2.4
- 🐛 Fix generated projection typing for identity-source selections and preserve source metadata, including
@Serialize, across aliased, generated, window-derived, and nested projections (#246). - 🐛 Fix ordinary Kotlin
if/whencondition lowering so only the selected SQL branch and its parameters are emitted; makecontains,startsWith, andendsWithescape literal LIKE wildcards (#249). - 🐛 Fix self-joins, repeated-table joins, correlated subqueries, and nested query layers by binding fields to runtime source identities and renaming colliding parameters (#252).
- 🐛 Fix named-parameter binding so collections expand only at explicit list occurrences, while
ByteArrayand other array values remain single JDBC parameters; add JDBC type hints for null temporal and binary values (#251). - 🐛 Make cursor pagination deterministic by appending a primary or unique-key tie-breaker, carrying hidden cursor fields for map results, and preserving rows tied on a non-unique order value. Also fix
limit(0)(#248). - 🐛 Fix upsert conflict-target inference for generated custom primary keys and replace aggregate existence probes with
SELECT 1, allowing PostgreSQL row locking (#247). - 🐛 Improve temporal conversion, DDL/default rendering, boolean predicates, CREATE TABLE AS SELECT, schema synchronization, codegen data-source setters, and mutation SQL across MySQL, PostgreSQL, SQLite, SQL Server, and Oracle (#250).
Upgrade notes
- Replace condition-level
ifNoValue(...)calls with ordinary Kotlin control flow. Use.takeIf(...)to omit a predicate, orif/elsewithtrue.asSql()/false.asSql()for an explicit fallback. - Cursor pagination now requires a primary key or unique index when the requested ordering is not already unique. Map results hide automatically added tie-breaker columns; typed projections must select every cursor field needed to construct the next token.
0.2.3
- ✨ Use typed cursor pagination through
cursor(pageSize, after), returningCursorResult(hasNext, nextCursor, records)as an execution-only stage. - ✨ Use
page(...).withTotal().toList()/toMapList()for namedPageResult(total, records, totalPages, pageIndex, pageSize)values; offset pages remain selectable. - 🐛 Fix derived-source and window-alias projection SQL so logical output names such as
rn,userName, andcreateTimeremain available in later query layers. - 🧩 Improve projection completion, including generated projection completion for
it.and safer handling of IntelliJ cancellation exceptions. - 📚 Refresh README, documentation macros, release snippets, and AI skill guidance for
0.2.3.
0.2.2
- ✨ Add metadata-backed KPojo runtime properties and refresh the public metadata guidance for generated column access (#240).
- 🐛 Fix compiler/core DSL handling for null-safe conditions, Elvis/selectable set values, generated keys, cascade and strategy edge cases, and DDL metadata casing (#240).
- 🐛 Publish
kronos-syntaxas an API dependency ofkronos-coreso downstream projects can compile DSL calls that expose syntax types without declaringkronos-syntaxdirectly (#241). - 🎨 Refresh documentation UI details, including the dark-theme language switcher, logo assets, and responsive docs layout (#238, #239, #240).
- 🔧 Add example-project smoke tests for Ktor, Spring Boot, and Solon, publish current artifacts to Maven local in CI, skip signing for local release-version publishing, and update examples for the current metadata API (#240, #241).
- 💪 Expand compiler, core, integration, and example coverage for projection, condition, set, utility, SQL Server, and strategy edge cases (#240).
- 📦 Prepare the stable
0.2.2release and update install snippets, documentation macros, plugin README files, and AI skill guidance.
0.2.1
- ✨ Support
it - [it.id, it.age]inside projection[], including mixed projection lists such as[it - [it.id, it.age], it.id.alias("sourceId")]. - 🔧 Make the release workflow's next SNAPSHOT PR step idempotent so reruns skip an already-open version PR instead of failing on an existing branch.
- 📚 Refresh README, documentation macros, user-facing examples, and AI skill references for
0.2.1.
0.2.0
0.2.0contains source- and binary-incompatible public API changes. Recompile the project after upgrading and update call sites and custom integrations as described below.
Breaking API changes
Query terminal operations now use collection-conversion and single-row terminology consistently:
0.1.x | 0.2.0 |
|---|---|
query() | toMapList() / toList<Map<String, Any?>>() |
queryList<T>() | toList<T>() |
queryMap() | toMap() / first<Map<String, Any?>>() |
queryMapOrNull() | toMapOrNull() / firstOrNull<Map<String, Any?>>() / first<Map<String, Any?>?>() |
queryOne<T>() | first<T>() |
queryOneOrNull<T>() | firstOrNull<T>() / first<T?>() |
PagedClause.query() | PagedClause.toMapList() |
PagedClause.queryList() | PagedClause.toList() |
toMapList(), toMap(), and toMapOrNull() are convenience methods for the corresponding generic forms; in general, firstOrNull<T>() is also equivalent to first<T?>(). Map query results now use Map<String, Any?>, preserving selected SQL NULL values. QueryType is reduced to ToMapList, ToList, ToMap, and First; projects that inspect query events must update their enum branches. Raw SQL extensions now come from com.kotlinorm.database.SqlExecutor, and the former SqlHandler object has been removed.
The built-in JDBC wrapper is now consistently exposed as KronosJdbcWrapper. Projects upgrading from older releases that still use the legacy KronosBasicWrapper must update both the class and package name:
// Legacy API
import com.kotlinorm.KronosBasicWrapper
val wrapper = KronosBasicWrapper(dataSource)
// 0.2.0
import com.kotlinorm.wrappers.KronosJdbcWrapper
val wrapper = KronosJdbcWrapper(dataSource)Custom KronosDataSourceWrapper implementations must replace forList, forMap, and forObject with the following two query entry points. Read the result mapping target from task.targetType:
override fun toList(task: KAtomicQueryTask): List<Any?>
override fun first(task: KAtomicQueryTask): Any?Query tasks and the conversion pipeline now carry complete Kotlin KType metadata:
KAtomicQueryTaskrequirestargetType: KType; directKronosAtomicQueryTaskconstruction must providetypeOf<T>().- The legacy transformer and serialization-processor APIs have been replaced by one bidirectional
ValueCodecregistry. Register codecs withKronos.registerValueCodec; matching and conversion receive complete source and target type metadata throughValueCodecContext. serializedValueCodecadapts one pair of encode/decode functions to all@Serializefields, including generic and nested collection types. There is no separate serializer registry.- The
Fieldconstructor replacescascadeIsCollectionOrArray,kClass, andsuperTypesparameters withkType.kTypeis now the only declaration type identity;elementKTypeandcascadeIsCollectionOrArrayremain derived helpers, whileField.kClassis no longer part of the API.
Features and fixes
- ✨ Preserve complete Kotlin
KTypemetadata across fields, query tasks, serialized fields, and value codecs, including nested generic collections such asList<List<String>>(#232) - 🐛 Fix Kotlinx Serialization deserialization for generic collection and data-class fields, and preserve selected
nullvalues in map and scalar query results (#232) - 🐛 Fix generated projection types for
select { it },select { [it] }, KPojo-minus projections, and mixed full-row plus alias projections using[](#232) - 🐛 Fix SQLite UNION rendering, SQLite schema synchronization, default string values, and other ORM edge cases found by expanded compiler, core, and integration tests (#232)
- 💪 Expand projection, serialization, nullable-result, schema-sync, and cross-database regression coverage; update the README, user docs, AI skill guide, and Gradle plugin for
0.2.0(#232)
0.1.2
- 🐛 Fix
syncTable()schema diffing for custom string primary keys so database metadata primary keys and KPojo@PrimaryKey(custom = true)definitions are treated as the same database primary-key mode (#229) - 🐛 Fix SQLite repeated schema sync after
ADD COLUMNby ignoring column-order-only diffs that SQLite cannot apply withALTER COLUMN(#229) - 💪 Add cross-database integration regression coverage for create V1 table, sync V2 with a new
agecolumn, verify primary-key metadata, and run a second idempotent sync across MySQL, PostgreSQL, SQLite, SQL Server, and Oracle (#229) - 💪 Simplify AI skill installation docs and keep Claude, Codex, Cursor, and generic agent installation paths on the
mainbranch (#228) - 🔧 Fix docs deployment on newer JDKs and bootstrap Java for the docs deployment workflow (#226, #227)
0.1.1
- ✨ Add projection and subquery DSL coverage for generated result-row classes, scalar subqueries, predicate subqueries, INSERT SELECT, and window-function aliases (#222)
- 💪 Reorganize user documentation around getting started, mapping, query, mutation, database, configuration, advanced topics, and resources; refresh examples for table mapping, functions, projection, dialect behavior, and codegen workflows (#222)
- 💪 Improve release automation so formal releases publish Maven artifacts, build JVM jars, attach them to a GitHub Release, and generate release notes automatically (#222)
- 🐛 Fix compiler-plugin type-parameter handling for
SelectFrom10throughSelectFrom16query functions and add official compiler tests for query return types and projection behavior (#222) - 🔧 Use the official Gradle distribution URL for all wrappers to avoid CI failures caused by mirror download timeouts (#222)
0.1.0
- ✨ Release
0.1.0with core module, build configuration, and README version reference updates (#204, #207, #208) - ✨ Add the K2 compiler plugin implementation, replace the old compiler plugin implementation, and publish the K2 plugin as the only main compiler plugin (#204)
- ✨ Add type-safe SQL AST and dialect renderers covering select, insert, update, delete, upsert, DDL, union, and function rendering (#204)
- ✨ Add transaction DSL support for isolation levels, timeout, savepoints, and nested transaction connection reuse; add ThreadLocal transaction connection sharing to the JDBC wrapper (#204)
- 💪 Improve cascade select, cross-module test infrastructure, codegen tests, core ORM/dialect function tests, and coverage CI (#204)
- 💪 Redesign the docs homepage and documentation UI with theme sync, collapsible sidebar, copy-as-markdown, footer, AI docs chapter, and module READMEs (#204)
- 🐛 Fix upsert
criteriaParamsinjection,.set {}assignment, logic-delete existence checks, PostgreSQLANY(ARRAY[...])type mismatches, and PostgreSQL concurrent index creation inside transactions (#204) - 🔧 Update
__tableNameproperty documentation and plugin configuration, and adjust detekt suppressions (#206)
0.0.7
- 🔧 Upgrade Gradle to 9.4.1 and Kotlin to 2.3.0 (#201)
- 🐛 Fix PostgreSQL identity primary key to use BIGSERIAL for BIGINT columns (#201)
- 💪 Refactor table name and comment from functions to properties (
__tableName,__tableComment) (#198) - 🔧 Fix bump-version.sh sed syntax for Linux CI environments (#197)
0.0.6
- ✨ Update Kotlin version to
2.2.21, add support forkotlin.time.Instant(#191) - ✨ Add patch functionality to select clause (#192)
- ✨ Add
takeIfcondition support for conditional query handling (#178) - 💪 Enhance upsert logic with null value handling and logic delete strategy (#188)
- 🐛 Fix criteria missing when join with on clause (#194)
- 🐛 Fix
java.sql.Dateconversion logic and add test case forLocalDatetype parsing (#185) - 🐛 Fix jdbc wrapper
getObject(position)NPE (#184) - 🐛 Handle empty default values in column definitions (#175)
0.0.5
- ✨ Add kClass attribute to DeleteClauseInfo and InsertClauseInfo (#152)
- 💪 Optimize query parameter processing, fix invalid parameter mapping (#150)
0.0.4
- ✨ Add default boolean value handling method
getDefaultBoolean(#147) - 💪 Modify cache implementation to use existing instance instead of creating new instance each time (#145)
- 🐛 Ensure table names are properly quoted in PostgreSQL SQL statements (#142)
0.0.3
- ✨ Add new CodeGen module for code generation (#130)
- ✨ Add DataGuardPlugin to prevent deletion, update, and truncation operations on tables
- ✨ Add LastInsertIdPlugin to support retrieving the last inserted ID
- ✨ Add task event hooks support with QueryEvent and ActionEvent (#123)
- ✨ Add cache and identity configuration (#122)
- ✨ Add named SQL parse cache (#116)
- 💪 Refactor jdbc wrapper (#117)
- 💪 Refactor LastInsertIdPlugin enable logic using plugin registration/unregistration (#125)
- 💪 Update logging DSL (#137)
- 🐛 Fix null value handling logic in InsertClause to adapt SpringData
- 🐛 Fix field index in coverage calculation (#133)
- 🔧 Remove KronosKClassMapperTransformer (#131)
0.0.2
- 🐛 Fix the problem that
@CreateTime,@Updatetable-level annotation parameterenableis not effective whenfalse. Fix global table create time, update time, logical delete field settings so that they only take effect when KPojo contains the field. (#92) - 💪 Optimize instantiation performance by removing the use of
mapas an intermediate variable when converting (#94) - 💪 Add default data source transaction creation function
fun transact(wrapper: KronosDataSourceWrapper? = null, block: () -> Any?)(#94) - 💪 Add cache support for insert statements, 20% performance improvement, see kronos-benchmark for detailed performance data (#100)
- ✨ Add
scaleproperty forField, which is used to specify the scale of the decimal type, and refactor default mapping from kotlin type to Column type, changejava.math.BigDecimal->decimal(fromNUMERIC),kotlin.ByteArray->BLOB(fromBINARY) (#106)
0.0.1
- The first version of Kronos was released, providing all the features described in the ORM documentation.
- Upgraded the minimum supported Kotlin version to
2.1.0.
Use Snapshot Versions
Snapshot versions provide early access to the next release for development and evaluation.
Add the snapshot repository to plugin and dependency resolution, then use the snapshot coordinate.
gradle(groovy)
// settings.gradle
pluginManagement {
repositories {
mavenCentral()
maven {
url "https://central.sonatype.com/repository/maven-snapshots/"
}
}
}
// build.gradle
repositories {
mavenCentral()
maven {
url "https://central.sonatype.com/repository/maven-snapshots/"
}
}
plugins {
id 'com.kotlinorm.kronos-gradle-plugin' version '0.4.1-SNAPSHOT'
}
dependencies {
implementation "com.kotlinorm:kronos-core:0.4.1-SNAPSHOT"
implementation "com.kotlinorm:kronos-jdbc-wrapper:0.4.1-SNAPSHOT"
}gradle(kts)
// settings.gradle.kts
pluginManagement {
repositories {
mavenCentral()
maven {
name = "Maven Central Snapshots"
url = uri("https://central.sonatype.com/repository/maven-snapshots/")
}
}
}
// build.gradle.kts
repositories {
mavenCentral()
maven {
name = "Maven Central Snapshots"
url = uri("https://central.sonatype.com/repository/maven-snapshots/")
}
}
plugins {
id("com.kotlinorm.kronos-gradle-plugin") version "0.4.1-SNAPSHOT"
}
dependencies {
implementation("com.kotlinorm:kronos-core:0.4.1-SNAPSHOT")
implementation("com.kotlinorm:kronos-jdbc-wrapper:0.4.1-SNAPSHOT")
}maven
<project>
<properties>
<kronos.version>0.4.1-SNAPSHOT</kronos.version>
</properties>
<repositories>
<repository>
<id>maven-central-snapshots</id>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.kotlinorm</groupId>
<artifactId>kronos-core</artifactId>
<version>${kronos.version}</version>
</dependency>
<dependency>
<groupId>com.kotlinorm</groupId>
<artifactId>kronos-jdbc-wrapper</artifactId>
<version>${kronos.version}</version>
</dependency>
</dependencies>
<pluginRepositories>
<pluginRepository>
<id>maven-central-snapshots</id>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<compilerPlugins>
<plugin>all-open</plugin>
<plugin>kronos-maven-plugin</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>com.kotlinorm</groupId>
<artifactId>kronos-maven-plugin</artifactId>
<version>${kronos.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>Kotlin Compatibility
| Kronos version | Supported Kotlin version | Notes |
|---|---|---|
0.4.0 | 2.4.21 | Kotlin Multiplatform: JVM, Android/JVM and Kotlin/Native |
0.3.1 | 2.4.0+ | H2 and DM8 dialects, JDBC connection and row mapping, and Kotlin String / cross-dialect SQL functions |
0.3.0 | 2.4.0+ | Android/JVM SQLite support; see the Android SQLite guide |
0.2.0 - 0.2.4 | 2.4.0+ | Kotlin 2.4.0 release line |
0.1.2 | 2.4.0+ | Fixes schema synchronization edge cases and expands cross-database integration coverage |
0.1.1 | 2.4.0+ | Adds projection docs and release automation improvements |
0.1.0 | 2.3.0+ | Stable release line based on Kotlin 2.3.0 |
0.0.7 | 2.3.0+ | Upgraded Gradle and Kotlin in the 0.0.7 release |
0.0.6 | 2.2.21+ | Added kotlin.time.Instant support |
0.0.2 - 0.0.5 | 2.2.0+ | Early development releases before the 2.2.21 upgrade |
0.0.1 | 2.1.0+ | Initial public release line |