* #2540 Add DTO mapping from Entity beans via generated mapper code
A large feature, refer to the docs / guides etc. This is a bit like MapStruct in that it generates mapping code via annotation processing but it ALSO creates an optimised FetchGroup for the destination DTO graph and it also implements a generic interface such that it can be fluently used via query.mapTo().
The value is that it automates the mapping code from entity -> dto plus optimises the query used to support building the DTO graph.
Expected to be better to use than MapStruct for ebean orm users.
* Bump ebean-annotation to 8.6 with the dto annotations
* Adjust the build order to via test dependency on ebean-api
---------
Co-authored-by: robin.bygrave <robin.bygrave@eroad.com>
* ebean-redisson - initial commit
* Thread.sleep(150) in IntegrationTest - ebean-redisson
* Fix two tenant-aware cache bugs in ebean-redisson + add test coverage
CacheCodec.getMapKeyDecoder() was returning only the tenant portion of
"id:tenantId" Redis field names (substring after the first colon). This
caused every tenant-aware getAll() call to miss: the decoded key did not
match the lookup key, so the DuelCache near-cache warm-up path also
failed to populate.
RedissonCache.getAll() was returning String keys instead of the original
key objects passed in. This broke the ServerCache contract and caused
DuelCache.near.putAll() to store entries under plain strings, making all
subsequent near.get(originalId) calls miss even when the remote cache had
the data.
Additional issues found while reviewing against ebean-redis:
- RServerCacheNotify.notify() was calling listener.notify() locally,
causing a second redundant cache invalidation on the originating node
(ebean-redis does not do this).
- processTableNotify() had no null-guard on listener, risking NPE if a
remote table-mod message arrived before createCacheNotify() was called.
- errorOnWrite() was throwing RuntimeException; cache writes must be
best-effort and only log on failure.
Tests added:
- RedissonCacheTest: direct cache tests for all operations (put/get,
getAll, putAll, remove, removeAll, clear, statistics, TTL, maxSize trim)
- RedissonCacheFactoryTest: factory tests covering cache type creation,
DuelCache for near caches, query-cache singleton, and cross-factory
cluster notification
- CacheCodecTest: key encoder/decoder regression test that pins the
"full string returned" behaviour for both plain and tenant-aware keys
- SerializableCodecTest, VersionGatedCodecTest: codec round-trip tests
- TenantAwareCacheTest: integration test that creates a tenant-aware
Database and verifies that single-bean finds and multi-ID findList()
calls are isolated per tenant at the Redis level
* 18.2.0 - updated version
* RedissonCache/FactoryTest: start Redis container directly in @BeforeAll
Tests were skipped whenever they ran before the integration tests triggered
DB/Redis container startup. Each test class now calls
RedissonTestFixtures.startRedis() (RedisContainer.builder("latest").start())
which is idempotent and requires no other test class to run first.
assumeTrue(isReachable()) remains as a fallback for Docker-less environments.
@Formula2 is a logical-path alternative to @Formula and a full replacement for it.
Where @Formula requires physical SQL (${ta} placeholders and hand-written joins),
@Formula2 takes a property-path expression and resolves the required joins
automatically:
@Formula2("coalesce(familyName, parent.familyName)")
String derivedFamilyName;
The path prefixes (parent, parent.parent, ...) define the joins needed to
satisfy the formula. Supported everywhere @Formula is:
- select() — root and nested-fetch paths, auto-joined
- where() — predicate paths trigger the extra joins
- orderBy() — order-by paths trigger the extra joins
- having()
- DDL — excluded from generated columns (read-only, like @Formula)
Default behaviour matches @Formula: included in the default select unless marked
@Transient, in which case it is opt-in but still auto-joins when selected.
Implementation:
- Parse @Formula2 after associations are wired, into a logical select fragment
plus the set of join paths (BeanDescriptor/BeanProperty).
- DeployPropertyParser registers formula2 join paths into query includes so the
existing predicate-include -> extra-join machinery builds the LEFT JOINs.
- ElPropertyChain prefixes all ${}/${path} placeholders for nested-path use.
- SqlTreeBuilder accumulates formula2 joins for select paths.
* Enhance ProfileStream to support Open Telemetry
* Add ebean-opentelemetry module
* Add the sql query text as span attribute.
Note: This is a breaking API change here but I'm pretty confident
that no one is using the ProfileStream API - hmmm.
* Otel: Use the query label and transaction label in span name if available
* SpiProfileHandler: Change such that if service loaded, doesn't need ProfileConfig
---------
Co-authored-by: Rob Bygrave <robin.bygrave@gmail.com>
Default prepared statement cache increased from 100 to 300. This could have the
effect of increased memory consumption for applications traded off with potentially
improved performance due to me cached prepared statements for larger applications.
Note that the Postgres itself has a default of 250.
Docker changed and that broke how ebean-test-containers detected the
currently assigned port for a container. That was fixed in 7.18 but
thinking its a good idea to mark that relatively important bug fix
with a bump of the major version to 8.0.
Everyone using ebean-test-containers should consider updating the
ebean-test-containers dependency to 8.0 or 7.18 (both have the fix).