Compare commits

...
76 Commits
Author SHA1 Message Date
Rob Bygrave 0842a3f3e2 Version 13.22.0 2023-08-30 22:17:31 +12:00
Rob Bygrave bd0cad723d Add test for Map @OneToMany without orphanRemoval
Without orphanRemoval then map.clear() does not invoke any lazy loading.
2023-08-29 22:16:37 +12:00
Rob BygraveandGitHub c83c85efc3 Merge pull request #3206 from ebean-orm/feature/3173-beanMap-clear
Map.clear() on a @OneToMany orphanRemoval=true invokes 1+N queries du…
2023-08-29 22:10:36 +12:00
Rob Bygrave b6b8f77213 Map.clear() on a @OneToMany orphanRemoval=true invokes 1+N queries due to MapKey
The fix is for LoadManyRequest to detect when a MapKey is on the collection
and include that in the lazy loading query (to avoid the N queries invoked)
2023-08-29 22:08:56 +12:00
Rob Bygrave 770eb06cab Add test for lazy loading @OneToMany using Map 2023-08-29 22:03:58 +12:00
Rob BygraveandGitHub 180b4d6e46 Merge pull request #3205 from ebean-orm/feature/3173-beanSet-clear
Follow up #3173 - Change BeanSet clear() to lazy load ALL properties
2023-08-29 22:02:07 +12:00
Rob Bygrave 5377454476 Follow up #3173 - Change BeanSet clear() to lazy load ALL properties
To avoid the 1+N lazy loading queries that are invoked due to the clear()
when the entity bean in the Set has a hashCode/equals implementation
2023-08-29 21:20:19 +12:00
Rob BygraveandGitHub dbbf6dd566 Merge pull request #3204 from ebean-orm/feature/3173-beanSet-clear
Follow up #3173 - Add test for BeanSet clear() when hashCode/equals used
2023-08-29 21:16:44 +12:00
Rob Bygrave 4b9d4d0a90 Follow up #3173 - Add test for BeanSet clear() when hashCode/equals used
This shows the extra lazy loading that is occurring when clear() is
called on the [Bean]Set DUE to the hashcode/equals implementation that
is present on the entity bean that is in the Set.
2023-08-29 21:13:19 +12:00
Rob Bygrave 90fc4466bf Follow up #3173 - Add test for BeanSet lazy loading OneToMany with hashCode/equals 2023-08-29 18:43:16 +12:00
Rob BygraveandGitHub 0d69377f8b Merge pull request #3203 from ebean-orm/feature/3173-BeanSet
#3173 - BeanSet lazy loading / Too many DataSource connections used
2023-08-29 18:32:04 +12:00
Rob Bygrave 359a55d7a5 #3173 - BeanSet lazy loading / Too many DataSource connections used
- The error reported was that a DataSource connection pool maxed out
- The symptom was that there was an additional lazy loading queries invoked via the hashCode/equals implementation of ManyToMany Set.
- The fix is for BeanSet init() to lazy load with onlyIds = false, that avoids the extra lazy loading query from being executed
2023-08-29 18:28:09 +12:00
Rob BygraveandGitHub b7804e7486 Merge pull request #3197 from ebean-orm/feature/parent-poms
Update ebean-agent to 13.22.0, required to support change in query bean generation
2023-08-27 22:48:17 +12:00
Rob Bygrave febb018036 Update ebean-agent to 13.22.0 2023-08-27 21:59:34 +12:00
Rob BygraveandGitHub dc0585246f Merge pull request #3196 from ebean-orm/feature/parent-poms
Use ebean-parent as parent pom for composites and platforms
2023-08-27 21:55:34 +12:00
Rob Bygrave 22c1848f58 Use ebean-parent as parent pom for composites and platforms 2023-08-27 21:53:11 +12:00
Rob BygraveandGitHub 054ea26893 Merge pull request #3195 from ebean-orm/feature/deprecate-database-commitTransaction
Deprecate for removal Database.commitTransaction() and Database.rollb…
2023-08-27 20:32:07 +12:00
Rob Bygrave 8c30b66d39 Add forRemoval = true on existing @Deprecated 2023-08-27 20:31:03 +12:00
Rob Bygrave 14f9fe68f7 Deprecate for removal Database.commitTransaction() and Database.rollbackTransaction() 2023-08-27 20:30:33 +12:00
Rob Bygrave d56ca5b841 Deprecate for removal Database.commitTransaction() and Database.rollbackTransaction()
Migrate to using try-with-resources and transaction.commit() and transaction.rollback()
2023-08-27 20:29:05 +12:00
Rob BygraveandGitHub 3f97f0f212 Merge pull request #3192 from ebean-orm/feature/spiEbeanServer
Refactor internal SpiEbeanServer API - transaction from SpiQuery
2023-08-26 00:19:16 +12:00
Rob Bygrave 60e0c552ab Fix test for MySql, which does not support delete statement with limit clause 2023-08-26 00:17:57 +12:00
Rob Bygrave f889628677 No functional change, tidy in persist.dml and dmlbind packages only 2023-08-26 00:15:37 +12:00
Rob Bygrave 128bd171f5 Refactor SpiEbeanServer for SpiSqlQuery with transaction (vs passing transaction) 2023-08-25 23:51:09 +12:00
Rob Bygrave 6402a346a1 Reuse via adding SpiOrmQueryRequest.isGetAllFromBeanCache() 2023-08-25 23:28:07 +12:00
Rob Bygrave 0ab0f9c569 Refactor internal SpiEbeanServer API - transaction from SpiQuery
Originally the API took explicit transactions but then the API changed
toward query.usingTransaction(), which means the SpiQuery holds the
explicit transaction.

This change is to update the SpiEbeanServer API to reflect that it can get
explicit transaction from SpiQuery.transaction() rather than pass transaction
around.

Doing this also identified a small bug where L2 cache could be hit when it should
not after there is some update on the transaction (hence the adjustment to the
test TestBeanCache missCount)
2023-08-25 23:15:51 +12:00
Rob BygraveandGitHub 19e21e17cc Merge pull request #3191 from ebean-orm/feature/spiEbeanServer
#3188 Fix findFutureCount() when there is a current transaction in scope
2023-08-25 21:15:15 +12:00
Rob Bygrave 7e60c66759 Follow up for #3188 Add tests for futures when creating new transaction 2023-08-25 21:05:14 +12:00
Rob Bygrave 4f18dc339f Follow up for #3188 Fix findFutureList() and findFutureIds() when txn in scope
Apply the same fix to findFutureList() and findFutureIds()
2023-08-25 20:56:55 +12:00
Rob Bygrave 60a2626f61 #3188 Fix findFutureCount() when there is a current transaction in scope 2023-08-25 20:32:48 +12:00
Rob BygraveandGitHub e3a6f12478 Merge pull request #3190 from ebean-orm/feature/spiEbeanServer
Refactor SpiEbeanServer to use SpiQuery
2023-08-25 20:31:29 +12:00
Rob Bygrave 2e980b06f6 Refactor SpiEbeanServer to use SpiQuery 2023-08-25 17:53:23 +12:00
Rob BygraveandGitHub b27b5512e3 Merge pull request #3189 from ebean-orm/feature/bump-datasource-dependency
Bump to ebean-datasource 8.7
2023-08-25 15:40:39 +12:00
Rob Bygrave 3a013d50d6 Bump to ebean-datasource 8.7 2023-08-25 15:40:09 +12:00
Rob Bygrave 3ebfd2e9e6 Update test only - TestDeleteCascadingOneToMany 2023-08-24 21:01:11 +12:00
Rob BygraveandGitHub f51b69445a Merge pull request #3187 from ebean-orm/feature/3183-deleteQueryIn
Update test only - TestDeleteCascadeById
2023-08-24 20:55:14 +12:00
Rob Bygrave 96904d525f Update test only - TestDeleteCascadeById 2023-08-24 20:54:43 +12:00
Rob BygraveandGitHub 26fa885adb Merge pull request #3186 from ebean-orm/feature/3183-deleteQueryIn
#3183 - Fix for: Wrong limit using setMaxRows on delete between calls
2023-08-24 20:38:32 +12:00
Rob Bygrave f4ca4ec476 #3183 - Fix for: Wrong limit using setMaxRows on delete between calls
Reproduces when the delete needs to perform a select due to caching or
cascading of the delete
2023-08-24 20:35:11 +12:00
Rob Bygrave 327995526e Fix tests for Postgres 2023-08-24 20:17:41 +12:00
Rob BygraveandGitHub dfbbdc7d58 Merge pull request #3182 from ebean-orm/feature/delete-batch-v2
When delete batching, use number of id properties
2023-08-23 10:54:21 +12:00
Rob Bygrave 35894b3d8f When delete batching, ALSO in deleteManyDetails use number of properties
Use int batch = maxDeleteBatch / targetDesc.idBinder().size()
2023-08-22 23:55:55 +12:00
Rob Bygrave 0f219b4cd0 When delete batching, use number of id properties 2023-08-22 23:49:38 +12:00
Rob Bygrave bfe94786de Merge branch 'FOCONIS-experimental-elliminate-not-in-with-too-many-params' 2023-08-22 23:43:41 +12:00
Rob Bygrave 6cab2498dc Merge branch 'experimental-elliminate-not-in-with-too-many-params' of github.com:FOCONIS/ebean into FOCONIS-experimental-elliminate-not-in-with-too-many-params 2023-08-22 23:22:11 +12:00
Rob BygraveandGitHub dbe81bdb6e Merge pull request #3180 from FOCONIS/bugfix/setId-or-idEq-in-subquery
BUG: Using a subquery with idEq or setId is missing the bind value
2023-08-22 22:35:31 +12:00
Jonas Pöhler 2e2b3844fe Tidy test 2023-08-22 11:36:44 +02:00
Jonas Pöhler 78b77dcd82 Potential Fix for using idEq or setId in subquery 2023-08-22 11:04:48 +02:00
Jonas Pöhler 90614adb2b ADD: Testcase to show missing bind values when using idEq or setId in subquery 2023-08-22 11:04:24 +02:00
Rob BygraveandGitHub 019ef43fe7 Merge pull request #3177 from ebean-orm/feature/remove-InTuples-literal-mode
#3166 Remove InTuples literal mode
2023-08-22 08:23:54 +12:00
Rob Bygrave cfb6f0a908 #3166 Remove InTuples literal mode, remove related plan useCache() 2023-08-22 08:18:19 +12:00
Roland Praml 77aeda1753 draft: elliminate the "not in" query that may 'explode' on SqlServer 2023-08-21 17:10:23 +02:00
Roland Praml 2a24ec3d49 Added some tests 2023-08-21 16:51:19 +02:00
Roland Praml d9d09b31b4 Refactored delete-by-id 2023-08-21 15:36:05 +02:00
Rob Bygrave 56550a9534 #3166 Remove InTuples literal mode 2023-08-21 23:16:55 +12:00
Rob BygraveandGitHub f40beb8234 Merge pull request #3175 from ebean-orm/feature/ListsPartition
For Lists.partition() fix for empty list input
2023-08-21 20:37:32 +12:00
Rob Bygrave cb06052c86 For Lists.partition() fix for empty list input
Fix such that empty list input produces an empty list
2023-08-21 20:19:59 +12:00
Rob BygraveandGitHub e09265fbc5 Merge pull request #3174 from FOCONIS/more-char-append
Use char-append instead of String-append
2023-08-21 19:58:42 +12:00
Roland Praml dede93ca62 Use char-append instead of String-append 2023-08-21 08:22:18 +02:00
Rob BygraveandGitHub caf8bd0c0f Merge pull request #3172 from ebean-orm/feature/filterManyRaw
Add filterManyRaw() and Deprecate filterMany( <string expressions> )
2023-08-21 11:30:43 +12:00
Rob Bygrave 01d89a01a5 Fix new test in QCustomerTest 2023-08-21 11:22:02 +12:00
Rob Bygrave b0da647b0e Fix javadoc for filterManyRaw() 2023-08-21 11:17:29 +12:00
Rob Bygrave fbcd4c3133 Add filterManyRaw() and Deprecate filterMany( <string expressions> )
The filterMany( <string expressions> ) uses the language parser which
ultimately will we probably remove in ebean 15.x

Code can migrate to filterManyRaw() instead or better yet change to
use the improved query beans filterMany( <closure> ) option that will
be included in this same ebean release.
2023-08-21 11:15:39 +12:00
Rob BygraveandGitHub 3e41c5973b Merge pull request #3171 from ebean-orm/feature/filterMany-raw-expression
FIX for filterMany with raw expression with single SQL query
2023-08-21 09:39:40 +12:00
Rob Bygrave 1933beed9b Tidy unused import in CQueryPredicates 2023-08-20 23:52:10 +12:00
Rob Bygrave defb35b258 FIX for filterMany with raw expression with single SQL query
Fix for the case where the filterMany is not executed on a separate
query but instead part of the origin query.

The fix is to use the appropriate DeployParser and also fix the path
alias like ${} -> ${contacts}
2023-08-20 23:32:55 +12:00
Rob Bygrave 8a4024ecfc FIX for filterMany with raw expression with single SQL query
Fix for the case where the filterMany is not executed on a separate
query but instead part of the origin query.

The fix is to use the appropriate DeployParser and also fix the path
alias like ${} -> ${contacts}
2023-08-19 13:54:38 +12:00
Rob Bygrave 9756c9133e Improve existing test for filterMany using raw with separate SQL query for filterMany 2023-08-19 13:46:45 +12:00
Rob BygraveandGitHub c07d5e2c97 Merge pull request #3170 from ebean-orm/feature/prefer-char-append
Refactor prefer char append
2023-08-19 11:11:35 +12:00
Rob Bygrave 00e594d4fa Refactor prefer char append 2023-08-19 11:01:15 +12:00
Rob Bygrave 3bf316af2b Update Test QCustomerTest removing extra space character in the SQL 2023-08-19 10:17:00 +12:00
Rob BygraveandGitHub b116d3da28 Merge pull request #3169 from ebean-orm/feature/filterMany-TQAssoc
Add Query bean filterMany() taking a closure
2023-08-19 10:11:46 +12:00
Rob BygraveandGitHub 804618d699 Merge pull request #3168 from ebean-orm/feature/like-extra-space
Remove extra space added to the generated SQL via the LIKE expression
2023-08-19 10:05:17 +12:00
Rob Bygrave 0e9fe6a096 Remove extra space added to the generated SQL via the LIKE expression 2023-08-19 09:29:19 +12:00
Rob Bygrave ded4b94e54 Add Query bean filterMany() taking a closure
Query beans also generate a "Assoc" query bean that is used
for the relationships. Previously these were generated into a
.query.assoc package and with this they are generated as an
inner class of the query bean.

This then allows the change where an additional filterMany()
is generated on the "Assoc" bean that takes a closure. This
simplifies the use of query beans for filterMany.

This change to the generated query beans needs a change to the
ebean-agent enhancement.
2023-08-18 22:12:30 +12:00
Rob Bygrave eb0812df16 Bump to next snapshot 2023-08-17 23:26:26 +12:00
269 changed files with 2768 additions and 1833 deletions
+7 -6
View File
@@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>composites</artifactId>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-clickhouse</name>
@@ -16,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -41,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+7 -6
View File
@@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>composites</artifactId>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-cockroach</name>
@@ -16,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -41,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+7 -6
View File
@@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>composites</artifactId>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-db2</name>
@@ -16,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -41,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+7 -6
View File
@@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>composites</artifactId>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-h2</name>
@@ -16,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -41,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+7 -6
View File
@@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>composites</artifactId>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-hana</name>
@@ -16,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -41,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+7 -6
View File
@@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>composites</artifactId>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-mariadb</name>
@@ -16,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -41,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+7 -6
View File
@@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>composites</artifactId>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-mysql</name>
@@ -16,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -41,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+7 -6
View File
@@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>composites</artifactId>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-nuodb</name>
@@ -16,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -41,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+7 -6
View File
@@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>composites</artifactId>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-oracle</name>
@@ -16,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -41,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+7 -6
View File
@@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>composites</artifactId>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-postgres</name>
@@ -16,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -41,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+7 -6
View File
@@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>composites</artifactId>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-sqlite</name>
@@ -16,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -41,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+7 -6
View File
@@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>composites</artifactId>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-sqlserver</name>
@@ -16,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -41,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+7 -6
View File
@@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>composites</artifactId>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-yugabyte</name>
@@ -16,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -41,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+8 -7
View File
@@ -2,9 +2,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>composites</artifactId>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean (all platforms)</name>
@@ -16,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -40,7 +41,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -59,13 +60,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
</parent>
<artifactId>composites</artifactId>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
</parent>
<name>ebean api</name>
+6
View File
@@ -267,15 +267,21 @@ public final class DB {
}
/**
* Deprecated for removal migrate using try-with-resources and commit on the transaction itself.
* <p>
* Commit the current transaction.
*/
@Deprecated(forRemoval = true)
public static void commitTransaction() {
getDefault().commitTransaction();
}
/**
* Deprecated for removal migrate to using try-with-resources and rollback on the transaction itself.
* <p>
* Rollback the current transaction.
*/
@Deprecated(forRemoval = true)
public static void rollbackTransaction() {
getDefault().rollbackTransaction();
}
@@ -650,13 +650,19 @@ public interface Database {
void flush();
/**
* Deprecated for removal migrate using try-with-resources and commit on the transaction itself.
* <p>
* Commit the current transaction.
*/
@Deprecated(forRemoval = true)
void commitTransaction();
/**
* Deprecated for removal migrate to using try-with-resources and rollback on the transaction itself.
* <p>
* Rollback the current transaction.
*/
@Deprecated(forRemoval = true)
void rollbackTransaction();
/**
@@ -36,6 +36,11 @@ import java.util.Map;
*/
public interface ExpressionFactory {
/**
* Return a new ExpressionList.
*/
<T> ExpressionList<T> expressionList();
/**
* Path exists - for the given path in a JSON document.
*/
@@ -56,7 +56,7 @@ public interface ExpressionList<T> {
/**
* Deprecated migrate to {@link #orderBy(String)}
*/
@Deprecated(since = "13.19")
@Deprecated(since = "13.19", forRemoval = true)
default ExpressionList<T> order(String orderByClause) {
return orderBy(orderByClause);
}
@@ -74,7 +74,7 @@ public interface ExpressionList<T> {
/**
* Deprecated migrate to orderBy().
*/
@Deprecated
@Deprecated(forRemoval = true)
default OrderBy<T> order() {
return orderBy();
}
@@ -508,6 +508,8 @@ public interface ExpressionList<T> {
ExpressionList<T> filterMany(String manyProperty);
/**
* Deprecated for removal - migrate to filterManyRaw()
* <p>
* Add filter expressions to the many property.
*
* <pre>{@code
@@ -524,8 +526,29 @@ public interface ExpressionList<T> {
* @param expressions Filter expressions with and, or and ? or ?1 type bind parameters
* @param params Bind parameters used in the expressions
*/
@Deprecated(forRemoval = true)
ExpressionList<T> filterMany(String manyProperty, String expressions, Object... params);
/**
* Add filter expressions for the many path. The expressions can include SQL functions if
* desired and the property names are translated to column names.
* <p>
* The expressions can contain placeholders for bind values using <code>?</code> or <code>?1</code> style.
*
* <pre>{@code
*
* new QCustomer()
* .name.startsWith("Postgres")
* .contacts.filterManyRaw("status = ? and firstName like ?", Contact.Status.NEW, "Rob%")
* .findList();
*
* }</pre>
*
* @param rawExpressions The raw expressions which can include ? and ?1 style bind parameter placeholders
* @param params The parameter values to bind
*/
ExpressionList<T> filterManyRaw(String manyProperty, String rawExpressions, Object... params);
/**
* Specify specific properties to fetch on the main/root bean (aka partial
* object).
+4 -1
View File
@@ -1,6 +1,7 @@
package io.ebean;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@@ -24,7 +25,9 @@ public final class Lists {
*/
public static <T> List<List<T>> partition(List<T> source, int max) {
final int totalCount = source.size();
if (totalCount <= max) {
if (totalCount == 0) {
return Collections.emptyList();
} else if (totalCount <= max) {
return List.of(source);
}
final int numOfPartitions = (totalCount + max - 1) / max; // round up
@@ -333,10 +333,10 @@ public class OrderBy<T> implements Serializable {
sb.append(property);
}
if (!ascending) {
sb.append(" ").append("desc");
sb.append(' ').append("desc");
}
if (nulls != null) {
sb.append(" ").append(nulls).append(" ").append(highLow);
sb.append(' ').append(nulls).append(' ').append(highLow);
}
return sb.toString();
}
+3 -3
View File
@@ -1398,7 +1398,7 @@ public interface Query<T> extends CancelableQuery {
/**
* Deprecated migrate to orderBy().
*/
@Deprecated(since = "13.19")
@Deprecated(since = "13.19", forRemoval = true)
default Query<T> order(String orderByClause) {
return orderBy(orderByClause);
}
@@ -1417,7 +1417,7 @@ public interface Query<T> extends CancelableQuery {
/**
* Deprecated migrate to orderBy().
*/
@Deprecated(since = "13.19")
@Deprecated(since = "13.19", forRemoval = true)
default OrderBy<T> order() {
return orderBy();
}
@@ -1430,7 +1430,7 @@ public interface Query<T> extends CancelableQuery {
/**
* Deprecated migrate to setOrderBy().
*/
@Deprecated(since = "13.19")
@Deprecated(since = "13.19", forRemoval = true)
default Query<T> setOrder(OrderBy<T> orderBy) {
return setOrderBy(orderBy);
}
@@ -77,9 +77,9 @@ public final class StdOperators {
StringBuilder expression = new StringBuilder(50);
expression.append("concat(").append(property.toString());
for (Object value : values) {
expression.append(",").append(sqlConcatString(value));
expression.append(',').append(sqlConcatString(value));
}
expression.append(")");
expression.append(')');
return Property.of(expression.toString());
}
@@ -45,7 +45,7 @@ public final class ToStringBuilder {
id.putIfAbsent(bean, 0);
}
if (counter <= MAX) {
sb.append(bean.getClass().getSimpleName()).append("@").append(counter).append("(");
sb.append(bean.getClass().getSimpleName()).append('@').append(counter).append('(');
}
}
@@ -77,7 +77,7 @@ public final class ToStringBuilder {
*/
public void end() {
if (counter <= MAX) {
sb.append(")");
sb.append(')');
}
}
@@ -90,7 +90,7 @@ public final class ToStringBuilder {
} else {
sb.append(", ");
}
sb.append(name).append(":");
sb.append(name).append(':');
}
private void value(Object value) {
@@ -125,20 +125,20 @@ public final class ToStringBuilder {
sb.append("{}");
} else {
boolean firstElement = true;
sb.append("{");
sb.append('{');
for (Map.Entry<?, ?> entry : map.entrySet()) {
if (firstElement) {
firstElement = false;
} else {
sb.append(", ");
}
sb.append(entry.getKey()).append(":");
sb.append(entry.getKey()).append(':');
value(entry.getValue());
if (counter > MAX) {
return;
}
}
sb.append("}");
sb.append('}');
}
}
@@ -151,7 +151,7 @@ public final class ToStringBuilder {
return;
}
boolean firstElement = true;
sb.append("[");
sb.append('[');
for (Object o : c) {
if (firstElement) {
firstElement = false;
@@ -163,7 +163,7 @@ public final class ToStringBuilder {
return;
}
}
sb.append("]");
sb.append(']');
}
private boolean push(Object bean) {
@@ -178,7 +178,7 @@ public final class ToStringBuilder {
Integer idx = id.putIfAbsent(bean, counter++);
if (idx != null) {
--counter;
sb.append(bean.getClass().getSimpleName()).append("@").append(idx);
sb.append(bean.getClass().getSimpleName()).append('@').append(idx);
return false;
}
first = true;
+1 -1
View File
@@ -69,7 +69,7 @@ public class TenantAwareKey {
public String toString() {
StringBuilder sb = new StringBuilder(key.toString());
if (tenantId != null) {
sb.append(":").append(tenantId);
sb.append(':').append(tenantId);
}
return sb.toString();
}
@@ -119,7 +119,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
try {
if (set == null) {
if (!disableLazyLoad && modifyListening) {
lazyLoadCollection(true);
lazyLoadCollection(false);
} else {
set = new LinkedHashSet<>();
}
@@ -136,7 +136,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
if (disableLazyLoad) {
set = new LinkedHashSet<>();
} else {
lazyLoadCollection(true);
lazyLoadCollection(false);
}
}
} finally {
@@ -228,7 +228,7 @@ public abstract class AbstractNamingConvention implements NamingConvention {
public TableName getM2MJoinTableName(TableName lhsTable, TableName rhsTable) {
StringBuilder buffer = new StringBuilder();
buffer.append(unQuote(lhsTable.getName()));
buffer.append("_");
buffer.append('_');
String rhsTableName = unQuote(rhsTable.getName());
if (rhsTableName.indexOf('_') < rhsPrefixLength) {
@@ -271,10 +271,10 @@ public abstract class AbstractNamingConvention implements NamingConvention {
public String getTableName(String catalog, String schema, String name) {
StringBuilder sb = new StringBuilder();
if (!isNull(catalog)) {
sb.append(quoteIdentifiers(catalog)).append(".");
sb.append(quoteIdentifiers(catalog)).append('.');
}
if (!isNull(schema)) {
sb.append(quoteIdentifiers(schema)).append(".");
sb.append(quoteIdentifiers(schema)).append('.');
}
return sb.append(quoteIdentifiers(name)).toString();
}
@@ -2376,7 +2376,7 @@ public class DatabaseConfig {
* Sorry if returning Set rather than List breaks code but it feels safer to
* do that than a subtle change to return a shallow copy which you will not detect.
*/
@Deprecated
@Deprecated(forRemoval = true)
public Set<Class<?>> getClasses() {
return classes;
}
@@ -3389,7 +3389,7 @@ public class DatabaseConfig {
/**
* Deprecated - migrate to isLoadModuleInfo().
*/
@Deprecated
@Deprecated(forRemoval = true)
public boolean isAutoLoadModuleInfo() {
return loadModuleInfo;
}
@@ -140,7 +140,7 @@ public class DbConstraintNaming {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
sb.append("_");
sb.append('_');
}
sb.append(normaliseColumn(columns[i]));
}
@@ -117,12 +117,12 @@ public final class TableName {
// Add schema
if (schema != null) {
if (buffer.length() > 0) {
buffer.append(".");
buffer.append('.');
}
buffer.append(schema);
}
if (buffer.length() > 0) {
buffer.append(".");
buffer.append('.');
}
return buffer.append(name).toString();
}
@@ -23,11 +23,11 @@ public class BasicSqlLimitOffset implements BasicSqlLimiter {
sb.append(dbSql);
if (maxRows > 0) {
sb.append(" ").append(LIMIT);
sb.append(" ").append(maxRows);
sb.append(' ').append(LIMIT);
sb.append(' ').append(maxRows);
}
if (firstRow > 0) {
sb.append(" ").append(OFFSET).append(" ");
sb.append(' ').append(OFFSET).append(' ');
sb.append(firstRow);
}
return sb.toString();
@@ -118,28 +118,28 @@ final class MetricsAsJson implements ServerMetricsAsJson {
private void objStart() throws IOException {
objKeyCounter = 0;
writer.append("{");
writer.append('{');
}
private void objEnd() throws IOException {
writer.append("}");
writer.append('}');
}
private void listStart() throws IOException {
listCounter = 0;
writer.append("[");
writer.append('[');
writer.append(newLine);
}
private void listEnd() throws IOException {
writer.append("]");
writer.append(']');
}
private void key(String key) throws IOException {
if (objKeyCounter++ > 0) {
writer.append(", ");
}
writer.append("\"").append(key).append("\":");
writer.append('"').append(key).append("\":");
}
private void val(long count) throws IOException {
@@ -147,12 +147,12 @@ final class MetricsAsJson implements ServerMetricsAsJson {
}
private void val(String val) throws IOException {
writer.append("\"").append(val).append("\"");
writer.append('"').append(val).append('"');
}
private void metricStart(MetaMetric metric) throws IOException {
if (listCounter++ > 0) {
writer.append(",").append(newLine);
writer.append(',').append(newLine);
}
objStart();
key("name");
@@ -205,7 +205,7 @@ public class PathProperties implements FetchPath {
sb.append(it.next());
hasNext = it.hasNext();
if (hasNext) {
sb.append(",");
sb.append(',');
}
}
return sb.toString();
@@ -25,14 +25,14 @@ public final class CamelCaseHelper {
lastUpper = i;
} else if (Character.isDigit(c)) {
if (i > lastUpper + 1 && !digitsCompressed) {
sb.append("_");
sb.append('_');
lastUpper = i;
}
sb.append(c);
} else if (Character.isUpperCase(c)) {
if (i > lastUpper + 1) {
sb.append("_");
sb.append('_');
}
sb.append(Character.toLowerCase(c));
lastUpper = i;
@@ -11,8 +11,7 @@ class ListsTest {
@Test
void partition_empty() {
List<List<Integer>> partitions = Lists.partition(List.of(), 5);
assertThat(partitions).hasSize(1);
assertThat(partitions.get(0)).hasSize(0);
assertThat(partitions).isEmpty();
}
@Test
+25 -25
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
</parent>
<name>ebean bom</name>
@@ -89,25 +89,25 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -125,13 +125,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -155,46 +155,46 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>kotlin-querybean-generator</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-redis</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-spring-txn</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<!-- platforms -->
@@ -202,67 +202,67 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-clickhouse</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-db2</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-h2</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-hana</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mariadb</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mysql</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-nuodb</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-oracle</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgres</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlite</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlserver</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
</parent>
<artifactId>ebean-core-type</artifactId>
@@ -16,7 +16,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
+6 -6
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.21.0</version>
<version>13.22.0</version>
</parent>
<artifactId>ebean-core</artifactId>
@@ -22,7 +22,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -46,7 +46,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
</dependency>
<dependency>
@@ -159,21 +159,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.21.0</version>
<version>13.22.0</version>
<scope>test</scope>
</dependency>
@@ -73,13 +73,13 @@ public final class BindParams implements Serializable {
for (Param param : positionedParameters) {
tempBindCount = param.queryBindCount();
bc += tempBindCount;
builder.append("p").append(bc).append(" ?:").append(tempBindCount).append(",");
builder.append('p').append(bc).append(" ?:").append(tempBindCount).append(',');
}
for (Map.Entry<String, Param> entry : namedParameters.entrySet()) {
tempBindCount = entry.getValue().queryBindCount();
bc += tempBindCount;
builder.append("n").append(bc).append(" k:").append(entry.getKey()).append(" ?:").append(tempBindCount).append(",");
builder.append('n').append(bc).append(" k:").append(entry.getKey()).append(" ?:").append(tempBindCount).append(',');
}
}
@@ -5,11 +5,6 @@ package io.ebeaninternal.api;
*/
public interface CQueryPlanKey {
/**
* Return true if the query plan should be cached.
*/
boolean useCache();
/**
* Used by read audit such that we can log read audit entries without the full sql
* (which would make the read audit logs verbose).
@@ -111,7 +111,12 @@ public final class LoadManyRequest extends LoadRequest {
loadContext.configureQuery(query);
if (onlyIds) {
// lazy loading invoked via clear() and removeAll()
query.select(many.targetIdProperty());
String mapKey = many.mapKey();
if (mapKey != null) {
query.select(mapKey);
} else {
query.select(many.targetIdProperty());
}
}
return query;
}
@@ -61,9 +61,4 @@ public interface SpiDtoQuery<T> extends DtoQuery<T>, SpiSqlBinding {
*/
SpiQuery<?> ormQuery();
/**
* Return the explicit transaction used to execute the query.
*/
Transaction transaction();
}
@@ -66,6 +66,11 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
*/
CallOrigin createCallOrigin();
/**
* Override in order to return SpiQuery
*/
<T> SpiQuery<T> createQuery(Class<T> beanType);
/**
* Return the PersistenceContextScope to use defined at query or server level.
*/
@@ -148,7 +153,7 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
/**
* Compile a query.
*/
<T> CQuery<T> compileQuery(Type type, Query<T> query, Transaction transaction);
<T> CQuery<T> compileQuery(Type type, SpiQuery<T> query, Transaction transaction);
/**
* Execute the findId's query but without copying the query.
@@ -157,12 +162,12 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
* the query has finished (if executing in a background thread).
* </p>
*/
<A, T> List<A> findIdsWithCopy(Query<T> query, Transaction transaction);
<A, T> List<A> findIdsWithCopy(SpiQuery<T> query);
/**
* Execute the findCount query but without copying the query.
*/
<T> int findCountWithCopy(Query<T> query, Transaction transaction);
<T> int findCountWithCopy(SpiQuery<T> query);
/**
* Load a batch of Associated One Beans.
@@ -290,7 +295,7 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
/**
* Execute the underlying ORM query returning as a JDBC ResultSet to map to DTO beans.
*/
SpiResultSet findResultSet(SpiQuery<?> ormQuery, SpiTransaction transaction);
SpiResultSet findResultSet(SpiQuery<?> ormQuery);
/**
* Visit all the metrics (typically reporting them).
@@ -322,136 +327,57 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
*/
SpiQueryBindCapture createQueryBindCapture(SpiQueryPlan queryPlan);
<T> boolean exists(SpiQuery<T> ormQuery);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> boolean exists(Query<T> ormQuery, Transaction transaction);
<T> int findCount(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> int findCount(Query<T> query, Transaction transaction);
<A, T> List<A> findIds(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<A, T> List<A> findIds(Query<T> query, Transaction transaction);
<T> QueryIterator<T> findIterate(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction);
<T> Stream<T> findStream(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> Stream<T> findStream(Query<T> query, Transaction transaction);
<T> void findEach(SpiQuery<T> query, Consumer<T> consumer);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> void findEach(Query<T> query, Consumer<T> consumer, Transaction transaction);
<T> void findEach(SpiQuery<T> query, int batch, Consumer<List<T>> consumer);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> void findEach(Query<T> query, int batch, Consumer<List<T>> consumer, Transaction t);
<T> void findEachWhile(SpiQuery<T> query, Predicate<T> consumer);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> void findEachWhile(Query<T> query, Predicate<T> consumer, Transaction transaction);
<T> List<Version<T>> findVersions(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> List<Version<T>> findVersions(Query<T> query, Transaction transaction);
<T> List<T> findList(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> List<T> findList(Query<T> query, Transaction transaction);
<T> FutureRowCount<T> findFutureCount(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> FutureRowCount<T> findFutureCount(Query<T> query, Transaction transaction);
<T> FutureIds<T> findFutureIds(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> FutureIds<T> findFutureIds(Query<T> query, Transaction transaction);
<T> FutureList<T> findFutureList(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> FutureList<T> findFutureList(Query<T> query, Transaction transaction);
<T> PagedList<T> findPagedList(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> PagedList<T> findPagedList(Query<T> query, Transaction transaction);
<T> Set<T> findSet(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> Set<T> findSet(Query<T> query, Transaction transaction);
<K, T> Map<K, T> findMap(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<K, T> Map<K, T> findMap(Query<T> query, Transaction transaction);
<A, T> List<A> findSingleAttributeList(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<A, T> List<A> findSingleAttributeList(Query<T> query, Transaction transaction);
<A, T> Set<A> findSingleAttributeSet(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<A, T> Set<A> findSingleAttributeSet(Query<T> query, Transaction transaction);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
@Nullable
<T> T findOne(Query<T> query, Transaction transaction);
<T> T findOne(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> Optional<T> findOneOrEmpty(Query<T> query, Transaction transaction);
<T> Optional<T> findOneOrEmpty(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> int delete(Query<T> query, Transaction transaction);
<T> int delete(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
<T> int update(Query<T> query, Transaction transaction);
<T> int update(SpiQuery<T> query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
List<SqlRow> findList(SqlQuery query, Transaction transaction);
List<SqlRow> findList(SpiSqlQuery query);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
void findEach(SqlQuery query, Consumer<SqlRow> consumer, Transaction transaction);
void findEach(SpiSqlQuery query, Consumer<SqlRow> consumer);
/**
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
*/
void findEachWhile(SqlQuery query, Predicate<SqlRow> consumer, Transaction transaction);
void findEachWhile(SpiSqlQuery query, Predicate<SqlRow> consumer);
/**
* Deprecated migrate to using {@link SqlQuery#usingTransaction(Transaction)}.
*/
@Nullable
SqlRow findOne(SqlQuery query, Transaction transaction);
SqlRow findOne(SpiSqlQuery query);
}
@@ -32,14 +32,14 @@ public interface SpiExpressionRequest {
SpiOrmQueryRequest<?> queryRequest();
/**
* Return the underling buffer.
* Append to the expression sql without any parsing.
*/
StringBuilder buffer();
SpiExpressionRequest append(String expression);
/**
* Append to the expression sql without any parsing.
*/
SpiExpressionRequest append(String expression);
SpiExpressionRequest append(char c);
/**
* Append to the expression sql with logical property parsing to db columns with logical path prefix.
@@ -235,6 +235,11 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
*/
String planLabel();
/**
* Return the transaction explicitly assigned or null.
*/
SpiTransaction transaction();
/**
* Return true if this query should not use the read only data source.
*/
@@ -872,17 +877,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
*/
boolean isDisableReadAudit();
/**
* Return true if this is a query executing in the background.
*/
boolean isFutureFetch();
/**
* Set to true to indicate the query is executing in a background thread
* asynchronously.
*/
void setFutureFetch(boolean futureFetch);
/**
* Set the readEvent for future queries (as prepared in foreground thread).
*/
@@ -1,10 +1,18 @@
package io.ebeaninternal.api;
import io.avaje.lang.Nullable;
/**
* SQL query binding (for SqlQuery and DtoQuery).
*/
public interface SpiSqlBinding extends SpiCancelableQuery {
/**
* Return the transaction explicitly associated to the query.
*/
@Nullable
SpiTransaction transaction();
/**
* Return true if this query should not use the read only data source.
*/
@@ -1,17 +1,10 @@
package io.ebeaninternal.api;
import io.avaje.lang.Nullable;
import io.ebean.SqlQuery;
import io.ebean.Transaction;
/**
* SQL query - Internal extension to SqlQuery.
*/
public interface SpiSqlQuery extends SqlQuery, SpiSqlBinding {
/**
* Return the transaction explicitly associated to the query.
*/
@Nullable
Transaction transaction();
}
@@ -33,10 +33,10 @@ public abstract class AbstractSqlQueryRequest implements CancelableQuery {
/**
* Create the BeanFindRequest.
*/
AbstractSqlQueryRequest(SpiEbeanServer server, SpiSqlBinding query, Transaction t) {
AbstractSqlQueryRequest(SpiEbeanServer server, SpiSqlBinding query) {
this.server = server;
this.query = query;
this.transaction = (SpiTransaction) t;
this.transaction = query.transaction();
this.query.setCancelableQuery(this);
}
@@ -48,7 +48,7 @@ public abstract class BeanRequest {
*/
public void commitTransIfRequired() {
if (createdTransaction) {
server.commitTransaction();
transaction.commit();
}
}
@@ -106,7 +106,7 @@ final class DefaultBeanLoader {
query.setReadOnly(true);
}
server.findOne(query, null);
server.findOne(query);
if (beanCollection != null) {
if (beanCollection.checkEmptyLazyLoad()) {
if (log.isLoggable(DEBUG)) {
@@ -127,6 +127,7 @@ final class DefaultBeanLoader {
throw new RuntimeException("Nothing in batch?");
}
final SpiQuery<?> query = server.createQuery(loadRequest.beanType());
query.usingTransaction(loadRequest.transaction());
loadRequest.configureQuery(query);
loadRequest.postLoad(executeQuery(loadRequest, query));
}
@@ -139,12 +140,13 @@ final class DefaultBeanLoader {
// MySql - we need a different transaction to execute the secondary query
SpiTransaction extraTxn = server.createReadOnlyTransaction(query.tenantId(), query.isUseMaster());
try {
return server.findList(query, extraTxn);
query.usingTransaction(extraTxn);
return server.findList(query);
} finally {
extraTxn.end();
}
} else {
return server.findList(query, loadRequest.transaction());
return server.findList(query);
}
}
@@ -440,8 +440,9 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
* Compile a query. Only valid for ORM queries.
*/
@Override
public <T> CQuery<T> compileQuery(Type type, Query<T> query, Transaction transaction) {
SpiOrmQueryRequest<T> qr = createQueryRequest(type, query, transaction);
public <T> CQuery<T> compileQuery(Type type, SpiQuery<T> query, Transaction transaction) {
query.usingTransaction(transaction);
SpiOrmQueryRequest<T> qr = createQueryRequest(type, query);
OrmQueryRequest<T> orm = (OrmQueryRequest<T>) qr;
return cqueryEngine.buildQuery(orm);
}
@@ -903,8 +904,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public SpiResultSet findResultSet(SpiQuery<?> ormQuery, SpiTransaction transaction) {
SpiOrmQueryRequest<?> request = createQueryRequest(ormQuery.type(), ormQuery, transaction);
public SpiResultSet findResultSet(SpiQuery<?> ormQuery) {
SpiOrmQueryRequest<?> request = createQueryRequest(ormQuery.type(), ormQuery);
request.initTransIfRequired();
return request.findResultSet();
}
@@ -935,24 +936,26 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
public <T> T find(Class<T> beanType, Object id, @Nullable Transaction transaction) {
Objects.requireNonNull(id);
Query<T> query = createQuery(beanType).setId(id);
return findId(query, transaction);
SpiQuery<T> query = createQuery(beanType);
query.usingTransaction(transaction);
query.setId(id);
return findId(query);
}
<T> SpiOrmQueryRequest<T> createQueryRequest(Type type, Query<T> query, @Nullable Transaction transaction) {
SpiOrmQueryRequest<T> request = buildQueryRequest(type, query, transaction);
<T> SpiOrmQueryRequest<T> createQueryRequest(Type type, SpiQuery<T> query) {
SpiOrmQueryRequest<T> request = buildQueryRequest(type, query);
request.prepareQuery();
return request;
}
<T> SpiOrmQueryRequest<T> buildQueryRequest(Type type, Query<T> query, @Nullable Transaction transaction) {
SpiQuery<T> spiQuery = (SpiQuery<T>) query;
spiQuery.setType(type);
spiQuery.checkNamedParameters();
return buildQueryRequest(spiQuery, transaction);
<T> SpiOrmQueryRequest<T> buildQueryRequest(Type type, SpiQuery<T> query) {
query.setType(type);
query.checkNamedParameters();
return buildQueryRequest(query);
}
private <T> SpiOrmQueryRequest<T> buildQueryRequest(SpiQuery<T> query, @Nullable Transaction transaction) {
private <T> SpiOrmQueryRequest<T> buildQueryRequest(SpiQuery<T> query) {
SpiTransaction transaction = query.transaction();
if (transaction == null) {
transaction = currentServerTransaction();
}
@@ -973,7 +976,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
if (query.parentNode() == null) {
query.setOrigin(createCallOrigin());
}
return new OrmQueryRequest<>(this, queryEngine, query, (SpiTransaction) transaction);
return new OrmQueryRequest<>(this, queryEngine, query, transaction);
}
/**
@@ -981,8 +984,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
*/
@Nullable
@SuppressWarnings("unchecked")
private <T> T findIdCheckPersistenceContextAndCache(@Nullable Transaction transaction, SpiQuery<T> query, Object id) {
SpiTransaction t = (SpiTransaction) transaction;
private <T> T findIdCheckPersistenceContextAndCache(SpiQuery<T> query, Object id) {
SpiTransaction t = query.transaction();
if (t == null) {
t = currentServerTransaction();
}
@@ -1028,18 +1031,17 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Nullable
@SuppressWarnings("unchecked")
private <T> T findId(Query<T> query, @Nullable Transaction transaction) {
SpiQuery<T> spiQuery = (SpiQuery<T>) query;
spiQuery.setType(Type.BEAN);
if (SpiQuery.Mode.NORMAL == spiQuery.mode() && !spiQuery.isForceHitDatabase()) {
private <T> T findId(SpiQuery<T> query) {
query.setType(Type.BEAN);
if (SpiQuery.Mode.NORMAL == query.mode() && !query.isForceHitDatabase()) {
// See if we can skip doing the fetch completely by getting the bean from the
// persistence context or the bean cache
T bean = findIdCheckPersistenceContextAndCache(transaction, spiQuery, spiQuery.getId());
T bean = findIdCheckPersistenceContextAndCache(query, query.getId());
if (bean != null) {
return bean;
}
}
SpiOrmQueryRequest<T> request = buildQueryRequest(spiQuery, transaction);
SpiOrmQueryRequest<T> request = buildQueryRequest(query);
request.prepareQuery();
if (request.isUseDocStore()) {
return docStore().find(request);
@@ -1053,23 +1055,19 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public <T> Optional<T> findOneOrEmpty(Query<T> query, Transaction transaction) {
return Optional.ofNullable(findOne(query, transaction));
public <T> Optional<T> findOneOrEmpty(SpiQuery<T> query) {
return Optional.ofNullable(findOne(query));
}
@Nullable
@Override
public <T> T findOne(Query<T> query, @Nullable Transaction transaction) {
SpiQuery<T> spiQuery = (SpiQuery<T>) query;
if (spiQuery.isFindById()) {
public <T> T findOne(SpiQuery<T> query) {
if (query.isFindById()) {
// actually a find by Id query
return findId(query, transaction);
}
if (transaction == null) {
transaction = currentServerTransaction();
return findId(query);
}
// a query that is expected to return either 0 or 1 beans
List<T> list = findList(query, transaction, true);
List<T> list = findList(query, true);
return extractUnique(list);
}
@@ -1086,10 +1084,10 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public <T> Set<T> findSet(Query<T> query, Transaction transaction) {
SpiOrmQueryRequest request = buildQueryRequest(Type.SET, query, transaction);
public <T> Set<T> findSet(SpiQuery<T> query) {
SpiOrmQueryRequest request = buildQueryRequest(Type.SET, query);
request.resetBeanCacheAutoMode(false);
if ((transaction == null || !transaction.isSkipCache()) && request.getFromBeanCache()) {
if (request.isGetAllFromBeanCache()) {
// hit bean cache and got all results from cache
return request.beanCacheHitsAsSet();
}
@@ -1108,10 +1106,10 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public <K, T> Map<K, T> findMap(Query<T> query, @Nullable Transaction transaction) {
SpiOrmQueryRequest request = buildQueryRequest(Type.MAP, query, transaction);
public <K, T> Map<K, T> findMap(SpiQuery<T> query) {
SpiOrmQueryRequest request = buildQueryRequest(Type.MAP, query);
request.resetBeanCacheAutoMode(false);
if ((transaction == null || !transaction.isSkipCache()) && request.getFromBeanCache()) {
if (request.isGetAllFromBeanCache()) {
// hit bean cache and got all results from cache
return request.beanCacheHitsAsMap();
}
@@ -1130,8 +1128,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
@SuppressWarnings("unchecked")
public <A, T> List<A> findSingleAttributeList(Query<T> query, Transaction transaction) {
SpiOrmQueryRequest<T> request = buildQueryRequest(Type.ATTRIBUTE, query, transaction);
public <A, T> List<A> findSingleAttributeList(SpiQuery<T> query) {
SpiOrmQueryRequest<T> request = buildQueryRequest(Type.ATTRIBUTE, query);
request.query().setSingleAttribute();
request.prepareQuery();
Object result = request.getFromQueryCache();
@@ -1148,8 +1146,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
@SuppressWarnings("unchecked")
public <A, T> Set<A> findSingleAttributeSet(Query<T> query, Transaction transaction) {
SpiOrmQueryRequest<T> request = buildQueryRequest(Type.ATTRIBUTE_SET, query, transaction);
public <A, T> Set<A> findSingleAttributeSet(SpiQuery<T> query) {
SpiOrmQueryRequest<T> request = buildQueryRequest(Type.ATTRIBUTE_SET, query);
request.query().setSingleAttribute();
request.prepareQuery();
Object result = request.getFromQueryCache();
@@ -1165,17 +1163,16 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public <T> int findCount(Query<T> query, @Nullable Transaction transaction) {
SpiQuery<T> spiQuery = ((SpiQuery<T>) query);
if (!spiQuery.isDistinct()) {
spiQuery = spiQuery.copy();
public <T> int findCount(SpiQuery<T> query) {
if (!query.isDistinct()) {
query = query.copy();
}
return findCountWithCopy(spiQuery, transaction);
return findCountWithCopy(query);
}
@Override
public <T> int findCountWithCopy(Query<T> query, @Nullable Transaction transaction) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.COUNT, query, transaction);
public <T> int findCountWithCopy(SpiQuery<T> query) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.COUNT, query);
Integer result = request.getFromQueryCache();
if (result != null) {
return result;
@@ -1190,13 +1187,17 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
public boolean exists(Class<?> beanType, Object beanId, Transaction transaction) {
return !findIdsWithCopy(find(beanType).setId(beanId), transaction).isEmpty();
final DefaultOrmQuery<?> query = createQuery(beanType);
query.usingTransaction(transaction);
query.setId(beanId);
return !findIdsWithCopy(query).isEmpty();
}
@Override
public <T> boolean exists(Query<T> ormQuery, Transaction transaction) {
Query<T> ormQueryCopy = ormQuery.copy().setMaxRows(1);
SpiOrmQueryRequest<?> request = createQueryRequest(Type.EXISTS, ormQueryCopy, transaction);
public <T> boolean exists(SpiQuery<T> ormQuery) {
SpiQuery<T> ormQueryCopy = ormQuery.copy();
ormQueryCopy.setMaxRows(1);
SpiOrmQueryRequest<?> request = createQueryRequest(Type.EXISTS, ormQueryCopy);
List<Object> ids = request.getFromQueryCache();
if (ids != null) {
return !ids.isEmpty();
@@ -1210,14 +1211,14 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public <A, T> List<A> findIds(Query<T> query, Transaction transaction) {
return findIdsWithCopy(((SpiQuery<T>) query).copy(), transaction);
public <A, T> List<A> findIds(SpiQuery<T> query) {
return findIdsWithCopy(query.copy());
}
@SuppressWarnings("unchecked")
@Override
public <A, T> List<A> findIdsWithCopy(Query<T> query, Transaction transaction) {
SpiOrmQueryRequest<?> request = createQueryRequest(Type.ID_LIST, query, transaction);
public <A, T> List<A> findIdsWithCopy(SpiQuery<T> query) {
SpiOrmQueryRequest<?> request = createQueryRequest(Type.ID_LIST, query);
Object result = request.getFromQueryCache();
if (result != null) {
if (Boolean.FALSE.equals(request.query().isReadOnly())) {
@@ -1235,8 +1236,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public <T> int delete(Query<T> query, Transaction transaction) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.DELETE, query, transaction);
public <T> int delete(SpiQuery<T> query) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.DELETE, query);
try {
request.initTransIfRequired();
request.markNotQueryOnly();
@@ -1258,8 +1259,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public <T> int update(Query<T> query, Transaction transaction) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.UPDATE, query, transaction);
public <T> int update(SpiQuery<T> query) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.UPDATE, query);
try {
request.initTransIfRequired();
request.markNotQueryOnly();
@@ -1270,29 +1271,44 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public <T> FutureRowCount<T> findFutureCount(Query<T> query, Transaction transaction) {
SpiQuery<T> copy = ((SpiQuery<T>) query).copy();
copy.setFutureFetch(true);
Transaction newTxn = createTransaction();
QueryFutureRowCount<T> queryFuture = new QueryFutureRowCount<>(new CallableQueryCount<>(this, copy, newTxn));
public <T> FutureRowCount<T> findFutureCount(SpiQuery<T> query) {
SpiQuery<T> copy = query.copy();
boolean createdTransaction = false;
SpiTransaction transaction = query.transaction();
if (transaction == null) {
transaction = currentServerTransaction();
if (transaction == null) {
transaction = (SpiTransaction) createTransaction();
createdTransaction = true;
}
copy.usingTransaction(transaction);
}
var queryFuture = new QueryFutureRowCount<>(new CallableQueryCount<>(this, copy, createdTransaction));
backgroundExecutor.execute(queryFuture.futureTask());
return queryFuture;
}
@Override
public <T> FutureIds<T> findFutureIds(Query<T> query, Transaction transaction) {
SpiQuery<T> copy = ((SpiQuery<T>) query).copy();
copy.setFutureFetch(true);
Transaction newTxn = createTransaction();
QueryFutureIds<T> queryFuture = new QueryFutureIds<>(new CallableQueryIds<>(this, copy, newTxn));
public <T> FutureIds<T> findFutureIds(SpiQuery<T> query) {
SpiQuery<T> copy = query.copy();
boolean createdTransaction = false;
SpiTransaction transaction = query.transaction();
if (transaction == null) {
transaction = currentServerTransaction();
if (transaction == null) {
transaction = (SpiTransaction) createTransaction();
createdTransaction = true;
}
copy.usingTransaction(transaction);
}
QueryFutureIds<T> queryFuture = new QueryFutureIds<>(new CallableQueryIds<>(this, copy, createdTransaction));
backgroundExecutor.execute(queryFuture.futureTask());
return queryFuture;
}
@Override
public <T> FutureList<T> findFutureList(Query<T> query, Transaction transaction) {
SpiQuery<T> spiQuery = (SpiQuery<T>) query.copy();
spiQuery.setFutureFetch(true);
public <T> FutureList<T> findFutureList(SpiQuery<T> query) {
SpiQuery<T> spiQuery = query.copy();
// FutureList query always run in it's own persistence content
spiQuery.setPersistenceContext(new DefaultPersistenceContext());
if (!spiQuery.isDisableReadAudit()) {
@@ -1300,28 +1316,36 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
desc.readAuditFutureList(spiQuery);
}
// Create a new transaction solely to execute the findList() at some future time
Transaction newTxn = createTransaction();
QueryFutureList<T> queryFuture = new QueryFutureList<>(new CallableQueryList<>(this, spiQuery, newTxn));
boolean createdTransaction = false;
SpiTransaction transaction = query.transaction();
if (transaction == null) {
transaction = currentServerTransaction();
if (transaction == null) {
transaction = (SpiTransaction) createTransaction();
createdTransaction = true;
}
spiQuery.usingTransaction(transaction);
}
QueryFutureList<T> queryFuture = new QueryFutureList<>(new CallableQueryList<>(this, spiQuery, createdTransaction));
backgroundExecutor.execute(queryFuture.futureTask());
return queryFuture;
}
@Override
public <T> PagedList<T> findPagedList(Query<T> query, Transaction transaction) {
SpiQuery<T> spiQuery = (SpiQuery<T>) query;
int maxRows = spiQuery.getMaxRows();
public <T> PagedList<T> findPagedList(SpiQuery<T> query) {
int maxRows = query.getMaxRows();
if (maxRows == 0) {
throw new PersistenceException("maxRows must be specified for findPagedList() query");
}
if (spiQuery.isUseDocStore()) {
return docStore().findPagedList(createQueryRequest(Type.LIST, query, transaction));
if (query.isUseDocStore()) {
return docStore().findPagedList(createQueryRequest(Type.LIST, query));
}
return new LimitOffsetPagedList<>(this, spiQuery);
return new LimitOffsetPagedList<>(this, query);
}
@Override
public <T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query, transaction);
public <T> QueryIterator<T> findIterate(SpiQuery<T> query) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query);
try {
request.initTransIfRequired();
return request.findIterate();
@@ -1332,8 +1356,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public <T> Stream<T> findStream(Query<T> query, Transaction transaction) {
return toStream(findIterate(query, transaction));
public <T> Stream<T> findStream(SpiQuery<T> query) {
return toStream(findIterate(query));
}
private <T> Stream<T> toStream(QueryIterator<T> queryIterator) {
@@ -1341,8 +1365,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public <T> void findEach(Query<T> query, Consumer<T> consumer, Transaction transaction) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query, transaction);
public <T> void findEach(SpiQuery<T> query, Consumer<T> consumer) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query);
if (request.isUseDocStore()) {
docStore().findEach(request, consumer);
return;
@@ -1353,8 +1377,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public <T> void findEach(Query<T> query, int batch, Consumer<List<T>> consumer, Transaction transaction) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query, transaction);
public <T> void findEach(SpiQuery<T> query, int batch, Consumer<List<T>> consumer) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query);
// if (request.isUseDocStore()) {
// docStore().findEach(request, consumer);
// return;
@@ -1365,8 +1389,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public <T> void findEachWhile(Query<T> query, Predicate<T> consumer, Transaction transaction) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query, transaction);
public <T> void findEachWhile(SpiQuery<T> query, Predicate<T> consumer) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query);
if (request.isUseDocStore()) {
docStore().findEachWhile(request, consumer);
return;
@@ -1377,8 +1401,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public <T> List<Version<T>> findVersions(Query<T> query, @Nullable Transaction transaction) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.LIST, query, transaction);
public <T> List<Version<T>> findVersions(SpiQuery<T> query) {
SpiOrmQueryRequest<T> request = createQueryRequest(Type.LIST, query);
try {
request.initTransIfRequired();
return request.findVersions();
@@ -1388,15 +1412,15 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public <T> List<T> findList(Query<T> query, Transaction transaction) {
return findList(query, transaction, false);
public <T> List<T> findList(SpiQuery<T> query) {
return findList(query, false);
}
@SuppressWarnings("unchecked")
private <T> List<T> findList(Query<T> query, @Nullable Transaction transaction, boolean findOne) {
SpiOrmQueryRequest<T> request = buildQueryRequest(Type.LIST, query, transaction);
private <T> List<T> findList(SpiQuery<T> query, boolean findOne) {
SpiOrmQueryRequest<T> request = buildQueryRequest(Type.LIST, query);
request.resetBeanCacheAutoMode(findOne);
if ((transaction == null || !transaction.isSkipCache()) && request.getFromBeanCache()) {
if (request.isGetAllFromBeanCache()) {
// hit bean cache and got all results from cache
return request.beanCacheHits();
}
@@ -1418,16 +1442,16 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Nullable
@Override
public SqlRow findOne(SqlQuery query, Transaction transaction) {
public SqlRow findOne(SpiSqlQuery query) {
// no findId() method for SqlQuery...
// a query that is expected to return either 0 or 1 rows
List<SqlRow> list = findList(query, transaction);
List<SqlRow> list = findList(query);
return extractUnique(list);
}
@Override
public void findEach(SqlQuery query, Consumer<SqlRow> consumer, Transaction transaction) {
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query, transaction);
public void findEach(SpiSqlQuery query, Consumer<SqlRow> consumer) {
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query);
try {
request.initTransIfRequired();
request.findEach(consumer);
@@ -1437,8 +1461,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public void findEachWhile(SqlQuery query, Predicate<SqlRow> consumer, Transaction transaction) {
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query, transaction);
public void findEachWhile(SpiSqlQuery query, Predicate<SqlRow> consumer) {
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query);
try {
request.initTransIfRequired();
request.findEachWhile(consumer);
@@ -1448,8 +1472,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public List<SqlRow> findList(SqlQuery query, Transaction transaction) {
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query, transaction);
public List<SqlRow> findList(SpiSqlQuery query) {
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query);
try {
request.initTransIfRequired();
return request.findList();
@@ -1459,7 +1483,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
private <P> P executeSqlQuery(Function<RelationalQueryRequest, P> fun, SpiSqlQuery query) {
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query, query.transaction());
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query);
try {
request.initTransIfRequired();
return fun.apply(request);
@@ -2179,9 +2203,10 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
Object id = idProperty.getValue(entityBean);
if (entityBean._ebean_getIntercept().isNew() && id != null) {
// Primary Key is changeable only on new models - so skip check if we are not new
Query<?> query = new DefaultOrmQuery<>(beanDesc, this, expressionFactory);
SpiQuery<?> query = new DefaultOrmQuery<>(beanDesc, this, expressionFactory);
query.usingTransaction(transaction);
query.setId(id);
if (findCount(query, transaction) > 0) {
if (findCount(query) > 0) {
return Collections.singleton(idProperty);
}
}
@@ -2200,7 +2225,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Nullable
private Set<Property> checkUniqueness(EntityBean entityBean, BeanDescriptor<?> beanDesc, BeanProperty[] props, @Nullable Transaction transaction) {
BeanProperty idProperty = beanDesc.idProperty();
Query<?> query = new DefaultOrmQuery<>(beanDesc, this, expressionFactory);
SpiQuery<?> query = new DefaultOrmQuery<>(beanDesc, this, expressionFactory);
query.usingTransaction(transaction);
ExpressionList<?> exprList = query.where();
if (!entityBean._ebean_getIntercept().isNew()) {
// if model is not new, exclude ourself.
@@ -2213,7 +2239,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
exprList.eq(prop.name(), value);
}
if (findCount(query, transaction) > 0) {
if (findCount(query) > 0) {
Set<Property> ret = new LinkedHashSet<>();
Collections.addAll(ret, props);
return ret;
@@ -281,9 +281,9 @@ public final class DefaultSqlUpdate implements Serializable, SpiSqlUpdate {
int offset = 0;
for (Object val : values) {
if (offset > 0) {
sqlExpand.append(",");
sqlExpand.append(',');
}
sqlExpand.append("?");
sqlExpand.append('?');
bindParams.setParameter(position + offset++, val);
}
bindExpansion += (offset - 1);
@@ -33,7 +33,7 @@ public final class DtoQueryRequest<T> extends AbstractSqlQueryRequest {
private DataReader dataReader;
DtoQueryRequest(SpiEbeanServer server, DtoQueryEngine engine, SpiDtoQuery<T> query) {
super(server, query, query.transaction());
super(server, query);
this.queryEngine = engine;
this.query = query;
query.obtainLocation();
@@ -52,7 +52,8 @@ public final class DtoQueryRequest<T> extends AbstractSqlQueryRequest {
query.setCancelableQuery(ormQuery);
// execute the underlying ORM query returning the ResultSet
SpiResultSet result = server.findResultSet(ormQuery, transaction);
ormQuery.usingTransaction(transaction);
SpiResultSet result = server.findResultSet(ormQuery);
this.pstmt = result.statement();
this.sql = ormQuery.getGeneratedSql();
setResultSet(result.resultSet(), ormQuery.queryPlanKey());
@@ -121,7 +121,7 @@ final class DumpMetrics {
}
private void appendQueryName(MetaQueryMetric metric, StringBuilder sb) {
sb.append("query:").append(padName(metric.name())).append(" ");
sb.append("query:").append(padName(metric.name())).append(' ');
}
private void appendProfileAndSql(MetaQueryMetric metric, StringBuilder sb) {
@@ -136,7 +136,7 @@ final class DumpMetrics {
private void log(MetaTimedMetric metric) {
StringBuilder sb = new StringBuilder();
sb.append(padNameTimed(metric.name())).append(" ");
sb.append(padNameTimed(metric.name())).append(' ');
appendCounters(metric, sb);
out(sb.toString());
}
@@ -23,7 +23,7 @@ final class ObtainedTransactionImplicit extends ObtainedTransaction {
@Override
public void commitIfCreated() {
server.commitTransaction();
transaction.commit();
}
@Override
@@ -60,6 +60,11 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return queryEngine.translate(this, bindLog, sql, e);
}
@Override
public boolean isGetAllFromBeanCache() {
return (transaction == null || !transaction.isSkipCache()) && getFromBeanCache();
}
@Override
public boolean isDeleteByStatement() {
if (!transaction.isPersistCascade() || beanDescriptor.isDeleteByStatement()) {
@@ -2,7 +2,7 @@ package io.ebeaninternal.server.core;
import io.ebean.*;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiSqlBinding;
import io.ebeaninternal.api.SpiSqlQuery;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
@@ -22,8 +22,8 @@ public final class RelationalQueryRequest extends AbstractSqlQueryRequest {
private int estimateCapacity;
private int rows;
RelationalQueryRequest(SpiEbeanServer server, RelationalQueryEngine engine, SqlQuery q, Transaction t) {
super(server, (SpiSqlBinding) q, t);
RelationalQueryRequest(SpiEbeanServer server, RelationalQueryEngine engine, SpiSqlQuery q) {
super(server, q);
this.queryEngine = engine;
}
@@ -188,4 +188,8 @@ public interface SpiOrmQueryRequest<T> extends BeanQueryRequest<T>, DocQueryRequ
*/
boolean isDeleteByStatement();
/**
* Return true if hitting bean cache and returning all beans from cache.
*/
boolean isGetAllFromBeanCache();
}
@@ -1,12 +1,12 @@
package io.ebeaninternal.server.deploy;
import io.ebean.Query;
import io.ebean.Transaction;
import io.ebean.bean.BeanCollection;
import io.ebean.bean.BeanCollectionAdd;
import io.ebean.bean.BeanCollectionLoader;
import io.ebean.bean.EntityBean;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.api.json.SpiJsonWriter;
import io.ebeaninternal.server.query.CQueryCollectionAdd;
@@ -63,11 +63,6 @@ public interface BeanCollectionHelp<T> extends CQueryCollectionAdd<T> {
*/
BeanCollection<T> createReference(EntityBean parentBean);
/**
* Refresh the List Set or Map.
*/
void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean);
/**
* Apply the new refreshed BeanCollection to the appropriate property of the parent bean.
*/
@@ -1503,9 +1503,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
}
public void queryPlan(CQueryPlanKey key, CQueryPlan plan) {
if (key.useCache()) {
queryPlanCache.put(key, plan);
}
queryPlanCache.put(key, plan);
}
/**
@@ -552,7 +552,7 @@ final class BeanDescriptorCacheHelp<T> {
if (val == null) {
return null;
}
sb.append(val).append(";");
sb.append(val).append(';');
}
return sb.toString();
}
@@ -1,12 +1,12 @@
package io.ebeaninternal.server.deploy;
import io.ebean.Query;
import io.ebean.Transaction;
import io.ebean.bean.BeanCollection;
import io.ebean.bean.BeanCollectionAdd;
import io.ebean.bean.EntityBean;
import io.ebean.common.BeanList;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.api.json.SpiJsonWriter;
import java.io.IOException;
@@ -67,12 +67,6 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
return beanList;
}
@Override
public final void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
BeanList<?> newBeanList = (BeanList<?>) server.findList(query, t);
refresh(newBeanList, parentBean);
}
@Override
public final void refresh(BeanCollection<?> bc, EntityBean parentBean) {
BeanList<?> newBeanList = (BeanList<?>) bc;
@@ -1,12 +1,12 @@
package io.ebeaninternal.server.deploy;
import io.ebean.Query;
import io.ebean.Transaction;
import io.ebean.bean.BeanCollection;
import io.ebean.bean.BeanCollectionAdd;
import io.ebean.bean.EntityBean;
import io.ebean.common.BeanMap;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.api.json.SpiJsonWriter;
import java.io.IOException;
@@ -113,12 +113,6 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
return beanMap;
}
@Override
public final void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
BeanMap<?, ?> newBeanMap = (BeanMap<?, ?>) server.findMap(query, t);
refresh(newBeanMap, parentBean);
}
@Override
public final void refresh(BeanCollection<?> bc, EntityBean parentBean) {
BeanMap<?, ?> newBeanMap = (BeanMap<?, ?>) bc;
@@ -69,7 +69,7 @@ public final class BeanNaturalKey {
public String calculateKey(Map<String, Object> map) {
StringBuilder sb = new StringBuilder();
for (BeanProperty prop : props) {
sb.append(prop.naturalKeyVal(map)).append(";");
sb.append(prop.naturalKeyVal(map)).append(';');
}
return sb.toString();
}
@@ -1,6 +1,8 @@
package io.ebeaninternal.server.deploy;
import io.ebean.Query;
import io.ebean.SqlUpdate;
import io.ebean.Transaction;
import io.ebean.bean.EntityBean;
import io.ebean.core.type.DocPropertyType;
import io.ebean.text.PathProperties;
@@ -570,4 +572,26 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
+ " or a @JoinColumn needs an explicit referencedColumnName specified?";
throw new PersistenceException(msg);
}
/**
* Create SqlUpdate statement to delete all child beans of the parent <code>id</code>.
*/
public abstract SqlUpdate deleteByParentId(Object id);
/**
* Create SqlUpdate statement to delete all child beans of the parent ids in <code>idList</code>.
*/
public abstract SqlUpdate deleteByParentIdList(List<Object> idList);
/**
* Find child beans of the parent <code>id</code>.
*/
public abstract List<Object> findIdsByParentId(Object id, Transaction transaction, boolean includeSoftDeletes);
/**
* Find child beans of the parent ids in <code>idList</code>.
*/
public abstract List<Object> findIdsByParentIdList(List<Object> idList, Transaction transaction, boolean includeSoftDeletes);
}
@@ -296,23 +296,38 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
// do not add to the selectChain at the top level of the Many bean
}
public SpiSqlUpdate deleteByParentId(Object parentId, List<Object> parentIdist) {
if (parentId != null) {
return sqlHelp.deleteByParentId(parentId);
} else {
return sqlHelp.deleteByParentIdList(parentIdist);
}
@Override
public SpiSqlUpdate deleteByParentId(Object parentId) {
return sqlHelp.deleteByParentId(parentId);
}
@Override
public SpiSqlUpdate deleteByParentIdList(List<Object> parentIdist) {
return sqlHelp.deleteByParentIdList(parentIdist);
}
/**
* Find the Id's of detail beans given a parent Id
*/
@Override
public List<Object> findIdsByParentId(Object parentId, Transaction t, boolean includeSoftDeletes) {
return sqlHelp.findIdsByParentId(parentId, t, includeSoftDeletes, null);
}
/**
* Find the Id's of detail beans given a parent Id or list of parent Id's.
* Find the Id's of detail beans given a parent Id and optionally exclude detail IDs
*/
public List<Object> findIdsByParentId(Object parentId, List<Object> parentIdList, Transaction t, List<Object> excludeDetailIds, boolean hard) {
if (parentId != null) {
return sqlHelp.findIdsByParentId(parentId, t, excludeDetailIds, hard);
} else {
return sqlHelp.findIdsByParentIdList(parentIdList, t, excludeDetailIds, hard);
}
public List<Object> findIdsByParentId(Object parentId, Transaction t, boolean includeSoftDeletes, Set<Object> excludeDetailIds) {
return sqlHelp.findIdsByParentId(parentId, t, includeSoftDeletes, excludeDetailIds);
}
/**
* Find the Id's of detail beans given a list of parent Id's.
*/
@Override
public List<Object> findIdsByParentIdList(List<Object> parentIdList, Transaction t, boolean includeSoftDeletes) {
return sqlHelp.findIdsByParentIdList(parentIdList, t, includeSoftDeletes);
}
/**
@@ -740,7 +755,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
throw new PersistenceException(from + ": Could not find mapKey property " + mapKey + " on " + to);
}
public IntersectionRow buildManyDeleteChildren(EntityBean parentBean, List<Object> excludeDetailIds) {
public IntersectionRow buildManyDeleteChildren(EntityBean parentBean, Set<Object> excludeDetailIds) {
IntersectionRow row = new IntersectionRow(tableJoin.getTable(), targetDescriptor);
if (excludeDetailIds != null && !excludeDetailIds.isEmpty()) {
row.setExcludeIds(excludeDetailIds, targetDescriptor());
@@ -4,12 +4,13 @@ import io.ebean.Transaction;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.api.SpiSqlUpdate;
import io.ebeaninternal.server.core.DefaultSqlUpdate;
import io.ebeaninternal.server.deploy.visitor.BaseTablePropertyVisitor;
import io.ebeaninternal.server.deploy.visitor.VisitProperties;
import io.ebeaninternal.server.core.DefaultSqlUpdate;
import io.ebeaninternal.server.util.Str;
import java.util.List;
import java.util.Set;
class BeanPropertyAssocManySqlHelp<T> {
@@ -86,7 +87,7 @@ class BeanPropertyAssocManySqlHelp<T> {
@Override
public void visitScalar(BeanProperty p, boolean allowNonNull) {
sb.append(",").append(p.dbColumn());
sb.append(',').append(p.dbColumn());
colCount++;
}
@@ -123,30 +124,30 @@ class BeanPropertyAssocManySqlHelp<T> {
many.bindParentIdsIn(rawWhere, parentIds, query);
}
List<Object> findIdsByParentId(Object parentId, Transaction t, List<Object> excludeDetailIds, boolean hard) {
List<Object> findIdsByParentId(Object parentId, Transaction t, boolean includeSoftDeletes, Set<Object> excludeDetailIds) {
final SpiEbeanServer server = descriptor.ebeanServer();
final SpiQuery<?> query = many.newQuery(server);
query.usingTransaction(t);
many.bindParentIdEq(rawParentIdEQ(""), parentId, query);
if (hard) {
if (includeSoftDeletes) {
query.setIncludeSoftDeletes();
}
if (excludeDetailIds != null && !excludeDetailIds.isEmpty()) {
query.where().not(query.getExpressionFactory().idIn(excludeDetailIds));
}
return server.findIds(query, t);
return server.findIds(query);
}
List<Object> findIdsByParentIdList(List<Object> parentIds, Transaction t, List<Object> excludeDetailIds, boolean hard) {
List<Object> findIdsByParentIdList(List<Object> parentIds, Transaction t, boolean includeSoftDeletes) {
final SpiEbeanServer server = descriptor.ebeanServer();
final SpiQuery<?> query = many.newQuery(server);
query.usingTransaction(t);
many.bindParentIdsIn(rawParentIdIN("", parentIds.size()), parentIds, query);
if (hard) {
if (includeSoftDeletes) {
query.setIncludeSoftDeletes();
}
if (excludeDetailIds != null && !excludeDetailIds.isEmpty()) {
query.where().not(query.getExpressionFactory().idIn(excludeDetailIds));
}
return server.findIds(query, t);
return server.findIds(query);
}
SpiSqlUpdate deleteByParentId(Object parentId) {
@@ -166,7 +167,7 @@ class BeanPropertyAssocManySqlHelp<T> {
private void appendBind(StringBuilder sb, int count, boolean skipComma) {
for (int i = 0; i < count; i++) {
if (!skipComma || i > 0) {
sb.append(",");
sb.append(',');
}
sb.append('?');
}
@@ -261,7 +262,7 @@ class BeanPropertyAssocManySqlHelp<T> {
return "?";
}
final var sb = new StringBuilder(exportedProperties.length * 2 + 2);
sb.append("(");
sb.append('(');
for (int i = 0; i < exportedProperties.length; i++) {
if (i > 0) {
sb.append(',');
@@ -237,51 +237,49 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
return encrypted ? elPlaceHolderEncrypted : elPlaceHolder;
}
public SqlUpdate deleteByParentId(Object parentId, List<Object> parentIdist) {
if (parentId != null) {
return deleteByParentId(parentId);
} else {
return deleteByParentIdList(parentIdist);
}
}
private SqlUpdate deleteByParentIdList(List<Object> parentIds) {
@Override
public SqlUpdate deleteByParentIdList(List<Object> parentIds) {
String sql = deleteByParentIdInSql + targetIdBinder.idInValueExpr(false, parentIds.size());
DefaultSqlUpdate delete = new DefaultSqlUpdate(sql);
bindParentIds(delete, parentIds);
return delete;
}
private SqlUpdate deleteByParentId(Object parentId) {
@Override
public SqlUpdate deleteByParentId(Object parentId) {
DefaultSqlUpdate delete = new DefaultSqlUpdate(deleteByParentIdSql);
bindParentId(delete, parentId);
return delete;
}
public List<Object> findIdsByParentId(Object parentId, List<Object> parentIds, Transaction t) {
if (parentId != null) {
return findIdsByParentId(parentId, t);
} else {
return findIdsByParentIdList(parentIds, t);
}
}
private List<Object> findIdsByParentId(Object parentId, Transaction t) {
@Override
public List<Object> findIdsByParentId(Object parentId, Transaction t, boolean includeSoftDeletes) {
String rawWhere = deriveWhereParentIdSql(false);
SpiEbeanServer server = server();
Query<?> q = server.find(type());
SpiQuery<?> q = server.createQuery(type());
q.usingTransaction(t);
bindParentIdEq(rawWhere, parentId, q);
return server.findIds(q, t);
if (includeSoftDeletes) {
q.setIncludeSoftDeletes();
}
return server.findIds(q);
}
private List<Object> findIdsByParentIdList(List<Object> parentIds, Transaction t) {
@Override
public List<Object> findIdsByParentIdList(List<Object> parentIds, Transaction t, boolean includeSoftDeletes) {
String rawWhere = deriveWhereParentIdSql(true);
String inClause = idBinder().idInValueExpr(false, parentIds.size());
String expr = rawWhere + inClause;
SpiEbeanServer server = server();
Query<?> q = server.find(type());
SpiQuery<?> q = server.createQuery(type());
q.usingTransaction(t);
bindParentIdsIn(expr, parentIds, q);
return server.findIds(q, t);
if (includeSoftDeletes) {
q.setIncludeSoftDeletes();
}
return server.findIds(q);
}
void addFkey() {
@@ -1,12 +1,12 @@
package io.ebeaninternal.server.deploy;
import io.ebean.Query;
import io.ebean.Transaction;
import io.ebean.bean.BeanCollection;
import io.ebean.bean.BeanCollectionAdd;
import io.ebean.bean.EntityBean;
import io.ebean.common.BeanSet;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.api.json.SpiJsonWriter;
import java.io.IOException;
@@ -72,12 +72,6 @@ public class BeanSetHelp<T> extends BaseCollectionHelp<T> {
return beanSet;
}
@Override
public final void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
BeanSet<?> newBeanSet = (BeanSet<?>) server.findSet(query, t);
refresh(newBeanSet, parentBean);
}
@Override
public final void refresh(BeanCollection<?> bc, EntityBean parentBean) {
BeanSet<?> newBeanSet = (BeanSet<?>) bc;
@@ -72,7 +72,7 @@ final class DetermineAggPath {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < pos; i++) {
if (i > 0) {
sb.append(".");
sb.append('.');
}
sb.append(paths[i]);
}
@@ -52,7 +52,7 @@ final class ExportedProperty {
public void appendWhere(StringBuilder sb, String alias, String path) {
sb.append(alias).append(foreignDbColumn).append(" = ");
if (path != null) {
sb.append(path).append(".");
sb.append(path).append('.');
}
sb.append(property.name());
}
@@ -51,9 +51,9 @@ public final class IntersectionBuilder {
if (i > 0) {
sb.append(", ");
}
sb.append("?");
sb.append('?');
}
sb.append(")");
sb.append(')');
return sb.toString();
}
@@ -11,13 +11,14 @@ import io.ebeaninternal.server.persist.DeleteMode;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public final class IntersectionRow {
private final String tableName;
private final BeanDescriptor<?> targetDescriptor;
private final LinkedHashMap<String, Object> values = new LinkedHashMap<>();
private List<Object> excludeIds;
private Set<Object> excludeIds;
private BeanDescriptor<?> excludeDescriptor;
IntersectionRow(String tableName, BeanDescriptor<?> targetDescriptor) {
@@ -33,7 +34,7 @@ public final class IntersectionRow {
/**
* Set Id's to exclude. This is for deleting non-attached detail Id's.
*/
void setExcludeIds(List<Object> excludeIds, BeanDescriptor<?> excludeDescriptor) {
void setExcludeIds(Set<Object> excludeIds, BeanDescriptor<?> excludeDescriptor) {
this.excludeIds = excludeIds;
this.excludeDescriptor = excludeDescriptor;
}
@@ -59,9 +60,9 @@ public final class IntersectionRow {
if (i > 0) {
sb.append(", ");
}
sb.append("?");
sb.append('?');
}
sb.append(")");
sb.append(')');
return new DefaultSqlUpdate(server, sb.toString(), bindParams);
}
@@ -105,9 +105,9 @@ public final class TableJoin {
@Override
public String toString() {
StringBuilder sb = new StringBuilder(30);
sb.append(type).append(" ").append(table).append(" ");
sb.append(type).append(' ').append(table).append(' ');
for (TableJoinColumn column : columns) {
sb.append(column).append(" ");
sb.append(column).append(' ');
}
return sb.toString();
}
@@ -160,9 +160,9 @@ public final class TableJoin {
if (i > 0) {
sb.append(" and ");
}
sb.append(a1).append(".").append(pair.getLocalDbColumn());
sb.append(a1).append('.').append(pair.getLocalDbColumn());
sb.append(" = ");
sb.append(a2).append(".").append(pair.getForeignDbColumn());
sb.append(a2).append('.').append(pair.getForeignDbColumn());
}
}
@@ -59,6 +59,13 @@ public interface IdBinder {
*/
boolean isComplexId();
/**
* Return the number of properties that make up the id.
*/
default int size() {
return 1;
}
/**
* Return the default order by that may need to be used if the query includes
* a many property.
@@ -57,26 +57,26 @@ public final class IdBinderEmbedded implements IdBinder {
private String idInExpanded() {
final StringBuilder sb = new StringBuilder(30);
sb.append("(");
sb.append('(');
for (int i = 0; i < props.length; i++) {
if (i > 0) {
sb.append(" and ");
}
sb.append(idDesc.baseTableAlias()).append(".").append(props[i].dbColumn()).append("=?");
sb.append(idDesc.baseTableAlias()).append('.').append(props[i].dbColumn()).append("=?");
}
sb.append(")");
sb.append(')');
return sb.toString();
}
private String idInCompressed() {
final StringBuilder sb = new StringBuilder(props.length * 2 + 2).append("(");
final StringBuilder sb = new StringBuilder(props.length * 2 + 2).append('(');
for (int i = 0; i < props.length; i++) {
if (i > 0) {
sb.append(",");
sb.append(',');
}
sb.append("?");
sb.append('?');
}
sb.append(")");
sb.append(')');
return sb.toString();
}
@@ -114,6 +114,11 @@ public final class IdBinderEmbedded implements IdBinder {
return true;
}
@Override
public int size() {
return props.length;
}
@Override
public String orderBy() {
return orderBy(null, true);
@@ -127,10 +132,10 @@ public final class IdBinderEmbedded implements IdBinder {
sb.append(", ");
}
if (pathPrefix != null) {
sb.append(pathPrefix).append(".");
sb.append(pathPrefix).append('.');
}
if (!idClass) {
sb.append(embIdProperty.name()).append(".");
sb.append(embIdProperty.name()).append('.');
}
sb.append(props[i].name());
if (!ascending) {
@@ -153,19 +158,19 @@ public final class IdBinderEmbedded implements IdBinder {
return idInValueExpr(false, size);
}
final StringBuilder sb = new StringBuilder(80);
sb.append("(");
sb.append('(');
for (int j = 0; j < size; j++) {
if (j > 0) {
sb.append(" or ");
}
sb.append("(");
sb.append('(');
for (int i = 0; i < props.length; i++) {
if (i > 0) {
sb.append(" and ");
}
sb.append(props[i].dbColumn()).append("=?");
}
sb.append(")");
sb.append(')');
}
sb.append(") ");
return sb.toString();
@@ -337,17 +342,17 @@ public final class IdBinderEmbedded implements IdBinder {
@Override
public String assocInExpr(String prefix) {
final StringBuilder sb = new StringBuilder(80);
sb.append("(");
sb.append('(');
for (int i = 0; i < props.length; i++) {
if (i > 0) {
sb.append(", ");
}
if (prefix != null) {
sb.append(prefix).append(".");
sb.append(prefix).append('.');
}
sb.append(props[i].name());
}
sb.append(")");
sb.append(')');
return sb.toString();
}
@@ -359,10 +364,10 @@ public final class IdBinderEmbedded implements IdBinder {
sb.append(" and ");
}
if (prefix != null) {
sb.append(prefix).append(".");
sb.append(prefix).append('.');
}
if (!idClass) {
sb.append(embIdProperty.name()).append(".");
sb.append(embIdProperty.name()).append('.');
}
sb.append(props[i].name()).append(operator);
}
@@ -377,7 +382,7 @@ public final class IdBinderEmbedded implements IdBinder {
sb.append(" and ");
}
if (baseTableAlias != null) {
sb.append(baseTableAlias).append(".");
sb.append(baseTableAlias).append('.');
}
sb.append(props[i].dbColumn()).append("=?");
}
@@ -390,17 +395,17 @@ public final class IdBinderEmbedded implements IdBinder {
return "";
}
final StringBuilder sb = new StringBuilder(80);
sb.append("(");
sb.append('(');
for (int i = 0; i < props.length; i++) {
if (i > 0) {
sb.append(",");
sb.append(',');
}
if (baseTableAlias != null) {
sb.append(baseTableAlias).append(".");
sb.append(baseTableAlias).append('.');
}
sb.append(props[i].dbColumn());
}
sb.append(")");
sb.append(')');
return sb.toString();
}
@@ -436,7 +441,7 @@ public final class IdBinderEmbedded implements IdBinder {
if (val != null) {
sb.append(prop.format(val));
}
sb.append("|");
sb.append('|');
}
return sb.toString();
}
@@ -59,7 +59,7 @@ public final class IdBinderSimple implements IdBinder {
public String orderBy(String pathPrefix, boolean ascending) {
StringBuilder sb = new StringBuilder();
if (pathPrefix != null) {
sb.append(pathPrefix).append(".");
sb.append(pathPrefix).append('.');
}
sb.append(idProperty.name());
if (!ascending) {
@@ -224,7 +224,7 @@ public final class IdBinderSimple implements IdBinder {
StringBuilder sb = new StringBuilder();
if (prefix != null) {
sb.append(prefix);
sb.append(".");
sb.append('.');
}
sb.append(idProperty.name());
return sb.toString();
@@ -809,7 +809,7 @@ public class DeployBeanDescriptor<T> {
for (DeployBeanProperty prop : propMap.values()) {
if (!prop.isTransient() && !(prop instanceof DeployBeanPropertyAssocMany<?>)) {
if (prop.isFetchEager()) {
sb.append(prop.getName()).append(",");
sb.append(prop.getName()).append(',');
} else {
hasLazyFetch = true;
}
@@ -235,17 +235,17 @@ public final class DeployInheritInfo implements Comparable<DeployInheritInfo> {
appendSqlLiteralValue(i, discList.get(i), sb);
}
if (size > 1) {
sb.append(")");
sb.append(')');
}
return sb.toString();
}
private void appendSqlLiteralValue(int count, Object value, StringBuilder sb) {
if (count > 0) {
sb.append(",");
sb.append(',');
}
if (value instanceof String) {
sb.append("'").append(value).append("'");
sb.append('\'').append(value).append('\'');
} else {
sb.append(value);
}
@@ -68,7 +68,7 @@ final class AllEqualsExpression extends NonPrepareExpression {
if (propMap.isEmpty()) {
return;
}
request.append("(");
request.append('(');
int count = 0;
for (Map.Entry<String, Object> entry : propMap.entrySet()) {
Object value = entry.getValue();
@@ -84,7 +84,7 @@ final class AllEqualsExpression extends NonPrepareExpression {
}
count++;
}
request.append(")");
request.append(')');
}
/**
@@ -105,9 +105,9 @@ final class AllEqualsExpression extends NonPrepareExpression {
} else {
builder.append(" =?");
}
builder.append(",");
builder.append(',');
}
builder.append("]");
builder.append(']');
}
@Override
@@ -44,7 +44,7 @@ final class ArrayContainsExpression extends AbstractExpression {
public void queryPlanHash(StringBuilder builder) {
builder.append("ArrayContains[").append(propName)
.append(" b:").append(contains)
.append(" ?:").append(values.length).append("]");
.append(" ?:").append(values.length).append(']');
}
@Override
@@ -30,7 +30,7 @@ final class ArrayIsEmptyExpression extends AbstractExpression {
} else {
builder.append("ArrayIsNotEmpty[");
}
builder.append(propName).append("]");
builder.append(propName).append(']');
}
@Override
@@ -57,7 +57,7 @@ final class BetweenExpression extends AbstractExpression {
@Override
public void queryPlanHash(StringBuilder builder) {
builder.append("Between[").append(propName).append("]");
builder.append("Between[").append(propName).append(']');
}
@Override
@@ -86,7 +86,7 @@ final class BetweenPropertyExpression extends NonPrepareExpression {
@Override
public void queryPlanHash(StringBuilder builder) {
builder.append("BetweenProperties[").append("low:").append(lowProperty).append(" high:").append(highProperty).append("]");
builder.append("BetweenProperties[").append("low:").append(lowProperty).append(" high:").append(highProperty).append(']');
}
@Override
@@ -61,9 +61,9 @@ final class CaseInsensitiveEqualExpression extends AbstractValueExpression {
@Override
public void queryPlanHash(StringBuilder builder) {
if (not) {
builder.append("Ine[").append(propName).append("]");
builder.append("Ine[").append(propName).append(']');
} else {
builder.append("Ieq[").append(propName).append("]");
builder.append("Ieq[").append(propName).append(']');
}
}
@@ -209,7 +209,7 @@ final class DefaultExampleExpression implements SpiExpression, ExampleExpression
if (list.isEmpty()) {
request.append(SQL_TRUE);
} else {
request.append("(");
request.append('(');
for (int i = 0; i < list.size(); i++) {
SpiExpression item = list.get(i);
if (i > 0) {
@@ -217,7 +217,7 @@ final class DefaultExampleExpression implements SpiExpression, ExampleExpression
}
item.addSql(request);
}
request.append(")");
request.append(')');
}
}
@@ -229,9 +229,9 @@ final class DefaultExampleExpression implements SpiExpression, ExampleExpression
builder.append("Example[");
for (SpiExpression expr : list) {
expr.queryPlanHash(builder);
builder.append(",");
builder.append(',');
}
builder.append("]");
builder.append(']');
}
@Override
@@ -36,6 +36,11 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
return "sql";
}
@Override
public <T> ExpressionList<T> expressionList() {
return new DefaultExpressionList<>(this);
}
@Override
public Expression textMatch(String propertyName, String search, Match options) {
return new TextMatchExpression(propertyName, search, options);
@@ -56,6 +56,10 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
this.parentExprList = parentExprList;
}
protected DefaultExpressionList(ExpressionFactory expr) {
this(null, expr, null, new ArrayList<>());
}
private DefaultExpressionList() {
this(null, null, null, new ArrayList<>());
}
@@ -112,10 +116,8 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
* <p>
* If this is the Top level "text" expressions then it detects if explicit or implicit Bool Should, Must etc is required
* to wrap the expressions.
* </p>
* <p>
* If implicit Bool is required SHOULD is used.
* </p>
*/
@Override
public void writeDocQuery(DocQueryContext context) throws IOException {
@@ -442,6 +444,11 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
return query.filterMany(manyProperty).where(expressions, params);
}
@Override
public ExpressionList<T> filterManyRaw(String manyProperty, String rawExpression, Object... params) {
return query.filterMany(manyProperty).raw(rawExpression, params);
}
@Override
public Query<T> withLock(Query.LockType lockType) {
return query.withLock(lockType);
@@ -608,7 +615,7 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
builder.append("textRoot:true ");
}
if (allDocNestedPath != null) {
builder.append("path:").append(allDocNestedPath).append(" ");
builder.append("path:").append(allDocNestedPath).append(' ');
}
for (SpiExpression expr : list) {
expr.queryPlanHash(builder);
@@ -82,9 +82,8 @@ public final class DefaultExpressionRequest implements SpiExpressionRequest {
*/
@Override
public void appendLike(boolean rawLikeExpression) {
sql.append(" ");
sql.append(' ');
sql.append(queryRequest.dbLikeClause(rawLikeExpression));
sql.append(" ");
}
@Override
@@ -110,20 +109,18 @@ public final class DefaultExpressionRequest implements SpiExpressionRequest {
return queryRequest;
}
@Override
public StringBuilder buffer() {
return sql;
}
/**
* Append text the underlying sql expression.
*/
@Override
public SpiExpressionRequest append(String expression) {
sql.append(expression);
return this;
}
@Override
public SpiExpressionRequest append(char c) {
sql.append(c);
return this;
}
@Override
public SpiExpressionRequest property(String expression) {
if (deployParser == null) {
@@ -161,7 +158,7 @@ public final class DefaultExpressionRequest implements SpiExpressionRequest {
if (bindLog == null) {
bindLog = new StringBuilder();
} else {
bindLog.append(",");
bindLog.append(',');
}
bindLog.append(val);
}
@@ -82,7 +82,7 @@ final class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreE
@Override
public void queryPlanHash(StringBuilder builder) {
builder.append("ExistsQuery[").append(" not:").append(not);
builder.append(" sql:").append(sql).append(" ?:").append(bindParams.size()).append("]");
builder.append(" sql:").append(sql).append(" ?:").append(bindParams.size()).append(']');
}
@Override
@@ -95,7 +95,7 @@ final class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreE
if (not) {
request.append("not ");
}
request.append("exists (").parse(sql).append(")");
request.append("exists (").parse(sql).append(')');
}
@Override
@@ -58,7 +58,7 @@ final class ExistsSqlQueryExpression implements SpiExpression, UnsupportedDocSto
@Override
public void queryPlanHash(StringBuilder builder) {
builder.append("ExistsSqlQuery[").append(" not:").append(not);
builder.append(" sql:").append(subQuery).append(" ?:").append(bindParams.length).append("]");
builder.append(" sql:").append(subQuery).append(" ?:").append(bindParams.length).append(']');
}
@Override
@@ -73,7 +73,7 @@ final class ExistsSqlQueryExpression implements SpiExpression, UnsupportedDocSto
if (not) {
request.append("not ");
}
request.append("exists (").parse(subQuery).append(")");
request.append("exists (").parse(subQuery).append(')');
}
@Override
@@ -109,7 +109,7 @@ public final class IdInExpression extends NonPrepareExpression implements IdInCo
// query plan specific to the number of parameters in the IN clause
builder.append(idCollection.size());
}
builder.append("]");
builder.append(']');
}
@Override
@@ -193,7 +193,7 @@ public final class InExpression extends AbstractExpression implements IdInCommon
builder.append(bindValues.size());
}
}
builder.append("]");
builder.append(']');
}
@Override
@@ -1,73 +0,0 @@
package io.ebeaninternal.server.expression;
import io.ebean.annotation.Platform;
import java.time.LocalDate;
import java.util.UUID;
/**
* Adds values as literals to SQL string.
*/
interface InLiterals {
/**
* Add the value as a SQL literal to the buffer.
*/
void append(StringBuilder buffer, Object value);
/**
* Return the InLiterals for the type of the given value.
*/
static InLiterals of(Object val, Platform platform) {
if (val instanceof Number) {
return NumLiteral.INSTANCE;
}
if (val instanceof String || val instanceof UUID) {
return StrLiteral.INSTANCE;
}
if (val instanceof LocalDate) {
return platform.base() == Platform.MYSQL ? DateEscapeLiteral.INSTANCE : DateLiteral.INSTANCE;
}
throw new UnsupportedOperationException();
}
final class NumLiteral implements InLiterals {
static NumLiteral INSTANCE = new NumLiteral();
@Override
public void append(StringBuilder buffer, Object value) {
buffer.append(value);
}
}
final class StrLiteral implements InLiterals {
static StrLiteral INSTANCE = new StrLiteral();
@Override
public void append(StringBuilder buffer, Object value) {
buffer.append('\'').append(value).append('\'');
}
}
final class DateLiteral implements InLiterals {
static DateLiteral INSTANCE = new DateLiteral();
@Override
public void append(StringBuilder buffer, Object value) {
buffer.append("date ").append('\'').append(value).append('\'');
}
}
final class DateEscapeLiteral implements InLiterals {
static DateEscapeLiteral INSTANCE = new DateEscapeLiteral();
@Override
public void append(StringBuilder buffer, Object value) {
buffer.append("{d '").append(value).append("'}");
}
}
}
@@ -103,15 +103,15 @@ final class InPairsExpression extends AbstractExpression {
} else {
builder.append("InPairs[");
}
builder.append(property0).append("-");
builder.append(property1).append("-");
builder.append(separator).append("-");
builder.append(property0).append('-');
builder.append(property1).append('-');
builder.append(separator).append('-');
builder.append(suffix).append(" ?");
if (!multiValueSupported || entries.isEmpty()) {
// query plan specific to the number of parameters in the IN clause
builder.append(entries.size());
}
builder.append("]");
builder.append(']');
}
@Override
@@ -55,12 +55,12 @@ final class InRangeExpression extends AbstractExpression {
if (prop != null && prop.isDbEncrypted()) {
pname = prop.beanProperty().decryptProperty(propName);
}
request.append("(").property(pname).append(" >= ? and ").property(pname).append(" < ?)");
request.append('(').property(pname).append(" >= ? and ").property(pname).append(" < ?)");
}
@Override
public void queryPlanHash(StringBuilder builder) {
builder.append("InRange[").append(propName).append("]");
builder.append("InRange[").append(propName).append(']');
}
@Override
@@ -1,8 +1,6 @@
package io.ebeaninternal.server.expression;
import io.ebean.InTuples;
import io.ebean.annotation.Platform;
import io.ebean.event.BeanQueryRequest;
import io.ebean.service.SpiInTuples;
import io.ebeaninternal.api.BindValuesKey;
import io.ebeaninternal.api.NaturalKeyQueryData;
@@ -10,7 +8,6 @@ import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.api.SpiExpressionRequest;
import java.util.List;
import java.util.UUID;
import static java.util.Objects.requireNonNull;
@@ -19,8 +16,6 @@ final class InTuplesExpression extends AbstractExpression {
private final boolean not;
private final String[] properties;
private final List<Object[]> entries;
private InLiterals[] literals;
private boolean literalMode;
InTuplesExpression(InTuples pairs, boolean not) {
super("");
@@ -31,44 +26,6 @@ final class InTuplesExpression extends AbstractExpression {
this.not = not;
}
@Override
public void prepareExpression(BeanQueryRequest<?> request) {
if (entries.size() > 50) {
// check if this should go into literal mode
final int maxInBinding = request.database().pluginApi().databasePlatform().maxInBinding();
final int threshold = literalThreshold(maxInBinding, properties.length);
if (entries.size() > threshold) {
literals = initLiterals(request.database().platform());
literalMode = literals != null;
}
}
}
private InLiterals[] initLiterals(Platform platform) {
try {
Object[] firstData = entries.get(0);
final InLiterals[] literals = new InLiterals[firstData.length];
for (int i = 0; i < firstData.length; i++) {
literals[i] = InLiterals.of(firstData[i], platform);
}
return literals;
} catch (UnsupportedOperationException e) {
// one of the value types is not supported as a SQL literal
// so stick to binding only
return null;
}
}
/**
* Return the threshold in number of entries before literal mode is used.
*/
static int literalThreshold(int maxInBinding, int propertyCount) {
if (maxInBinding == 0) {
return 5000 / propertyCount;
}
return (maxInBinding / propertyCount) - 200;
}
@Override
public boolean naturalKey(NaturalKeyQueryData<?> data) {
return false;
@@ -81,9 +38,6 @@ final class InTuplesExpression extends AbstractExpression {
@Override
public void addBindValues(SpiExpressionRequest request) {
if (literalMode) {
return;
}
for (Object[] entry : entries) {
for (Object value : entry) {
requireNonNull(value);
@@ -98,45 +52,23 @@ final class InTuplesExpression extends AbstractExpression {
request.append(not ? SQL_TRUE : SQL_FALSE);
return;
}
request.append("(");
request.append('(');
for (int i = 0; i < properties.length; i++) {
if (i > 0) {
request.append(",");
request.append(',');
}
request.property(properties[i]);
}
request.append(") in (");
if (literalMode) {
addSqlLiterals(request);
} else {
addSqlBinding(request);
}
request.append(")");
}
private void addSqlLiterals(SpiExpressionRequest request) {
final var buffer = request.buffer();
for (int i = 0; i < entries.size(); i++) {
if (i > 0) {
buffer.append(',');
}
buffer.append('(');
Object[] values = entries.get(i);
for (int v = 0; v < values.length; v++) {
if (v > 0) {
buffer.append(',');
}
literals[v].append(buffer, values[v]);
}
buffer.append(')');
}
addSqlBinding(request);
request.append(')');
}
private void addSqlBinding(SpiExpressionRequest request) {
final String eb = entryBinding();
for (int i = 0; i < entries.size(); i++) {
if (i > 0) {
request.append(",");
request.append(',');
}
request.append(eb);
}
@@ -159,17 +91,12 @@ final class InTuplesExpression extends AbstractExpression {
*/
@Override
public void queryPlanHash(StringBuilder builder) {
if (literalMode) {
builder.delete(0, builder.length());
builder.append("$NoCache/").append(UUID.randomUUID()).append('/');
return;
}
if (not) {
builder.append("Not");
}
builder.append("InTuple[");
for (String property : properties) {
builder.append(property).append("-");
builder.append(property).append('-');
}
builder.append(entries.size()).append(']');
}
@@ -84,7 +84,7 @@ final class IsEmptyExpression extends AbstractExpression {
request
.append("exists (select 1 ")
.parse(prop.assocIsEmpty(request, propertyPath))
.append(")");
.append(')');
}
/**
@@ -97,7 +97,7 @@ final class IsEmptyExpression extends AbstractExpression {
} else {
builder.append("IsNotEmpty[");
}
builder.append(propName).append("]");
builder.append(propName).append(']');
}
@Override
@@ -80,7 +80,7 @@ final class JsonPathExpression extends AbstractExpression {
if (upperValue != null) {
builder.append(" ?2");
}
builder.append("]");
builder.append(']');
}
@Override

Some files were not shown because too many files have changed in this diff Show More