The reason for this is that as part of DefaultOrmQuery.copy() it uses
DefaultExpressionList.copy() and that assumed that expressions were
safe to share which is NOT the case for IN and EXISTS sub-query expressions
so InQueryExpression and ExistsQueryExpression
The effective fix for this is that DefaultExpressionList.copy() changes
to call SpiExpression.copy() and for InQueryExpression and ExistsQueryExpression
to implement that copy() by creating a copy of the sub-query.
A "side-fix" is that in DefaultOrmQuery.createExtraJoinsToSupportManyWhereClause()
it was creating an instance of ManyWhereJoins, then mutating it ... and if we
change that to only doing the assignment at the end (object assignment is atomic)
then racy access reading ManyWhereJoins would always get a fully completed non-mutating
instance of ManyWhereJoins. Noting this because it kind of points to where I think
the race condition is (in createExtraJoinsToSupportManyWhereClause()) but noting that
with the change to DefaultExpressionList.copy() this "side-fix" isn't required per say.
Moves the joda-time ScalarTypes into a new ebean-joda-time module. Include
the ebean-joda-time module in the classpath, and the extra types will be
service loaded (by DefaultTypeManager).
Due to the move and change of CsvReader using StringParser ScalarType no longer
needs that general convertFromMillis() method. Note that date and dateTime ScalarTypes
still retain this conversion method.
So the complexity cost doesn't justify itself against only being used
by CSV reader to validate when assigning a date/time format to a property
/ expression path.
For example, can apply a lower case underscore naming convention to the metrics names. This
can be done such that it doesn't have to be applied every time the metrics are collected and
reported.
Currently, lastAccessTime can mutate during cache trim processing. This fixes this issue by taking a copy of the lastAccessTime storing as lastAccessSort and using that for sorting for cache trim.
The design change is to use TenantAwareCache to deal with wrap/unwrap of tenant aware keys, removing any tenant awareness from the underlying cache implementations (DefaultServerCache, redis, hazelcast etc).
With the view that we can optimise the readOnly + disableLazyLoad case by using InterceptReadOnly which doesn't need to support any of the flags used as part of mutation.
The change for #2121 brought in a regression where the scheduledExecutorService was used for processing ALL submitted tasks (not just scheduled ones) and is a bounded executor service. Previously non-scheduled tasks went to a "newCachedThreadPool" based executor service and with this change we are moving back to that (via restoring and using the DaemonExecutorService for those tasks).