Add Postgres specific support for binding an array of byte[] with ANY(?)
which is used as with client side encryption where the bind values are
implicitly converted to byte[].
Fixes Postgres specific failure running TestEncryptClientSide.java
Currently, this bug fix needs to be enabled explicitly via ebean.mf with:
allow-nullable-dbarray: true
We will look to enable this bug fix by default shortly noting that some code
will see a behaviour change. We need to publicise it well when we do turn
this on by default.
This bug fix is actually in ebean-agent 13.10.0 and all this change in ebean-core
does is read the new `@DbArray(nullable=false)` attribute [as a new alternative to
using `@NotNull` or `@Column(nullable=false)`]
- When detected markerAnnotation (e.g. Jackson annotation) then go directly to createJsonObjectMapperType()
- Simplify for the simple List, Set and Map of Object cases.
The issue fixed here is that SavepointTransaction was effectively using the
TransactionEvent of the underlying 'parent' transaction. The fix is for
SavepointTransaction to have its own TransactionEvent.
Typically useful for handling DuplicateKeyException where we expect
DuplicateKeyException to be thrown and catch it with the intention of
continuing processing using the same transaction.
Note that some databases like Oracle do not require this explicit
rollback() and would work without the rollbackAndContinue(). Postgres
in particular requires the rollback() call on the underlying connection
such that we can continue using that transaction/java.sql.Connection.
Note that in the existing test we can see that rollbackAndContinue()
is pretty close to being syntactic sugar. I think adding rollbackAndContinue()
is justified and complements the existing commitAndContinue().
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.