Without this fix, a DbArray of List<Integer> on the plaforms that do NOT natively
support it like MySQL, Oracle, SQL Server fallback to a JSON array and this didn't
support all the specific types like Integer.
This adds the appropriate element converters when reading values, including Integer, Long, floating-point, BigDecimal, date/time, and UUID types. This prevents JSON numeric values from being returned as Long for List<Integer> properties.
This is handy when compiling to native image with GraalVM and using Postgis and DriverWrapperLW
Adds the PGbox2d, PGbox3d, PGgeography, PGgeographyLW, PGgeometry, PGgeometryLW
Co-authored-by: robin.bygrave <robin.bygrave@eroad.com>
* Dto mapper generation support for @DbArray
Currently it is not detected DbArray and instead thinking its a ToMany which is invalid.
* Dto mapper generation support for @DbJson collections
Currently it is not detected and instead thinking its a ToMany which is invalid.
---------
Co-authored-by: robin.bygrave <robin.bygrave@eroad.com>
* Publish timed metric max values over rolling 59-second windows
* Publish timed metric max values over rolling 59-second windows
Use "now - 2 * WINDOW_NANOS" on initialise and reset to ensure
the next collection publishes.
---------
Co-authored-by: robin.bygrave <robin.bygrave@eroad.com>
This is handy when compiling to native image with GraalVM and using Postgis and DriverWrapperLW
Co-authored-by: robin.bygrave <robin.bygrave@eroad.com>
* Add test for #1852 : cascaded delete order broken by a write from a persist callback
A join entity owns the foreign key to the bean its delete cascades to, so the join row
has to be deleted first. When a BeanPersistController writes to the database from
preDelete, that write flushes the batch from inside the flush that is already running :
the outer flush has taken the join rows out of their bean holder, so the inner flush
finds only the assets and executes them first, which fails on the foreign key.
BatchControl flush [DcoLink:0 d:2, DcoAsset:1 d:2] <- outer flush
BatchControl flush [DcoLink:0 d:0, DcoAsset:1 d:2, DcoAudit:2 i:1] <- from preDelete
The scenario is fixed as a side effect of a2f954a60 (#3830, released in 18.3.0) which
moved controllerPreDelete() ahead of the cascade. The test pins that down : it fails
with a DataIntegrityException on a2f954a60~1 and passes on master. The graph is fetched
up front on purpose, a lazy load would flush the batch on its own and hide the ordering.
* Add failing test reproducing #1852 : out of order cascaded delete on a self referencing tree
The shape reported on the issue in 2019 : a container cascades the delete down a tree of
TreeBean, and the deletes are not issued deepest first. On 18.4.0 :
delete from dco_tree where id in (?) -- the root, whose children are still there
delete from dco_tree where id in (?,?,?)
delete from dco_tree where id in (?,?)
Referential integrity constraint violation: FK_DCO_TREE_PARENT_ID.
This is a different defect from the batch reordering fixed by a2f954a60 : nothing is batched
here, the recursion itself walks the tree in the wrong order. Disabled so it does not break
the build, remove the annotation to see the failure.
* FIX: a persist done from a BeanPersistController callback flushes the batch mid-execution
#3148 stopped a query performed from a callback from flushing the batch that is already
executing : BatchControl.executeNow disables flushOnQuery for the duration. A persist done
from the same callback is not covered. It reaches BatchControl.executeOrQueue, which flushes,
and the statements queued behind the one currently executing are issued early.
Saving a parent/child graph in batch while an audit row is written from preInsert issues the
children before their parent has an id :
insert into dco_link (parent_id, asset_id) values (?,?)
NULL not allowed for column "PARENT_ID"
Same defect on the delete side, where the join rows are issued after the beans they reference
(#1852, #3185) — that path no longer reproduces since a2f954a60 moved controllerPreDelete()
ahead of the cascade, but only preDelete was moved, so preInsert and preUpdate still run
inside the flush.
Guard executeOrQueue with the same reasoning as the existing flushOnQuery guard : while the
batch is executing, queue rather than flush. The statements added meanwhile are picked up by
the do/while loop in executeAll().
* FIX: same guard on executeStatementOrBatch, a SqlUpdate from a callback also flushes mid-execution
executeStatementOrBatch() flushes on (batchFlushOnMixed && !isBeansEmpty()), and persistedBeans
is only cleared once executeAll() returns, so during the batch execution that condition holds and
a SqlUpdate run from a BeanPersistController callback re-enters the flush the same way a save does.
Reproduced with the same test, the callback running a SqlUpdate instead of a save :
insert into dco_link (parent_id, asset_id) values (?,?)
NULL not allowed for column "PARENT_ID"
The second flush of that method, on pstmtHolder.maxSize() >= batchSize, is left untouched : it can
only trigger when the pstmt holder fills up mid-execution and there is no test covering it.
Read-only TxScope previously ignored isolation when creating
ImplicitReadOnlyTransaction. Apply setIsolationLevel after
createReadOnlyTransaction so @Transactional(readOnly=true, isolation=...)
and TxScope setReadOnly+setIsolation take effect.
Co-authored-by: arimu1 <19286898+arimu1@users.noreply.github.com>
* Metrics - support both CUMULATIVE and DELTA metrics collection concurrently
ebean insight [and StatsD] work off DELTA metrics, where as OTEL
and Prometheus want CUMULATIVE. With this change we can have a metrics
collection for ebean insight using DELTA mode and have a second collection
use CUMULATIVE for reporting to OTEL - for the case of fan-out metrics
going to 2 places.
This isn't strictly needed when only one collection mode is used.
* Metrics - Add Mode with RESET, DELTA and CUMULATIVE
Previously we were overloading RESET and DELTA but we really need
these to be 2 separate modes for the existing tests and the
get(reset) api
* Fix test TestNatKeyCacheWithForeignKey with cache stats reset
---------
Co-authored-by: robin.bygrave <robin.bygrave@eroad.com>
* DB2 exists - use existsWithCaseWhen true, similar to #3849
Fixes exists() query regression with DB2 by using the platform flag existsWithCaseWhen = true;
* DB2 using existsFromClause = " from sysibm.sysdummy1";
---------
Co-authored-by: robin.bygrave <robin.bygrave@eroad.com>
* Add FinableQuery, StreamableQuery common interfaces for Query, DtoQuery, MappedQuery, SqlQuery
* QueryBean.cancel() added to support the new common FindableQuery interface
---------
Co-authored-by: robin.bygrave <robin.bygrave@eroad.com>