Breaking Changes
0.49.0
For SQLite database, Exposed now requires bumping the SQLite JDBC driver version to a minimum of 3.45.0.0.
0.48.0
In
nonNullValueToString
forKotlinInstantColumnType
andJavaDateColumnType
, the formatted String for MySQL did not match the format received from the metadata whenisFractionDateTimeSupported
is true, so a new formatter specific to that is now used.In
nonNullValueToString
forKotlinLocalDateTimeColumnType
, the formatted String for MySQL did not match the format received from the metadata whenisFractionDateTimeSupported
is true, so a new formatter specific to MySQL is now used.In
nonNullValueToString
forDateColumnType
,JavaLocalDateTimeColumnType
,JavaLocalTimeColumnType
,JavaInstantColumnType
,KotlinLocalDateTimeColumnType
,KotlinLocalTimeColumnType
, andKotlinInstantColumnType
, the correct formatter for MySQL is used when the version (below 5.6) does not support fractional seconds.In
nonNullValueToString
forDateColumnType
andDateTimeWithTimeZoneColumnType
, the formatters used are changed to reflect the fact that Joda-Time stores date/time values only down to the millisecond (up to SSS and not SSSSSS).Functions
anyFrom(array)
andallFrom(array)
now useArrayColumnType
to process the provided array argument when query building.ArrayColumnType
requires a base column type to process contents correctly, and Exposed attempts to resolve the best match internally based on the array content type. A specific column type argument should be provided to the function parameterdelegateType
if the content requires either an unsupported or custom column type, or a column type not defined in theexposed-core
module.exposed-crypt
module now uses Spring Security Crypto 6.+, which requires Java 17 as a minimum version.
0.47.0
The function SchemaUtils.checkExcessiveIndices
is used to check both excessive indices and excessive foreign key constraints. It now has a different behavior and deals with excessive indices only. Also, its return type is now List<Index>
instead of Unit
. A new function, SchemaUtils.checkExcessiveForeignKeyConstraints
, deals with excessive foreign key constraints and has a return type List<ForeignKeyConstraint>
.
0.46.0
When an Exposed table object is created with a keyword identifier (a table or column name) it now retains the exact case used before being automatically quoted in generated SQL. This primarily affects H2 and Oracle, both of which support folding identifiers to uppercase, and PostgresSQL, which folds identifiers to a lower case.
If
preserveKeywordCasing = true
had been previously set inDatabaseConfig
to remove logged warnings about any keyword identifiers, this can now be removed as the property istrue
by default.To temporarily opt out of this behavior and to not keep the defined casing of keyword identifiers, please set
preserveKeywordCasing = false
inDatabaseConfig
:
Exposed 0.49.0 Help
Breaking Changes
0.50.0
The
Transaction
class propertyrepetitionAttempts
is being deprecated in favor ofmaxAttempts
. Additionally, the propertyminRepetitionDelay
should be replaced withminRetryDelay
, andmaxRepetitionDelay
withmaxRetryDelay
. These changes also affect the default variants of these properties inDatabaseConfig
.The property
maxAttempts
represents the maximum amount of attempts to perform a transaction block. Setting it, or the now deprecatedrepetitionAttempts
, to a value less than 1 now throws anIllegalArgumentException
.IColumnType
andColumnType
now expect a type argument.IColumnType.valueFromDB()
also no longer has a default implementation, so an override for this method must be provided in any custom column type implementation. Check this pull request for details regarding this change.
0.49.0
For SQLite database, Exposed now requires bumping the SQLite JDBC driver version to a minimum of 3.45.0.0.
0.48.0
In
nonNullValueToString
forKotlinInstantColumnType
andJavaDateColumnType
, the formatted String for MySQL did not match the format received from the metadata whenisFractionDateTimeSupported
is true, so a new formatter specific to that is now used.In
nonNullValueToString
forKotlinLocalDateTimeColumnType
, the formatted String for MySQL did not match the format received from the metadata whenisFractionDateTimeSupported
is true, so a new formatter specific to MySQL is now used.In
nonNullValueToString
forDateColumnType
,JavaLocalDateTimeColumnType
,JavaLocalTimeColumnType
,JavaInstantColumnType
,KotlinLocalDateTimeColumnType
,KotlinLocalTimeColumnType
, andKotlinInstantColumnType
, the correct formatter for MySQL is used when the version (below 5.6) does not support fractional seconds.In
nonNullValueToString
forDateColumnType
andDateTimeWithTimeZoneColumnType
, the formatters used are changed to reflect the fact that Joda-Time stores date/time values only down to the millisecond (up to SSS and not SSSSSS).Functions
anyFrom(array)
andallFrom(array)
now useArrayColumnType
to process the provided array argument when query building.ArrayColumnType
requires a base column type to process contents correctly, and Exposed attempts to resolve the best match internally based on the array content type. A specific column type argument should be provided to the function parameterdelegateType
if the content requires either an unsupported or custom column type, or a column type not defined in theexposed-core
module.exposed-crypt
module now uses Spring Security Crypto 6.+, which requires Java 17 as a minimum version.
0.47.0
The function SchemaUtils.checkExcessiveIndices
is used to check both excessive indices and excessive foreign key constraints. It now has a different behavior and deals with excessive indices only. Also, its return type is now List<Index>
instead of Unit
. A new function, SchemaUtils.checkExcessiveForeignKeyConstraints
, deals with excessive foreign key constraints and has a return type List<ForeignKeyConstraint>
.
0.46.0
When an Exposed table object is created with a keyword identifier (a table or column name) it now retains the exact case used before being automatically quoted in generated SQL. This primarily affects H2 and Oracle, both of which support folding identifiers to uppercase, and PostgresSQL, which folds identifiers to a lower case.
If
preserveKeywordCasing = true
had been previously set inDatabaseConfig
to remove logged warnings about any keyword identifiers, this can now be removed as the property istrue
by default.To temporarily opt out of this behavior and to not keep the defined casing of keyword identifiers, please set
preserveKeywordCasing = false
inDatabaseConfig
:
0.44.0
SpringTransactionManager
no longer extendsDataSourceTransactionManager
; instead, it directly extendsAbstractPlatformTransactionManager
while retaining the previous basic functionality. The class also no longer implements the Exposed interfaceTransactionManager
, as transaction operations are instead delegated to Spring. These changes ensure that Exposed's underlying transaction management no longer interferes with the expected behavior of Spring's transaction management, for example, when using nested transactions or with@Transactional
elements likepropagation
orisolation
.If integration still requires a
DataSourceTransactionManager
, please add two bean declarations to the configuration: one forSpringTransactionManager
and one forDataSourceTransactionManager
. Then define a composite transaction manager that combines these two managers.If
TransactionManager
functions were being invoked by aSpringTransactionManager
instance, please replace these calls with the appropriate Spring annotation or, if necessary, by using the companion object ofTransactionManager
directly (for example,TransactionManager.currentOrNull()
).spring-transaction
andexposed-spring-boot-starter
modules now use Spring Framework 6.0 and Spring Boot 3.0, which require Java 17 as a minimum version.A table that is created with a keyword identifier (a table or column name) now logs a warning that the identifier's case may be lost when it is automatically quoted in generated SQL. This primarily affects H2 and Oracle, both of which support folding identifiers to uppercase, and PostgreSQL, which folds identifiers to a lower case.
To remove these warnings and to ensure that the keyword identifier sent to the database matches the exact case used in the Exposed table object, please set
preserveKeywordCasing = true
inDatabaseConfig
:
0.44.0
SpringTransactionManager
no longer extendsDataSourceTransactionManager
; instead, it directly extendsAbstractPlatformTransactionManager
while retaining the previous basic functionality. The class also no longer implements the Exposed interfaceTransactionManager
, as transaction operations are instead delegated to Spring. These changes ensure that Exposed's underlying transaction management no longer interferes with the expected behavior of Spring's transaction management, for example, when using nested transactions or with@Transactional
elements likepropagation
orisolation
.If integration still requires a
DataSourceTransactionManager
, please add two bean declarations to the configuration: one forSpringTransactionManager
and one forDataSourceTransactionManager
. Then define a composite transaction manager that combines these two managers.If
TransactionManager
functions were being invoked by aSpringTransactionManager
instance, please replace these calls with the appropriate Spring annotation or, if necessary, by using the companion object ofTransactionManager
directly (for example,TransactionManager.currentOrNull()
).spring-transaction
andexposed-spring-boot-starter
modules now use Spring Framework 6.0 and Spring Boot 3.0, which require Java 17 as a minimum version.A table that is created with a keyword identifier (a table or column name) now logs a warning that the identifier's case may be lost when it is automatically quoted in generated SQL. This primarily affects H2 and Oracle, both of which support folding identifiers to uppercase, and PostgreSQL, which folds identifiers to a lower case.
To remove these warnings and to ensure that the keyword identifier sent to the database matches the exact case used in the Exposed table object, please set
preserveKeywordCasing = true
inDatabaseConfig
:
0.43.0
In all databases except MySQL, MariaDB, and SQL Server, the
ubyte()
column now maps to data typeSMALLINT
instead ofTINYINT
, which allows the full range ofUByte
values to be inserted without any overflow. Registering the column on a table also creates a check constraint that restricts inserted data to the range between 0 andUByte.MAX_VALUE
. If a column that only uses 1 byte of storage is needed, but without allowing any non-negative values to be inserted, please use a signedbyte()
column instead with a manually created check constraint:
0.43.0
In all databases except MySQL, MariaDB, and SQL Server, the
ubyte()
column now maps to data typeSMALLINT
instead ofTINYINT
, which allows the full range ofUByte
values to be inserted without any overflow. Registering the column on a table also creates a check constraint that restricts inserted data to the range between 0 andUByte.MAX_VALUE
. If a column that only uses 1 byte of storage is needed, but without allowing any non-negative values to be inserted, please use a signedbyte()
column instead with a manually created check constraint:
In all databases except MySQL and MariaDB, the
uint()
column now maps to data typeBIGINT
instead ofINT
, which allows the full range ofUInt
values to be inserted without any overflow. Registering the column on a table also creates a check constraint that restricts inserted data to the range between 0 andUInt.MAX_VALUE
. If a column that only uses 4 bytes of storage is needed, but without allowing any non-negative values to be inserted, please use a signedinteger()
column instead with a manually created check constraint:
In all databases except MySQL and MariaDB, the
uint()
column now maps to data typeBIGINT
instead ofINT
, which allows the full range ofUInt
values to be inserted without any overflow. Registering the column on a table also creates a check constraint that restricts inserted data to the range between 0 andUInt.MAX_VALUE
. If a column that only uses 4 bytes of storage is needed, but without allowing any non-negative values to be inserted, please use a signedinteger()
column instead with a manually created check constraint:
0.42.0
SQLite The table column created using
date()
now uses TEXT datatype instead of DATE (which the database mapped internally to NUMERIC type). This applies to the specificDateColumnType
in all 3 date/time modules and meansLocalDate
comparisons can now be done directly without conversions.H2, PostgreSQL Using
replace()
now throws an exception as the REPLACE command is not supported by these databases. Ifreplace()
was being used to perform an insert or update operation, all usages should instead be switched toupsert()
. See documentation for UPSERT detailsOperator classes
exists
andnotExists
have been renamed toExists
andNotExists
. The functionsexists()
andnotExists()
have been introduced to return an instance of their respectively-named classes and to avoid unresolved reference issues. Any usages of these classes should be renamed to their capitalized forms.customEnumeration()
now registers aCustomEnumerationColumnType
to allow referencing by another column. The signature ofcustomEnumeration()
has not changed and table columns initialized using it are still of typeColumn<DataClass>
.Transaction.suspendedTransaction()
has been renamed toTransaction.withSuspendTransaction()
. Please runEdit -> Find -> Replace in files...
twice withsuspendedTransaction(
andsuspendedTransaction
as the search options, to ensure that both variants are replaced without affectingsuspendedTransactionAsync()
(if used in code).The
repetitionAttempts
parameter intransaction()
has been removed and replaced with a mutable property in theTransaction
class. Please remove any arguments for this parameter and assign values to the property directly:
0.42.0
SQLite The table column created using
date()
now uses TEXT datatype instead of DATE (which the database mapped internally to NUMERIC type). This applies to the specificDateColumnType
in all 3 date/time modules and meansLocalDate
comparisons can now be done directly without conversions.H2, PostgreSQL Using
replace()
now throws an exception as the REPLACE command is not supported by these databases. Ifreplace()
was being used to perform an insert or update operation, all usages should instead be switched toupsert()
. See documentation for UPSERT detailsOperator classes
exists
andnotExists
have been renamed toExists
andNotExists
. The functionsexists()
andnotExists()
have been introduced to return an instance of their respectively-named classes and to avoid unresolved reference issues. Any usages of these classes should be renamed to their capitalized forms.customEnumeration()
now registers aCustomEnumerationColumnType
to allow referencing by another column. The signature ofcustomEnumeration()
has not changed and table columns initialized using it are still of typeColumn<DataClass>
.Transaction.suspendedTransaction()
has been renamed toTransaction.withSuspendTransaction()
. Please runEdit -> Find -> Replace in files...
twice withsuspendedTransaction(
andsuspendedTransaction
as the search options, to ensure that both variants are replaced without affectingsuspendedTransactionAsync()
(if used in code).The
repetitionAttempts
parameter intransaction()
has been removed and replaced with a mutable property in theTransaction
class. Please remove any arguments for this parameter and assign values to the property directly:
In all databases except MySQL and MariaDB, the
ushort()
column now maps to data typeINT
instead ofSMALLINT
, which allows the full range ofUShort
values to be inserted without any overflow. Registering the column on a table also creates a check constraint that restricts inserted data to the range between 0 andUShort.MAX_VALUE
. If a column that only uses 2 bytes of storage is needed, but without allowing any non-negative values to be inserted, please use a signedshort()
column instead with a manually created check constraint:
In all databases except MySQL and MariaDB, the
ushort()
column now maps to data typeINT
instead ofSMALLINT
, which allows the full range ofUShort
values to be inserted without any overflow. Registering the column on a table also creates a check constraint that restricts inserted data to the range between 0 andUShort.MAX_VALUE
. If a column that only uses 2 bytes of storage is needed, but without allowing any non-negative values to be inserted, please use a signedshort()
column instead with a manually created check constraint: