Compare commits

...
Author SHA1 Message Date
Rob Bygrave c697c010d0 Fix for #3338 Potential shutdown hang with SpringContextShutdownHook and ebean ShutdownHook 2024-02-26 08:30:27 +13:00
Rob Bygrave 24b99d065a Merge branch 'master' into ebean-15x 2024-02-19 22:43:41 +13:00
Rob BygraveandGitHub 187cc0903d Merge pull request #3329 from ebean-orm/feature/bump-test-dependencies
Bump test dependencies for assertj and bytebuddy
2024-02-19 22:04:56 +13:00
Rob Bygrave 1d7a14c8f4 Bump test dependencies for assertj and bytebuddy 2024-02-19 21:51:38 +13:00
Rob Bygrave c58b7d3da3 Test ebean.properties config values 2024-02-15 22:51:26 +13:00
Rob Bygrave 6b2cdc14aa Version 14.0.0 2024-02-15 22:48:38 +13:00
Rob Bygrave 6d712a92a0 Bump ebean-agent to 14.0.0, no functional change 2024-02-15 22:21:09 +13:00
Rob BygraveandGitHub ea11b0c3b6 Merge pull request #3289 from FOCONIS/fix-nested-user-objects
Change semantic of userObjects in nested transaction
2024-02-15 22:10:45 +13:00
Rob BygraveandGitHub 08e8402d05 Merge pull request #3301 from ebean-orm/feature/3295-PC-clear-on-bulk-update
#3295 Clear PersistenceContext on execution of bulk updates or deletes
2024-02-15 22:09:16 +13:00
Rob BygraveandGitHub 006ad79379 Merge branch 'master' into feature/3295-PC-clear-on-bulk-update 2024-02-15 22:09:03 +13:00
Rob BygraveandGitHub 0e063549cd Merge pull request #3327 from ebean-orm/feature/remove-deprecated-commitTransaction
Remove deprecated database.commitTransaction(), migrate to transaction.commit()
2024-02-15 22:07:32 +13:00
Rob BygraveandGitHub 4f0d2cabfb Merge pull request #3325 from ebean-orm/feature/default-batchSize-100
Change default persistBatchSize from 20 to 100 (as a better default value)
2024-02-15 22:07:14 +13:00
Rob Bygrave 80b2d9f983 Remove deprecated database.commitTransaction(), migrate to transaction.commit()
Remove the deprecated methods:
- DB.commitTransaction()
- DB.rollbackTransaction()
- DB.endTransaction()
- database.commitTransaction()
- database.rollbackTransaction()
- database.endTransaction()

Migrate to using try-with-resources and transaction.commit(), transaction.rollback()
2024-02-15 21:56:57 +13:00
Rob Bygrave 287d0c467d #3326 Update the test example of Postgres DML with RETURNING clause to use explicit transactions and transaction.addModification() 2024-02-11 14:25:01 +13:00
Rob Bygrave a8835379e7 #3326 Add test as example of Postgres DML with RETURNING clause 2024-02-11 13:18:19 +13:00
Rob Bygrave e4df20b9dc Update test TestPersistCascade with default batch size 100 2024-02-10 13:28:04 +13:00
Rob Bygrave e6e53e0d93 Change default persistBatchSize from 20 to 100 (as a better default value)
This is the batch size used with PreparedStatement executeBatch() with
batched inserts, updates and deletes. 20 is really on the low side and
bumping this default to 100 seems good and right.
2024-02-10 12:15:50 +13:00
Rob Bygrave 6645e5b9ec Update the test comments in TestPersistenceContextQueryScope
To reflect the behaviour with #3295
2024-01-19 08:58:19 +13:00
Rob Bygrave 3576aafffc #3295 When isAutoPersistUpdates is used do NOT clear the PersistenceContext
Also make improvements to the test asserts in TestPersistenceContextQueryScope
2024-01-10 23:23:47 +13:00
Rob Bygrave 66234249c6 #3295 Clear PersistenceContext on execution of bulk updates or deletes
Using SqlUpdate or an ORM Update query clear the appropriate part of
the PersistenceContext. The effect is that ORM queries executed after
a bulk update will effectively load a fresh copy of the data from the
database and will not reuse an instance from the persistence context
if the bean in question had already been loaded.
2024-01-09 07:44:27 +13:00
Roland Praml 6f64821584 Change semantic of userObjects in nested transaction 2023-12-08 14:50:30 +01:00
robin.bygrave db7fbd5246 Merge branch 'master' into ebean-15x 2023-11-07 15:39:06 +13:00
Rob Bygrave ca97338839 Rebase from master 2023-10-11 22:58:59 +13:00
Rob Bygrave 355144f16d [15x] Update test Document model 2023-10-11 22:55:38 +13:00
Rob Bygrave 7316fb8f1d [15x] Remove Inheritance support 2023-10-11 22:55:36 +13:00
Rob Bygrave 475c30c2a2 [15x] Remove "Future queries" findFutureList, findFutureIds, findFutureCount
Note that findFutureCount still exists as an internal implementation detail
of findPagedList but not exposed via Query API for public use.
2023-10-11 22:54:05 +13:00
Rob Bygrave 5a11dcb2e3 [15x] Remove ElasticSearch support 2023-10-11 22:54:05 +13:00
Rob Bygrave 66d29a7f0c [15x] Remove Draftable support 2023-10-11 22:54:05 +13:00
Rob Bygrave e3af5cdeb4 [15x] Remove Read Auditing feature 2023-10-11 22:54:05 +13:00
Rob Bygrave c4bfa48b59 [15x] Remove Named DTO queries and External Mapping (loading named queries) 2023-10-11 22:54:05 +13:00
Rob Bygrave 8473f9fd39 [15x] Remove Named queries, ANTLR, Query language parser 2023-10-11 22:54:00 +13:00
519 changed files with 1285 additions and 26922 deletions
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -22,13 +22,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -47,19 +47,19 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis-types</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -41,7 +41,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -60,13 +60,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.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.26.1-jakarta</version>
<version>14.0.0</version>
</parent>
<name>ebean api</name>
@@ -155,10 +155,4 @@ public abstract class BeanFinder<I,T> {
return db().findNative(type, nativeSql);
}
/**
* Creates a query using the ORM query language.
*/
protected Query<T> query(String ormQuery) {
return db().createQuery(type, ormQuery);
}
}
-101
View File
@@ -266,55 +266,6 @@ public final class DB {
getDefault().register(transactionCallback);
}
/**
* 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();
}
/**
* If the current transaction has already been committed do nothing otherwise
* rollback the transaction.
* <p>
* It is preferable to use <em>try with resources</em> rather than this.
* <p>
* Useful to put in a finally block to ensure the transaction is ended, rather
* than a rollbackTransaction() in each catch block.
* <p>
* Code example:
*
* <pre>{@code
* DB.beginTransaction();
* try {
* // do some fetching and or persisting
*
* // commit at the end
* DB.commitTransaction();
*
* } finally {
* // if commit didn't occur then rollback the transaction
* DB.endTransaction();
* }
* }</pre>
*/
public static void endTransaction() {
getDefault().endTransaction();
}
/**
* Mark the current transaction as rollback only.
*/
@@ -790,21 +741,6 @@ public final class DB {
return getDefault().createUpdate(beanType, ormUpdate);
}
/**
* Create a named query.
* <p>
* For RawSql the named query is expected to be in ebean.xml.
*
* @param beanType The type of entity bean
* @param namedQuery The name of the query
* @param <T> The type of entity bean
* @return The query
*/
public static <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
return getDefault().createNamedQuery(beanType, namedQuery);
}
/**
* Create a query for a type of entity bean.
* <p>
@@ -824,43 +760,6 @@ public final class DB {
return getDefault().createQuery(beanType);
}
/**
* Parse the Ebean query language statement returning the query which can then
* be modified (add expressions, change order by clause, change maxRows, change
* fetch and select paths etc).
* <p>
* <h3>Example</h3>
* <pre>{@code
*
* // Find order additionally fetching the customer, details and details.product name.
*
* String eql = "fetch customer fetch details fetch details.product (name) where id = :orderId ";
*
* Query<Order> query = DB.createQuery(Order.class, eql);
* query.setParameter("orderId", 2);
*
* Order order = query.findOne();
*
* // This is the same as:
*
* Order order = DB.find(Order.class)
* .fetch("customer")
* .fetch("details")
* .fetch("detail.product", "name")
* .setId(2)
* .findOne();
*
* }</pre>
*
* @param beanType The type of bean to fetch
* @param eql The Ebean query
* @param <T> The type of the entity bean
* @return The query with expressions defined as per the parsed query statement
*/
public static <T> Query<T> createQuery(Class<T> beanType, String eql) {
return getDefault().createQuery(beanType, eql);
}
/**
* Create a query for a type of entity bean.
* <p>
@@ -242,18 +242,6 @@ public interface Database {
*/
<T> UpdateQuery<T> update(Class<T> beanType);
/**
* Create a named query.
* <p>
* For RawSql the named query is expected to be in ebean.xml.
*
* @param beanType The type of entity bean
* @param namedQuery The name of the query
* @param <T> The type of entity bean
* @return The query
*/
<T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery);
/**
* Create a query for an entity bean and synonym for {@link #find(Class)}.
*
@@ -261,41 +249,6 @@ public interface Database {
*/
<T> Query<T> createQuery(Class<T> beanType);
/**
* Parse the Ebean query language statement returning the query which can then
* be modified (add expressions, change order by clause, change maxRows, change
* fetch and select paths etc).
* <p>
* <h3>Example</h3>
* <pre>{@code
*
* // Find order additionally fetching the customer, details and details.product name.
*
* String ormQuery = "fetch customer fetch details fetch details.product (name) where id = :orderId ";
*
* Query<Order> query = DB.createQuery(Order.class, ormQuery);
* query.setParameter("orderId", 2);
*
* Order order = query.findOne();
*
* // This is the same as:
*
* Order order = DB.find(Order.class)
* .fetch("customer")
* .fetch("details")
* .fetch("detail.product", "name")
* .setId(2)
* .findOne();
*
* }</pre>
*
* @param beanType The type of bean to fetch
* @param ormQuery The Ebean ORM query
* @param <T> The type of the entity bean
* @return The query with expressions defined as per the parsed query statement
*/
<T> Query<T> createQuery(Class<T> beanType, String ormQuery);
/**
* Create a query for a type of entity bean.
* <p>
@@ -459,18 +412,6 @@ public interface Database {
*/
<T> DtoQuery<T> findDto(Class<T> dtoType, String sql);
/**
* Create a named Query for DTO beans.
* <p>
* DTO beans are just normal bean like classes with public constructor(s) and setters.
* They do not need to be registered with DB before use.
*
* @param dtoType The type of the DTO bean the rows will be mapped into.
* @param namedQuery The name of the query
* @param <T> The type of the DTO bean.
*/
<T> DtoQuery<T> createNamedDtoQuery(Class<T> dtoType, String namedQuery);
/**
* Look to execute a native sql query that does not return beans but instead
* returns SqlRow or direct access to ResultSet.
@@ -666,49 +607,6 @@ 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();
/**
* If the current transaction has already been committed do nothing otherwise
* rollback the transaction.
* <p>
* Useful to put in a finally block to ensure the transaction is ended, rather
* than a rollbackTransaction() in each catch block.
* <p>
* Code example:
* <p>
* <pre>{@code
*
* database.beginTransaction();
* try {
* // do some fetching and or persisting ...
*
* // commit at the end
* database.commitTransaction();
*
* } finally {
* // if commit didn't occur then rollback the transaction
* database.endTransaction();
* }
*
* }</pre>
*/
void endTransaction();
/**
* Refresh the values of a bean.
* <p>
@@ -1428,109 +1326,6 @@ public interface Database {
*/
ScriptRunner script();
/**
* Return the Document store.
*/
DocumentStore docStore();
/**
* Publish a single bean given its type and id returning the resulting live bean.
* <p>
* The values are published from the draft to the live bean.
*
* @param <T> the type of the entity bean
* @param beanType the type of the entity bean
* @param id the id of the entity bean
* @param transaction the transaction the publish process should use (can be null)
*/
@Nullable
<T> T publish(Class<T> beanType, Object id, Transaction transaction);
/**
* Publish a single bean given its type and id returning the resulting live bean.
* This will use the current transaction or create one if required.
* <p>
* The values are published from the draft to the live bean.
*
* @param <T> the type of the entity bean
* @param beanType the type of the entity bean
* @param id the id of the entity bean
*/
@Nullable
<T> T publish(Class<T> beanType, Object id);
/**
* Publish the beans that match the query returning the resulting published beans.
* <p>
* The values are published from the draft beans to the live beans.
*
* @param <T> the type of the entity bean
* @param query the query used to select the draft beans to publish
* @param transaction the transaction the publish process should use (can be null)
*/
<T> List<T> publish(Query<T> query, Transaction transaction);
/**
* Publish the beans that match the query returning the resulting published beans.
* This will use the current transaction or create one if required.
* <p>
* The values are published from the draft beans to the live beans.
*
* @param <T> the type of the entity bean
* @param query the query used to select the draft beans to publish
*/
<T> List<T> publish(Query<T> query);
/**
* Restore the draft bean back to the live state.
* <p>
* The values from the live beans are set back to the draft bean and the
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
*
* @param <T> the type of the entity bean
* @param beanType the type of the entity bean
* @param id the id of the entity bean to restore
* @param transaction the transaction the restore process should use (can be null)
*/
@Nullable
<T> T draftRestore(Class<T> beanType, Object id, Transaction transaction);
/**
* Restore the draft bean back to the live state.
* <p>
* The values from the live beans are set back to the draft bean and the
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
*
* @param <T> the type of the entity bean
* @param beanType the type of the entity bean
* @param id the id of the entity bean to restore
*/
@Nullable
<T> T draftRestore(Class<T> beanType, Object id);
/**
* Restore the draft beans matching the query back to the live state.
* <p>
* The values from the live beans are set back to the draft bean and the
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
*
* @param <T> the type of the entity bean
* @param query the query used to select the draft beans to restore
* @param transaction the transaction the restore process should use (can be null)
*/
<T> List<T> draftRestore(Query<T> query, Transaction transaction);
/**
* Restore the draft beans matching the query back to the live state.
* <p>
* The values from the live beans are set back to the draft bean and the
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
*
* @param <T> the type of the entity bean
* @param query the query used to select the draft beans to restore
*/
<T> List<T> draftRestore(Query<T> query);
/**
* Returns the set of properties/paths that are unknown (do not map to known properties or paths).
* <p>
@@ -13,8 +13,6 @@ import io.ebean.event.*;
import io.ebean.event.changelog.ChangeLogListener;
import io.ebean.event.changelog.ChangeLogPrepare;
import io.ebean.event.changelog.ChangeLogRegister;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
import jakarta.persistence.EnumType;
import javax.sql.DataSource;
@@ -690,38 +688,6 @@ public interface DatabaseBuilder {
@Deprecated
DatabaseBuilder setChangeLogAsync(boolean changeLogAsync);
/**
* Set the ReadAuditLogger to use. If not set the default implementation is used
* which logs the read events in JSON format to a standard named SLF4J logger
* (which can be configured in say logback to log to a separate log file).
*/
default DatabaseBuilder readAuditLogger(ReadAuditLogger readAuditLogger) {
return setReadAuditLogger(readAuditLogger);
}
/**
* @deprecated migrate to {@link #readAuditLogger(ReadAuditLogger)}.
*/
@Deprecated
DatabaseBuilder setReadAuditLogger(ReadAuditLogger readAuditLogger);
/**
* Set the ReadAuditPrepare to use.
* <p>
* It is expected that an implementation is used that read user context information
* (user id, user ip address etc) and sets it on the ReadEvent bean before it is sent
* to the ReadAuditLogger.
*/
default DatabaseBuilder readAuditPrepare(ReadAuditPrepare readAuditPrepare) {
return setReadAuditPrepare(readAuditPrepare);
}
/**
* @deprecated migrate to {@link #readAuditPrepare(ReadAuditPrepare)}.
*/
@Deprecated
DatabaseBuilder setReadAuditPrepare(ReadAuditPrepare readAuditPrepare);
/**
* Set the configuration for profiling.
*/
@@ -1004,16 +970,6 @@ public interface DatabaseBuilder {
@Deprecated
DatabaseBuilder setAllQuotedIdentifiers(boolean allQuotedIdentifiers);
/**
* Set to true if this Database is Document store only instance (has no JDBC DB).
*/
DatabaseBuilder setDocStoreOnly(boolean docStoreOnly);
/**
* Set the configuration for the ElasticSearch integration.
*/
DatabaseBuilder setDocStoreConfig(DocStoreConfig docStoreConfig);
/**
* Set the constraint naming convention used in DDL generation.
*/
@@ -2442,16 +2398,6 @@ public interface DatabaseBuilder {
*/
boolean isChangeLogAsync();
/**
* Return the ReadAuditLogger to use.
*/
ReadAuditLogger getReadAuditLogger();
/**
* Return the ReadAuditPrepare to use.
*/
ReadAuditPrepare getReadAuditPrepare();
/**
* Return the tenancy catalog provider.
*/
@@ -2590,16 +2536,6 @@ public interface DatabaseBuilder {
*/
boolean isAllQuotedIdentifiers();
/**
* Return true if this Database is a Document store only instance (has no JDBC DB).
*/
boolean isDocStoreOnly();
/**
* Return the configuration for the ElasticSearch integration.
*/
DocStoreConfig getDocStoreConfig();
/**
* Return the constraint naming convention used in DDL generation.
*/
@@ -1,94 +0,0 @@
package io.ebean;
/**
* Bean holding the details to update the document store.
*/
public final class DocStoreQueueEntry {
/**
* Action to either update or delete a document from the index.
*/
public enum Action {
/**
* Action is to update a document in the doc store.
*/
INDEX(1),
/**
* Action is to delete a document from the doc store..
*/
DELETE(2),
/**
* An update is required based on a change to a nested/embedded object at a given path.
*/
NESTED(3);
int value;
Action(int value) {
this.value = value;
}
/**
* Return the value associated with this action type.
*/
public int getValue() {
return value;
}
}
private final Action type;
private final String queueId;
private final String path;
private final Object beanId;
/**
* Construct for an INDEX or DELETE action.
*/
public DocStoreQueueEntry(Action type, String queueId, Object beanId) {
this(type, queueId, null, beanId);
}
/**
* Construct for an NESTED/embedded path invalidation action.
*/
public DocStoreQueueEntry(Action type, String queueId, String path, Object beanId) {
this.type = type;
this.queueId = queueId;
this.path = path;
this.beanId = beanId;
}
/**
* Return the event type.
*/
public Action getType() {
return type;
}
/**
* Return the associate queueId.
*/
public String getQueueId() {
return queueId;
}
/**
* Return the path if this is a nested update.
*/
public String getPath() {
return path;
}
/**
* Return the bean id (which matches the document id).
*/
public Object getBeanId() {
return beanId;
}
}
@@ -1,312 +0,0 @@
package io.ebean;
import io.avaje.lang.NonNullApi;
import io.avaje.lang.Nullable;
import io.ebean.docstore.DocQueryContext;
import io.ebean.docstore.RawDoc;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* Document storage operations.
*/
@NonNullApi
public interface DocumentStore {
/**
* Update the associated document store using the result of the query.
* <p>
* This will execute the query against the database creating a document for each
* bean graph and sending this to the document store.
* </p>
* <p>
* Note that the select and fetch paths of the query is set for you to match the
* document structure needed based on <code>@DocStore</code> and <code>@DocStoreEmbedded</code>
* so what this query requires is the predicates only.
* </p>
* <p>
* This query will be executed using findEach so it is safe to use a query
* that will fetch a lot of beans. The default bulkBatchSize is used.
* </p>
*
* @param query The query that selects object to send to the document store.
*/
<T> void indexByQuery(Query<T> query);
/**
* Update the associated document store index using the result of the query additionally specifying a
* bulkBatchSize to use for sending the messages to ElasticSearch.
*
* @param query The query that selects object to send to the document store.
* @param bulkBatchSize The batch size to use when bulk sending to the document store.
*/
<T> void indexByQuery(Query<T> query, int bulkBatchSize);
/**
* Update the document store for all beans of this type.
* <p>
* This is the same as indexByQuery where the query has no predicates and so fetches all rows.
* </p>
*/
void indexAll(Class<?> beanType);
/**
* Return the bean by fetching it's content from the document store.
* If the document is not found null is returned.
* <p>
* Typically this is called indirectly by findOne() on the query.
* </p>
* <pre>{@code
*
* Customer customer =
* database.find(Customer.class)
* .setUseDocStore(true)
* .setId(42)
* .findOne();
*
* }</pre>
*/
@Nullable
<T> T find(DocQueryContext<T> request);
/**
* Execute the find list query. This request is prepared to execute secondary queries.
* <p>
* Typically this is called indirectly by findList() on the query that has setUseDocStore(true).
* </p>
* <pre>{@code
*
* List<Customer> newCustomers =
* database.find(Customer.class)
* .setUseDocStore(true)
* .where().eq("status, Customer.Status.NEW)
* .findList();
*
* }</pre>
*/
<T> List<T> findList(DocQueryContext<T> request);
/**
* Execute the query against the document store returning the paged list.
* <p>
* The query should have <code>firstRow</code> or <code>maxRows</code> set prior to calling this method.
* </p>
* <p>
* Typically this is called indirectly by findPagedList() on the query that has setUseDocStore(true).
* </p>
* <pre>{@code
*
* PagedList<Customer> newCustomers =
* database.find(Customer.class)
* .setUseDocStore(true)
* .where().eq("status, Customer.Status.NEW)
* .setMaxRows(50)
* .findPagedList();
*
* }</pre>
*/
<T> PagedList<T> findPagedList(DocQueryContext<T> request);
/**
* Execute the query against the document store with the expectation of a large set of results
* that are processed in a scrolling resultSet fashion.
* <p>
* For example, with the ElasticSearch doc store this uses SCROLL.
* </p>
* <p>
* Typically this is called indirectly by findEach() on the query that has setUseDocStore(true).
* </p>
* <pre>{@code
*
* database.find(Order.class)
* .setUseDocStore(true)
* .where()... // perhaps add predicates
* .findEach((Order order) -> {
* // process the bean ...
* });
*
* }</pre>
*/
<T> void findEach(DocQueryContext<T> query, Consumer<T> consumer);
/**
* Execute the query against the document store with the expectation of a large set of results
* that are processed in a scrolling resultSet fashion.
* <p>
* Unlike findEach() this provides the opportunity to stop iterating through the large query.
* </p>
* <p>
* For example, with the ElasticSearch doc store this uses SCROLL.
* </p>
* <p>
* Typically this is called indirectly by findEachWhile() on the query that has setUseDocStore(true).
* </p>
* <pre>{@code
*
* database.find(Order.class)
* .setUseDocStore(true)
* .where()... // perhaps add predicates
* .findEachWhile(new Predicate<Order>() {
* @Override
* public void accept(Order bean) {
* // process the bean
*
* // return true to continue, false to stop
* // boolean shouldContinue = ...
* return shouldContinue;
* }
* });
*
* }</pre>
*/
<T> void findEachWhile(DocQueryContext<T> query, Predicate<T> consumer);
/**
* Find each processing raw documents.
*
* @param indexNameType The full index name and type
* @param rawQuery The query to execute
* @param consumer Consumer to process each document
*/
void findEach(String indexNameType, String rawQuery, Consumer<RawDoc> consumer);
/**
* Find each processing raw documents stopping when the predicate returns false.
*
* @param indexNameType The full index name and type
* @param rawQuery The query to execute
* @param consumer Consumer to process each document until false is returned
*/
void findEachWhile(String indexNameType, String rawQuery, Predicate<RawDoc> consumer);
/**
* Process the queue entries sending updates to the document store or queuing them for later processing.
*/
long process(List<DocStoreQueueEntry> queueEntries) throws IOException;
/**
* Drop the index from the document store (similar to DDL drop table).
* <pre>{@code
*
* DocumentStore documentStore = database.docStore();
*
* documentStore.dropIndex("product_copy");
*
* }</pre>
*/
void dropIndex(String indexName);
/**
* Create an index given a mapping file as a resource in the classPath (similar to DDL create table).
* <pre>{@code
*
* DocumentStore documentStore = database.docStore();
*
* // uses product_copy.mapping.json resource
* // ... to define mappings for the index
*
* documentStore.createIndex("product_copy", null);
*
* }</pre>
*
* @param indexName the name of the new index
* @param alias the alias of the index
*/
void createIndex(String indexName, String alias);
/**
* Modify the settings on an index.
* <p>
* For example, this can be used be used to set elasticSearch refresh_interval
* on an index before a bulk update.
* </p>
* <pre>{@code
*
* // refresh_interval -1 ... disable refresh while bulk loading
*
* Map<String,Object> settings = new LinkedHashMap<>();
* settings.put("refresh_interval", "-1");
*
* documentStore.indexSettings("product", settings);
*
* }</pre>
* <pre>{@code
*
* // refresh_interval 1s ... restore after bulk loading
*
* Map<String,Object> settings = new LinkedHashMap<>();
* settings.put("refresh_interval", "1s");
*
* documentStore.indexSettings("product", settings);
*
* }</pre>
*
* @param indexName the name of the index to update settings on
* @param settings the settings to set on the index
*/
void indexSettings(String indexName, Map<String, Object> settings);
/**
* Copy the index to a new index.
* <p>
* This copy process does not use the database but instead will copy from the source index to a destination index.
* </p>
* <pre>{@code
*
* long copyCount = documentStore.copyIndex(Product.class, "product_copy");
*
* }</pre>
*
* @param beanType The bean type of the source index
* @param newIndex The name of the index to copy to
* @return the number of documents copied to the new index
*/
long copyIndex(Class<?> beanType, String newIndex);
/**
* Copy entries from an index to a new index but limiting to documents that have been
* modified since the sinceEpochMillis time.
* <p>
* To support this the document needs to have a <code>@WhenModified</code> property.
* </p>
* <pre>{@code
*
* long copyCount = documentStore.copyIndex(Product.class, "product_copy", sinceMillis);
*
* }</pre>
*
* @param beanType The bean type of the source index
* @param newIndex The name of the index to copy to
* @return the number of documents copied to the new index
*/
long copyIndex(Class<?> beanType, String newIndex, long sinceEpochMillis);
/**
* Copy from a source index to a new index taking only the documents
* matching the given query.
* <pre>{@code
*
* // predicates to select the source documents to copy
* Query<Product> query = database.find(Product.class)
* .where()
* .ge("whenModified", new Timestamp(since))
* .ge("name", "A")
* .lt("name", "D")
* .query();
*
* // copy from the source index to "product_copy" index
* long copyCount = documentStore.copyIndex(query, "product_copy", 1000);
*
* }</pre>
*
* @param query The query to select the source documents to copy
* @param newIndex The target index to copy the documents to
* @param bulkBatchSize The ElasticSearch bulk batch size, if 0 uses the default.
* @return The number of documents copied to the new index.
*/
long copyIndex(Query<?> query, String newIndex, int bulkBatchSize);
}
@@ -1,7 +1,5 @@
package io.ebean;
import io.ebean.search.*;
import java.util.Collection;
import java.util.Map;
@@ -625,31 +623,6 @@ public interface ExpressionFactory {
*/
Expression raw(String raw);
/**
* Create a Text Match expression (currently doc store/Elastic only).
*/
Expression textMatch(String propertyName, String search, Match options);
/**
* Create a Text Multi match expression (currently doc store/Elastic only).
*/
Expression textMultiMatch(String query, MultiMatch options);
/**
* Create a text simple query expression (currently doc store/Elastic only).
*/
Expression textSimple(String search, TextSimple options);
/**
* Create a text query string expression (currently doc store/Elastic only).
*/
Expression textQueryString(String search, TextQueryString options);
/**
* Create a text common terms expression (currently doc store/Elastic only).
*/
Expression textCommonTerms(String search, TextCommonTerms options);
/**
* And - join two expressions with a logical and.
*/
@@ -693,12 +666,4 @@ public interface ExpressionFactory {
*/
<T> Junction<T> junction(Junction.Type type, Query<T> query, ExpressionList<T> parent);
/**
* Add the expressions to the given expression list.
*
* @param where The expression list to add the expressions to
* @param expressions The expressions that are parsed
* @param params Bind parameters to match ? or ?1 bind positions.
*/
<T> void where(ExpressionList<T> where, String expressions, Object[] params);
}
@@ -2,7 +2,6 @@ package io.ebean;
import io.avaje.lang.NonNullApi;
import io.avaje.lang.Nullable;
import io.ebean.search.*;
import jakarta.persistence.NonUniqueResultException;
import java.sql.Connection;
@@ -106,11 +105,6 @@ public interface ExpressionList<T> {
*/
Query<T> asOf(Timestamp asOf);
/**
* Execute the query against the draft set of tables.
*/
Query<T> asDraft();
/**
* Convert the query to a DTO bean query.
* <p>
@@ -418,42 +412,6 @@ public interface ExpressionList<T> {
*/
Optional<T> findOneOrEmpty();
/**
* Execute find row count query in a background thread.
* <p>
* This returns a Future object which can be used to cancel, check the
* execution status (isDone etc) and get the value (with or without a
* timeout).
* </p>
*
* @return a Future object for the row count query
*/
FutureRowCount<T> findFutureCount();
/**
* Execute find Id's query in a background thread.
* <p>
* This returns a Future object which can be used to cancel, check the
* execution status (isDone etc) and get the value (with or without a
* timeout).
* </p>
*
* @return a Future object for the list of Id's
*/
FutureIds<T> findFutureIds();
/**
* Execute find list query in a background thread.
* <p>
* This returns a Future object which can be used to cancel, check the
* execution status (isDone etc) and get the value (with or without a
* timeout).
* </p>
*
* @return a Future object for the list result of the query
*/
FutureList<T> findFutureList();
/**
* Return a PagedList for this query using firstRow and maxRows.
* <p>
@@ -507,28 +465,6 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> filterMany(String manyProperty);
/**
* @deprecated for removal - migrate to {@link #filterManyRaw(String, String, Object...)}.
* <p>
* Add filter expressions to the many property.
*
* <pre>{@code
*
* DB.find(Customer.class)
* .where()
* .eq("name", "Rob")
* .filterMany("orders", "status = ?", Status.NEW)
* .findList();
*
* }</pre>
*
* @param manyProperty The many property
* @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.
@@ -580,19 +516,6 @@ public interface ExpressionList<T> {
*/
Query<T> setDistinct(boolean distinct);
/**
* Set the index(es) to search for a document store which uses partitions.
* <p>
* For example, when executing a query against ElasticSearch with daily indexes we can
* explicitly specify the indexes to search against.
* </p>
*
* @param indexName The index or indexes to search against
* @return This query
* @see Query#setDocIndexName(String)
*/
Query<T> setDocIndexName(String indexName);
/**
* Set the first row to fetch.
*
@@ -676,14 +599,6 @@ public interface ExpressionList<T> {
return setUseQueryCache(enabled ? CacheMode.ON : CacheMode.OFF);
}
/**
* Set to true if this query should execute against the doc store.
* <p>
* When setting this you may also consider disabling lazy loading.
* </p>
*/
Query<T> setUseDocStore(boolean useDocsStore);
/**
* Set true if you want to disable lazy loading.
* <p>
@@ -692,16 +607,6 @@ public interface ExpressionList<T> {
*/
Query<T> setDisableLazyLoading(boolean disableLazyLoading);
/**
* Disable read auditing for this query.
* <p>
* This is intended to be used when the query is not a user initiated query and instead
* part of the internal processing in an application to load a cache or document store etc.
* In these cases we don't want the query to be part of read auditing.
* </p>
*/
Query<T> setDisableReadAuditing();
/**
* Set a label on the query (to help identify query execution statistics).
*/
@@ -721,14 +626,6 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> where();
/**
* Add the expressions to this expression list.
*
* @param expressions The expressions that are parsed and added to this expression list
* @param params Bind parameters to match ? or ?1 bind positions.
*/
ExpressionList<T> where(String expressions, Object... params);
/**
* Path exists - for the given path in a JSON document.
* <pre>{@code
@@ -1623,47 +1520,6 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> rawOrEmpty(String raw, Collection<?> values);
/**
* Add a match expression.
*
* @param propertyName The property name for the match
* @param search The search value
*/
ExpressionList<T> match(String propertyName, String search);
/**
* Add a match expression with options.
*
* @param propertyName The property name for the match
* @param search The search value
*/
ExpressionList<T> match(String propertyName, String search, Match options);
/**
* Add a multi-match expression.
*/
ExpressionList<T> multiMatch(String search, String... properties);
/**
* Add a multi-match expression using options.
*/
ExpressionList<T> multiMatch(String search, MultiMatch options);
/**
* Add a simple query string expression.
*/
ExpressionList<T> textSimple(String search, TextSimple options);
/**
* Add a query string expression.
*/
ExpressionList<T> textQueryString(String search, TextQueryString options);
/**
* Add common terms expression.
*/
ExpressionList<T> textCommonTerms(String search, TextCommonTerms options);
/**
* And - join two expressions with a logical and.
*/
@@ -1806,42 +1662,6 @@ public interface ExpressionList<T> {
*/
Junction<T> disjunction();
/**
* Start a list of expressions that will be joined by MUST.
* <p>
* This automatically makes the query a useDocStore(true) query that
* will execute against the document store (ElasticSearch etc).
* </p>
* <p>
* This is logically similar to and().
* </p>
*/
Junction<T> must();
/**
* Start a list of expressions that will be joined by SHOULD.
* <p>
* This automatically makes the query a useDocStore(true) query that
* will execute against the document store (ElasticSearch etc).
* </p>
* <p>
* This is logically similar to or().
* </p>
*/
Junction<T> should();
/**
* Start a list of expressions that will be joined by MUST NOT.
* <p>
* This automatically makes the query a useDocStore(true) query that
* will execute against the document store (ElasticSearch etc).
* </p>
* <p>
* This is logically similar to not().
* </p>
*/
Junction<T> mustNot();
/**
* End a junction returning the parent expression list.
* <p>
@@ -213,11 +213,4 @@ public class Finder<I, T> {
return db().findNative(type, nativeSql);
}
/**
* Creates a query using the ORM query language.
*/
public Query<T> query(String ormQuery) {
return db().createQuery(type, ormQuery);
}
}
@@ -1,20 +0,0 @@
package io.ebean;
import java.util.List;
import java.util.concurrent.Future;
/**
* FutureIds represents the result of a background query execution for the Id's.
* <p>
* It extends the java.util.concurrent.Future with the ability to get the Id's
* while the query is still executing in the background.
* </p>
*/
public interface FutureIds<T> extends Future<List<Object>> {
/**
* Returns the original query used to fetch the Id's.
*/
Query<T> getQuery();
}
-138
View File
@@ -250,11 +250,6 @@ public interface Query<T> extends CancelableQuery {
*/
Query<T> asOf(Timestamp asOf);
/**
* Execute the query against the draft set of tables.
*/
Query<T> asDraft();
/**
* Convert the query to a DTO bean query.
* <p>
@@ -321,43 +316,6 @@ public interface Query<T> extends CancelableQuery {
*/
Query<T> setPersistenceContextScope(PersistenceContextScope scope);
/**
* Set the index(es) to search for a document store which uses partitions.
* <p>
* For example, when executing a query against ElasticSearch with daily indexes we can
* explicitly specify the indexes to search against.
* </p>
* <pre>{@code
*
* // explicitly specify the indexes to search
* query.setDocIndexName("logstash-2016.11.5,logstash-2016.11.6")
*
* // search today's index
* query.setDocIndexName("$today")
*
* // search the last 3 days
* query.setDocIndexName("$last-3")
*
* }</pre>
* <p>
* If the indexName is specified with ${daily} e.g. "logstash-${daily}" ... then we can use
* $today and $last-x as the search docIndexName like the examples below.
* </p>
* <pre>{@code
*
* // search today's index
* query.setDocIndexName("$today")
*
* // search the last 3 days
* query.setDocIndexName("$last-3")
*
* }</pre>
*
* @param indexName The index or indexes to search against
* @return This query
*/
Query<T> setDocIndexName(String indexName);
/**
* Return the ExpressionFactory used by this query.
*/
@@ -424,16 +382,6 @@ public interface Query<T> extends CancelableQuery {
*/
Query<T> setIncludeSoftDeletes();
/**
* Disable read auditing for this query.
* <p>
* This is intended to be used when the query is not a user initiated query and instead
* part of the internal processing in an application to load a cache or document store etc.
* In these cases we don't want the query to be part of read auditing.
* </p>
*/
Query<T> setDisableReadAuditing();
/**
* Specify the properties to fetch on the root level entity bean in comma delimited format.
* <p>
@@ -1139,41 +1087,6 @@ public interface Query<T> extends CancelableQuery {
*/
int findCount();
/**
* Execute find row count query in a background thread.
* <p>
* This returns a Future object which can be used to cancel, check the
* execution status (isDone etc) and get the value (with or without a
* timeout).
* </p>
*
* @return a Future object for the row count query
*/
FutureRowCount<T> findFutureCount();
/**
* Execute find Id's query in a background thread.
* <p>
* This returns a Future object which can be used to cancel, check the
* execution status (isDone etc) and get the value (with or without a
* timeout).
* </p>
*
* @return a Future object for the list of Id's
*/
FutureIds<T> findFutureIds();
/**
* Execute find list query in a background thread.
* <p>
* This query will execute in it's own PersistenceContext and using its own transaction.
* What that means is that it will not share any bean instances with other queries.
* </p>
*
* @return a Future object for the list result of the query
*/
FutureList<T> findFutureList();
/**
* Return a PagedList for this query using firstRow and maxRows.
* <p>
@@ -1322,27 +1235,6 @@ public interface Query<T> extends CancelableQuery {
*/
ExpressionList<T> where();
/**
* Add Full text search expressions for Document store queries.
* <p>
* This is currently ElasticSearch only and provides the full text
* expressions such as Match and Multi-Match.
* </p>
* <p>
* This automatically makes this query a "Doc Store" query and will execute
* against the document store (ElasticSearch).
* </p>
* <p>
* Expressions added here are added to the "query" section of an ElasticSearch
* query rather than the "filter" section.
* </p>
* <p>
* Expressions added to the where() are added to the "filter" section of an
* ElasticSearch query.
* </p>
*/
ExpressionList<T> text();
/**
* This applies a filter on the 'many' property list rather than the root
* level objects.
@@ -1601,14 +1493,6 @@ public interface Query<T> extends CancelableQuery {
*/
Query<T> setLabel(String label);
/**
* Set to true if this query should execute against the doc store.
* <p>
* When setting this you may also consider disabling lazy loading.
* </p>
*/
Query<T> setUseDocStore(boolean useDocStore);
/**
* When set to true when you want the returned beans to be read only.
*/
@@ -1743,28 +1627,6 @@ public interface Query<T> extends CancelableQuery {
*/
Class<T> getBeanType();
/**
* Restrict the query to only return subtypes of the given inherit type.
*
* <pre>{@code
*
* List<Animal> animals =
* new QAnimal()
* .name.startsWith("Fluffy")
* .setInheritType(Cat.class)
* .findList();
*
* }</pre>
*
* @param type An inheritance subtype of the
*/
Query<T> setInheritType(Class<? extends T> type);
/**
* Returns the inherit type. This is normally the same as getBeanType() returns as long as no other type is set.
*/
Class<? extends T> getInheritType();
/**
* Return the type of query being executed.
*/
@@ -1,9 +1,7 @@
package io.ebean;
import io.ebean.annotation.DocStoreMode;
import io.ebean.annotation.PersistBatch;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DocStoreConfig;
import jakarta.persistence.PersistenceException;
import java.sql.Connection;
@@ -211,29 +209,6 @@ public interface Transaction extends AutoCloseable {
*/
boolean isActive();
/**
* Set the behavior for document store updates on this transaction.
* <p>
* For example, set the mode to DocStoreEvent.IGNORE for this transaction and
* then any changes via this transaction are not sent to the doc store. This
* would be used when doing large bulk inserts into the database and we want
* to control how that is sent to the document store.
* </p>
*/
void setDocStoreMode(DocStoreMode mode);
/**
* Set the batch size to use for sending messages to the document store.
* <p>
* You might set this if you know the changes in this transaction result in especially large or
* especially small payloads and want to adjust the batch size to match.
* </p>
* <p>
* Setting this overrides the default of {@link DocStoreConfig#getBulkBatchSize()}
* </p>
*/
void setDocStoreBatchSize(int batchSize);
/**
* Explicitly turn off or on the cascading nature of save() and delete(). This
* gives the developer exact control over what beans are saved and deleted
@@ -16,8 +16,6 @@ import io.ebean.event.*;
import io.ebean.event.changelog.ChangeLogListener;
import io.ebean.event.changelog.ChangeLogPrepare;
import io.ebean.event.changelog.ChangeLogRegister;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
import io.ebean.meta.MetricNamingMatch;
import io.ebean.util.StringHelper;
import jakarta.persistence.EnumType;
@@ -137,16 +135,6 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
*/
private List<String> packages = new ArrayList<>();
/**
* Configuration for the ElasticSearch integration.
*/
private DocStoreConfig docStoreConfig = new DocStoreConfig();
/**
* Set to true when the Database only uses Document store.
*/
private boolean docStoreOnly;
/**
* This is used to populate @WhoCreated, @WhoModified and
* support other audit features (who executed a query etc).
@@ -236,7 +224,7 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
*/
private PersistBatch persistBatchOnCascade = PersistBatch.INHERIT;
private int persistBatchSize = 20;
private int persistBatchSize = 100;
private EnumType defaultEnumType = EnumType.ORDINAL;
@@ -421,8 +409,6 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
private ChangeLogListener changeLogListener;
private ChangeLogRegister changeLogRegister;
private boolean changeLogAsync = true;
private ReadAuditLogger readAuditLogger;
private ReadAuditPrepare readAuditPrepare;
private EncryptKeyManager encryptKeyManager;
private EncryptDeployManager encryptDeployManager;
private Encryptor encryptor;
@@ -994,28 +980,6 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
return this;
}
@Override
public ReadAuditLogger getReadAuditLogger() {
return readAuditLogger;
}
@Override
public DatabaseConfig setReadAuditLogger(ReadAuditLogger readAuditLogger) {
this.readAuditLogger = readAuditLogger;
return this;
}
@Override
public ReadAuditPrepare getReadAuditPrepare() {
return readAuditPrepare;
}
@Override
public DatabaseConfig setReadAuditPrepare(ReadAuditPrepare readAuditPrepare) {
this.readAuditPrepare = readAuditPrepare;
return this;
}
@Override
public ProfilingConfig getProfilingConfig() {
return profilingConfig;
@@ -1290,28 +1254,6 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
}
}
@Override
public boolean isDocStoreOnly() {
return docStoreOnly;
}
@Override
public DatabaseConfig setDocStoreOnly(boolean docStoreOnly) {
this.docStoreOnly = docStoreOnly;
return this;
}
@Override
public DocStoreConfig getDocStoreConfig() {
return docStoreConfig;
}
@Override
public DatabaseConfig setDocStoreConfig(DocStoreConfig docStoreConfig) {
this.docStoreConfig = docStoreConfig;
return this;
}
@Override
public DbConstraintNaming getConstraintNaming() {
return platformConfig.getConstraintNaming();
@@ -2084,13 +2026,6 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
readOnlyDataSourceConfig.loadSettings(p.properties, name + "-ro");
}
/**
* This is broken out to allow overridden behaviour.
*/
protected void loadDocStoreSettings(PropertiesWrapper p) {
docStoreConfig.loadSettings(p);
}
/**
* This is broken out to allow overridden behaviour.
*/
@@ -2122,11 +2057,6 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
}
loadDataSourceSettings(p);
if (docStoreConfig == null) {
docStoreConfig = new DocStoreConfig();
}
loadDocStoreSettings(p);
defaultServer = p.getBoolean("defaultServer", defaultServer);
readOnlyDatabase = p.getBoolean("readOnlyDatabase", readOnlyDatabase);
autoPersistUpdates = p.getBoolean("autoPersistUpdates", autoPersistUpdates);
@@ -2142,7 +2072,6 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
queryPlanCapturePeriodSecs = p.getLong("queryPlan.capturePeriodSecs", queryPlanCapturePeriodSecs);
queryPlanCaptureMaxTimeMillis = p.getLong("queryPlan.captureMaxTimeMillis", queryPlanCaptureMaxTimeMillis);
queryPlanCaptureMaxCount = p.getInt("queryPlan.captureMaxCount", queryPlanCaptureMaxCount);
docStoreOnly = p.getBoolean("docStoreOnly", docStoreOnly);
disableL2Cache = p.getBoolean("disableL2Cache", disableL2Cache);
localOnlyL2Cache = p.getBoolean("localOnlyL2Cache", localOnlyL2Cache);
enabledL2Regions = p.get("enabledL2Regions", enabledL2Regions);
@@ -1,320 +0,0 @@
package io.ebean.config;
import io.ebean.Transaction;
import io.ebean.annotation.DocStoreMode;
/**
* Configuration for the Document store integration (e.g. ElasticSearch).
*/
public class DocStoreConfig {
/**
* True when the Document store integration is active/on.
*/
protected boolean active;
/**
* Set to true means Ebean will generate mapping files on startup.
*/
protected boolean generateMapping;
/**
* When true the Document store should drop and re-create document indexes.
*/
protected boolean dropCreate;
/**
* When true the Document store should create any document indexes that don't already exist.
*/
protected boolean create;
/**
* The URL of the Document store. For example: http://localhost:9200.
*/
protected String url;
/**
* Credential that be used for authentication to document store.
*/
protected String username;
/**
* Password credential that be used for authentication to document store.
*/
protected String password;
/**
* Set to true such that the client allows connections to invalid/self signed SSL certificates.
*/
protected boolean allowAllCertificates;
/**
* The default mode used by indexes.
*/
protected DocStoreMode persist = DocStoreMode.UPDATE;
/**
* The default batch size to use for the Bulk API calls.
*/
protected int bulkBatchSize = 1000;
/**
* Resource path for the Document store mapping files.
*/
protected String mappingPath;
/**
* Suffix used for mapping files.
*/
protected String mappingSuffix;
/**
* Location of resources that mapping files are generated into.
*/
protected String pathToResources = "src/main/resources";
/**
* Return true if the Document store (ElasticSearch) integration is active.
*/
public boolean isActive() {
String systemValue = System.getProperty("ebean.docstore.active");
if (systemValue != null) {
return Boolean.parseBoolean(systemValue);
}
return active;
}
/**
* Set to true to make the Document store (ElasticSearch) integration active.
*/
public void setActive(boolean active) {
this.active = active;
}
/**
* Return the URL to the Document store.
*/
public String getUrl() {
String systemValue = System.getProperty("ebean.docstore.url");
if (systemValue != null) {
return systemValue;
}
return url;
}
/**
* Return the user credential for connecting to the document store.
*/
public String getUsername() {
return username;
}
/**
* Set the user credential for connecting to the document store.
*/
public void setUsername(String username) {
this.username = username;
}
/**
* Return the password credential for connecting to the document store.
*/
public String getPassword() {
return password;
}
/**
* Set the password credential for connecting to the document store.
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Set the URL to the Document store.
* <p>
* For a local ElasticSearch server this would be: http://localhost:9200
*/
public void setUrl(String url) {
this.url = url;
}
/**
* Return true if Ebean should generate mapping files on server startup.
*/
public boolean isGenerateMapping() {
String systemValue = System.getProperty("ebean.docstore.generateMapping");
if (systemValue != null) {
return Boolean.parseBoolean(systemValue);
}
return generateMapping;
}
/**
* Set to true if Ebean should generate mapping files on server startup.
*/
public void setGenerateMapping(boolean generateMapping) {
this.generateMapping = generateMapping;
}
/**
* Return true if the document store should recreate mapped indexes.
*/
public boolean isDropCreate() {
String systemValue = System.getProperty("ebean.docstore.dropCreate");
if (systemValue != null) {
return Boolean.parseBoolean(systemValue);
}
return dropCreate;
}
/**
* Set to true if the document store should recreate mapped indexes.
*/
public void setDropCreate(boolean dropCreate) {
this.dropCreate = dropCreate;
}
/**
* Create true if the document store should create mapped indexes that don't yet exist.
* This is only used if dropCreate is false.
*/
public boolean isCreate() {
String systemValue = System.getProperty("ebean.docstore.create");
if (systemValue != null) {
return Boolean.parseBoolean(systemValue);
}
return create;
}
/**
* Set to true if the document store should create mapped indexes that don't yet exist.
* This is only used if dropCreate is false.
*/
public void setCreate(boolean create) {
this.create = create;
}
/**
* Return true if the client allows connections to invalid/self signed SSL certificates.
*/
public boolean isAllowAllCertificates() {
return allowAllCertificates;
}
/**
* Set to true such that the client allows connections to invalid/self signed SSL certificates.
*/
public void setAllowAllCertificates(boolean allowAllCertificates) {
this.allowAllCertificates = allowAllCertificates;
}
/**
* Return the default batch size to use for calls to the Bulk API.
*/
public int getBulkBatchSize() {
return bulkBatchSize;
}
/**
* Set the default batch size to use for calls to the Bulk API.
* <p>
* The batch size can be set on a transaction via {@link Transaction#setDocStoreBatchSize(int)}.
* </p>
*/
public void setBulkBatchSize(int bulkBatchSize) {
this.bulkBatchSize = bulkBatchSize;
}
/**
* Return the mapping path.
*/
public String getMappingPath() {
return mappingPath;
}
/**
* Set the mapping path.
*/
public void setMappingPath(String mappingPath) {
this.mappingPath = mappingPath;
}
/**
* Return the mapping suffix.
*/
public String getMappingSuffix() {
return mappingSuffix;
}
/**
* Set the mapping suffix.
*/
public void setMappingSuffix(String mappingSuffix) {
this.mappingSuffix = mappingSuffix;
}
/**
* Return the relative file system path to resources when generating mapping files.
*/
public String getPathToResources() {
return pathToResources;
}
/**
* Set the relative file system path to resources when generating mapping files.
*/
public void setPathToResources(String pathToResources) {
this.pathToResources = pathToResources;
}
/**
* Return the default behavior for when Insert, Update and Delete events occur on beans that have an associated
* Document store.
*/
public DocStoreMode getPersist() {
return persist;
}
/**
* Set the default behavior for when Insert, Update and Delete events occur on beans that have an associated
* Document store.
* <ul>
* <li>DocStoreEvent.UPDATE - build and send message to Bulk API</li>
* <li>DocStoreEvent.QUEUE - add an entry with the index type and id only into a queue for later processing</li>
* <li>DocStoreEvent.IGNORE - ignore. Most likely used when some scheduled batch job handles updating the index</li>
* </ul>
* <p>
* You might choose to use QUEUE if that particular index data is updating very frequently or the cost of indexing
* is expensive. Setting it to QUEUE can mean many changes can be batched together potentially coalescing multiple
* updates for an index entry into a single update.
* </p>
* <p>
* You might choose to use IGNORE when you have your own external process for updating the indexes. In this case
* you don't want Ebean to do anything when the data changes.
* </p>
*/
public void setPersist(DocStoreMode persist) {
this.persist = persist;
}
/**
* Load settings specified in properties files.
*/
public void loadSettings(PropertiesWrapper properties) {
active = properties.getBoolean("docstore.active", active);
url = properties.get("docstore.url", url);
username = properties.get("docstore.username", url);
password = properties.get("docstore.password", url);
persist = properties.getEnum(DocStoreMode.class, "docstore.persist", persist);
bulkBatchSize = properties.getInt("docstore.bulkBatchSize", bulkBatchSize);
generateMapping = properties.getBoolean("docstore.generateMapping", generateMapping);
dropCreate = properties.getBoolean("docstore.dropCreate", dropCreate);
create = properties.getBoolean("docstore.create", create);
allowAllCertificates = properties.getBoolean("docstore.allowAllCertificates", allowAllCertificates);
mappingPath = properties.get("docstore.mappingPath", mappingPath);
mappingSuffix = properties.get("docstore.mappingSuffix", mappingSuffix);
pathToResources = properties.get("docstore.pathToResources", pathToResources);
}
}
@@ -1,7 +0,0 @@
package io.ebean.docstore;
/**
* Document Mapping for a bean marker interface.
*/
public interface DocMapping {
}
@@ -1,7 +0,0 @@
package io.ebean.docstore;
/**
* Document query request context marker interface.
*/
public interface DocQueryContext<T> {
}
@@ -1,7 +0,0 @@
package io.ebean.docstore;
/**
* Document update context marker interface.
*/
public interface DocUpdateContext {
}
@@ -1,102 +0,0 @@
package io.ebean.docstore;
import java.util.Map;
/**
* Raw document.
*/
public class RawDoc {
private Map<String, Object> source;
private String id;
private double score;
private String index;
private String type;
/**
* Construct the document with all the meta data.
*/
public RawDoc(Map<String, Object> source, String id, double score, String index, String type) {
this.source = source;
this.id = id;
this.score = score;
this.index = index;
this.type = type;
}
/**
* Construct empty (typically for JSON marshalling).
*/
public RawDoc() {
}
/**
* Return the source document as a Map.
*/
public Map<String, Object> getSource() {
return source;
}
/**
* Return the Id value.
*/
public String getId() {
return id;
}
/**
* Return the score.
*/
public double getScore() {
return score;
}
/**
* Return the index name.
*/
public String getIndex() {
return index;
}
/**
* Return the index type.
*/
public String getType() {
return type;
}
/**
* Set the source document.
*/
public void setSource(Map<String, Object> source) {
this.source = source;
}
/**
* Set the id value.
*/
public void setId(String id) {
this.id = id;
}
/**
* Set the score.
*/
public void setScore(double score) {
this.score = score;
}
/**
* Set the index name.
*/
public void setIndex(String index) {
this.index = index;
}
/**
* Set the index type.
*/
public void setType(String type) {
this.type = type;
}
}
@@ -8,6 +8,7 @@ import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
@@ -23,7 +24,7 @@ public final class ShutdownManager {
private static final System.Logger log = EbeanVersion.log;
private static final ReentrantLock lock = new ReentrantLock();
private static final List<Database> databases = new ArrayList<>();
private static final List<Database> databases = Collections.synchronizedList(new ArrayList<>());
private static final ShutdownHook shutdownHook = new ShutdownHook();
private static boolean stopping;
@@ -177,12 +178,7 @@ public final class ShutdownManager {
* Register an ebeanServer to be shutdown when the JVM is shutdown.
*/
public static void registerDatabase(Database server) {
lock.lock();
try {
databases.add(server);
} finally {
lock.unlock();
}
databases.add(server);
}
/**
@@ -192,12 +188,7 @@ public final class ShutdownManager {
* </p>
*/
public static void unregisterDatabase(Database server) {
lock.lock();
try {
databases.remove(server);
} finally {
lock.unlock();
}
databases.remove(server);
}
private static class ShutdownHook extends Thread {
@@ -1,37 +0,0 @@
package io.ebean.event.readaudit;
/**
* Log that the query was executed
*/
public interface ReadAuditLogger {
/**
* Called when a new query plan is created.
* <p>
* The query plan has the full sql and logging the query plan separately means that each of
* the bean and many read events can log the query plan key and not the full sql (reducing the
* bulk size of the read audit logs).
* </p>
*/
void queryPlan(ReadAuditQueryPlan queryPlan);
/**
* Audit a find bean query that returned a bean.
* <p>
* Finds that did not return a bean are excluded.
* </p>
*/
void auditBean(ReadEvent readBean);
/**
* Audit a find many query that returned some beans.
* <p>
* Finds that did not return any beans are excluded.
* </p>
* <p>
* For large queries executed via findEach() etc the ids are collected in batches
* and logged. Hence the ids list has a maximum size of the batch size.
* </p>
*/
void auditMany(ReadEvent readMany);
}
@@ -1,23 +0,0 @@
package io.ebean.event.readaudit;
/**
* Set user context information into the read event prior to it being logged.
*/
public interface ReadAuditPrepare {
/**
* Prepare the read event by setting any user context information into the read event such as the
* application user id and ip address.
* <p>
* This method is called prior to the read event being sent to the ReadAuditLogger.
* </p>
* <p>
* Note that for findFutureList() queries prepare() is called early in the foreground thread
* prior to the query executing and at that point the ReadEvent bean only has the bean type
* and no other details (which are populated later when the query is executed in the background
* thread).
* </p>
*/
void prepare(ReadEvent readEvent);
}
@@ -1,97 +0,0 @@
package io.ebean.event.readaudit;
/**
* A SQL query and associated keys.
* <p>
* This is logged as a separate event so that the
* </p>
*/
public class ReadAuditQueryPlan {
String beanType;
String queryKey;
String sql;
/**
* Construct given the beanType, queryKey and sql.
*/
public ReadAuditQueryPlan(String beanType, String queryKey, String sql) {
this.beanType = beanType;
this.queryKey = queryKey;
this.sql = sql;
}
/**
* Construct for JSON tools.
*/
public ReadAuditQueryPlan() {
}
@Override
public String toString() {
return "beanType:" + beanType + " queryKey:" + queryKey + " sql:" + sql;
}
/**
* Return the bean type.
*/
public String getBeanType() {
return beanType;
}
/**
* Set the bean type.
*/
public void setBeanType(String beanType) {
this.beanType = beanType;
}
/**
* Return the query key (relative to the bean type).
*/
public String getQueryKey() {
return queryKey;
}
/**
* Set the query key.
*/
public void setQueryKey(String queryKey) {
this.queryKey = queryKey;
}
/**
* Return the sql statement.
*/
public String getSql() {
return sql;
}
/**
* Set the sql statement.
*/
public void setSql(String sql) {
this.sql = sql;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ReadAuditQueryPlan that = (ReadAuditQueryPlan) o;
if (!beanType.equals(that.beanType)) return false;
if (!queryKey.equals(that.queryKey)) return false;
return sql.equals(that.sql);
}
@Override
public int hashCode() {
int result = beanType.hashCode();
result = 92821 * result + queryKey.hashCode();
result = 92821 * result + sql.hashCode();
return result;
}
}
@@ -1,261 +0,0 @@
package io.ebean.event.readaudit;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Read event sent to the ReadEventLogger.
* <p>
* This is a flattened in that it contains either a read bean or list of beans. It is flattened
* in this way to simplify logging and processing and simply means that it either contains an
* id or a list of ids.
* </p>
*/
public class ReadEvent {
/**
* User defined 'source' such as the application name.
*/
protected String source;
/**
* Application user id expected to be optionally populated by ChangeLogPrepare.
*/
protected String userId;
/**
* Application user ip address expected to be optionally populated by ChangeLogPrepare.
*/
protected String userIpAddress;
/**
* Arbitrary user context information expected to be optionally populated by ChangeLogPrepare.
*/
protected Map<String, String> userContext;
/**
* The time the bean change was created.
*/
protected long eventTime;
/**
* The type of the bean(s) read.
*/
protected String beanType;
/**
* The query key (relative to the bean type).
*/
protected String queryKey;
/**
* The bind log when the query was executed.
*/
protected String bindLog;
/**
* The id of the bean read.
*/
protected Object id;
/**
* The ids of the beans read.
*/
protected List<Object> ids;
/**
* Common constructor for single bean and multi-bean read events.
*/
protected ReadEvent(String beanType, String queryKey, String bindLog) {
this.beanType = beanType;
this.queryKey = queryKey;
this.bindLog = bindLog;
this.eventTime = System.currentTimeMillis();
}
/**
* Construct for a single bean read.
*/
public ReadEvent(String beanType, String queryKey, String bindLog, Object id) {
this(beanType, queryKey, bindLog);
this.id = id;
}
/**
* Construct for many beans read.
*/
public ReadEvent(String beanType, String queryKey, String bindLog, List<Object> ids) {
this(beanType, queryKey, bindLog);
this.ids = ids;
}
/**
* Construct for many future list query.
*/
public ReadEvent(String beanType) {
this.beanType = beanType;
this.eventTime = System.currentTimeMillis();
}
/**
* Constructor for JSON tools.
*/
public ReadEvent() {
}
/**
* Return a code that identifies the source of the change (like the name of the application).
*/
public String getSource() {
return source;
}
/**
* Set the source of the change (like the name of the application).
*/
public void setSource(String source) {
this.source = source;
}
/**
* Return the application user Id.
*/
public String getUserId() {
return userId;
}
/**
* Set the application user Id.
* <p>
* This can be set by the ChangeLogListener in the prepare() method which is called
* in the foreground thread.
* </p>
*/
public void setUserId(String userId) {
this.userId = userId;
}
/**
* Return the application users ip address.
*/
public String getUserIpAddress() {
return userIpAddress;
}
/**
* Set the application users ip address.
* <p>
* This can be set by the ChangeLogListener in the prepare() method which is called
* in the foreground thread.
* </p>
*/
public void setUserIpAddress(String userIpAddress) {
this.userIpAddress = userIpAddress;
}
/**
* Return a user context value - anything you set yourself in ChangeLogListener prepare().
*/
public Map<String, String> getUserContext() {
if (userContext == null) {
userContext = new LinkedHashMap<>();
}
return userContext;
}
/**
* Set a user context value (anything you like).
* <p>
* This can be set by the ChangeLogListener in the prepare() method which is called
* in the foreground thread.
* </p>
*/
public void setUserContext(Map<String, String> userContext) {
this.userContext = userContext;
}
/**
* Return the type of bean read.
*/
public String getBeanType() {
return beanType;
}
/**
* Set the type of bean read.
*/
public void setBeanType(String beanType) {
this.beanType = beanType;
}
/**
* Return the query key (relative to the bean type).
*/
public String getQueryKey() {
return queryKey;
}
/**
* Set the query key (relative to the bean type).
*/
public void setQueryKey(String queryKey) {
this.queryKey = queryKey;
}
/**
* Return the bind log used when executing the query.
*/
public String getBindLog() {
return bindLog;
}
/**
* Set the bind log used when executing the query.
*/
public void setBindLog(String bindLog) {
this.bindLog = bindLog;
}
/**
* Return the event date time.
*/
public long getEventTime() {
return eventTime;
}
/**
* Set the event date time.
*/
public void setEventTime(long eventTime) {
this.eventTime = eventTime;
}
/**
* Return the id of the bean read.
*/
public Object getId() {
return id;
}
/**
* Set the id of the bean read.
*/
public void setId(Object id) {
this.id = id;
}
/**
* Return the ids of the beans read.
*/
public List<Object> getIds() {
return ids;
}
/**
* Set the ids of the beans read.
*/
public void setIds(List<Object> ids) {
this.ids = ids;
}
}
@@ -1,8 +0,0 @@
/**
* Provides Auditing of read events including queries and L2 cache.
* <p>
* Provides a built support for supplied an audit of all the 'read events' for beans annotated
* with <code>@ReadAudit</code>
* </p>
*/
package io.ebean.event.readaudit;
@@ -1,72 +0,0 @@
package io.ebean.plugin;
import io.ebean.FetchPath;
import io.ebean.Query;
import io.ebean.docstore.DocUpdateContext;
import java.io.IOException;
/**
* Doc store functions for a specific entity bean type.
*
* @param <T> The type of entity bean
*/
public interface BeanDocType<T> {
/**
* Return the doc store index type for this bean type.
*/
String indexType();
/**
* Return the doc store index name for this bean type.
*/
String indexName();
/**
* Apply the appropriate fetch path to the query such that the query returns beans matching
* the document store structure with the expected embedded properties.
*/
void applyPath(Query<T> spiQuery);
/**
* Return the FetchPath for the embedded document.
*/
FetchPath embedded(String path);
/**
* For embedded 'many' properties we need a FetchPath relative to the root which is used to
* build and replace the embedded list.
*/
FetchPath embeddedManyRoot(String path);
/**
* Return a 'raw' property mapped for the given property.
* If none exists the given property is returned.
*/
String rawProperty(String property);
/**
* Store the bean in the doc store index.
* <p>
* This somewhat assumes the bean is fetched with appropriate path properties
* to match the expected document structure.
*/
void index(Object idValue, T bean, DocUpdateContext txn) throws IOException;
/**
* Add a delete by Id to the doc store.
*/
void deleteById(Object idValue, DocUpdateContext txn) throws IOException;
/**
* Add a embedded document update to the doc store.
*
* @param idValue the Id value of the bean holding the embedded document
* @param embeddedProperty the embedded property
* @param embeddedRawContent the content of the embedded document in JSON form
* @param txn the doc store transaction to add the update to
*/
void updateEmbedded(Object idValue, String embeddedProperty, String embeddedRawContent, DocUpdateContext txn) throws IOException;
}
@@ -2,15 +2,12 @@ package io.ebean.plugin;
import io.ebean.Query;
import io.ebean.config.dbplatform.IdType;
import io.ebean.docstore.DocMapping;
import io.ebean.event.BeanFindController;
import io.ebean.event.BeanPersistController;
import io.ebean.event.BeanPersistListener;
import io.ebean.event.BeanQueryAdapter;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
/**
* Information and methods on BeanDescriptors made available to plugins.
@@ -145,73 +142,4 @@ public interface BeanType<T> {
*/
IdType idType();
/**
* Return true if this bean type has doc store backing.
*/
boolean isDocStoreMapped();
/**
* Return the DocumentMapping for this bean type.
* <p>
* This is the document structure and mapping options for how this bean type is mapped
* for the document store.
* </p>
*/
DocMapping docMapping();
/**
* Return the doc store queueId for this bean type.
*/
String docStoreQueueId();
/**
* Return the doc store support for this bean type.\
*/
BeanDocType<T> docStore();
/**
* Add the discriminator value to the query if needed.
*/
void addInheritanceWhere(Query<?> query);
/**
* Return the root bean type for an inheritance hierarchy.
*/
BeanType<?> root();
/**
* Return true if this bean type has an inheritance hierarchy.
*/
boolean hasInheritance();
/**
* Return true if this object is the root level object in its entity
* inheritance.
*/
boolean isInheritanceRoot();
/**
* Returns all direct children of this beantype
*/
List<BeanType<?>> inheritanceChildren();
/**
* Returns the parent in inheritance hierarchy
*/
BeanType<?> inheritanceParent();
/**
* Visit all children recursively
*/
void visitAllInheritanceChildren(Consumer<BeanType<?>> visitor);
/**
* Return the discriminator column.
*/
String discColumn();
/**
* Create a bean given the discriminator value.
*/
T createBeanUsingDisc(Object discValue);
}
@@ -38,11 +38,6 @@ public interface SpiServer extends Database {
*/
List<? extends BeanType<?>> beanTypes(String baseTableName);
/**
* Return the bean type for a given doc store queueId.
*/
BeanType<?> beanTypeForQueueId(String queueId);
/**
* Return a BeanLoader.
*/
@@ -1,98 +0,0 @@
package io.ebean.search;
/**
* Options for the text match and multi match expressions.
*/
public abstract class AbstractMatch {
protected boolean operatorAnd;
protected String analyzer;
protected double boost;
protected String minShouldMatch;
protected int maxExpansions;
protected String zeroTerms;
protected double cutoffFrequency;
protected String fuzziness;
protected int prefixLength;
protected String rewrite;
/**
* Return true if using the AND operator otherwise using the OR operator.
*/
public boolean isOperatorAnd() {
return operatorAnd;
}
/**
* Return the boost.
*/
public double getBoost() {
return boost;
}
/**
* Return the minimum should match.
*/
public String getMinShouldMatch() {
return minShouldMatch;
}
/**
* Return the zero terms option.
*/
public String getZeroTerms() {
return zeroTerms;
}
/**
* Return the cutoff frequency.
*/
public double getCutoffFrequency() {
return cutoffFrequency;
}
/**
* Return the max expansions.
*/
public int getMaxExpansions() {
return maxExpansions;
}
/**
* Return the analyzer.
*/
public String getAnalyzer() {
return analyzer;
}
/**
* Return the fuzziness.
*/
public String getFuzziness() {
return fuzziness;
}
/**
* Return the prefix length.
*/
public int getPrefixLength() {
return prefixLength;
}
/**
* Return the rewrite option.
*/
public String getRewrite() {
return rewrite;
}
}
@@ -1,117 +0,0 @@
package io.ebean.search;
/**
* Options for the text match expression.
*/
public class Match extends AbstractMatch {
protected boolean phrase;
protected boolean phrasePrefix;
public Match() {
}
/**
* Set this to be a "Phrase" type expression.
*/
public Match phrase() {
phrase = true;
return this;
}
/**
* Set this to be a "Phrase Prefix" type expression.
*/
public Match phrasePrefix() {
phrasePrefix = true;
return this;
}
/**
* Use the AND operator (rather than OR).
*/
public Match opAnd() {
operatorAnd = true;
return this;
}
/**
* Use the OR operator (rather than AND).
*/
public Match opOr() {
operatorAnd = false;
return this;
}
/**
* Set the zero terms.
*/
public Match zeroTerms(String zeroTerms) {
this.zeroTerms = zeroTerms;
return this;
}
/**
* Set the cutoff frequency.
*/
public Match cutoffFrequency(double cutoffFrequency) {
this.cutoffFrequency = cutoffFrequency;
return this;
}
/**
* Set the max expansions (for phrase prefix only).
*/
public Match maxExpansions(int maxExpansions) {
this.maxExpansions = maxExpansions;
return this;
}
/**
* Set the Analyzer to use for this expression.
*/
public Match analyzer(String analyzer) {
this.analyzer = analyzer;
return this;
}
/**
* Set the boost.
*/
public Match boost(double boost) {
this.boost = boost;
return this;
}
/**
* Set the rewrite to use.
*/
public Match minShouldMatch(String minShouldMatch) {
this.minShouldMatch = minShouldMatch;
return this;
}
/**
* Set the rewrite to use.
*/
public Match rewrite(String rewrite) {
this.rewrite = rewrite;
return this;
}
/**
* Return true if this is a phrase query.
*/
public boolean isPhrase() {
return phrase;
}
/**
* Return true if this is a phrase prefix query.
*/
public boolean isPhrasePrefix() {
return phrasePrefix;
}
}
@@ -1,148 +0,0 @@
package io.ebean.search;
/**
* Options for the text match expression.
*/
public class MultiMatch extends AbstractMatch {
/**
* The MultiMatch type.
*/
public enum Type {
BEST_FIELDS,
MOST_FIELDS,
CROSS_FIELDS,
PHRASE,
PHRASE_PREFIX
}
protected final String[] fields;
protected Type type = Type.BEST_FIELDS;
protected double tieBreaker;
/**
* Create with the given fields.
*/
public static MultiMatch fields(String... fields) {
return new MultiMatch(fields);
}
/**
* Construct with a set of fields.
*/
public MultiMatch(String... fields) {
this.fields = fields;
}
/**
* Set the type of query.
*/
public MultiMatch type(Type type) {
this.type = type;
return this;
}
/**
* Set the tieBreaker to use.
*/
public MultiMatch tieBreaker(double tieBreaker) {
this.tieBreaker = tieBreaker;
return this;
}
/**
* Use the AND operator (rather than OR).
*/
public MultiMatch opAnd() {
operatorAnd = true;
return this;
}
/**
* Use the OR operator (rather than AND).
*/
public MultiMatch opOr() {
operatorAnd = false;
return this;
}
/**
* Set the minimum should match value.
*/
public MultiMatch minShouldMatch(String minShouldMatch) {
this.minShouldMatch = minShouldMatch;
return this;
}
/**
* Set the boost.
*/
public MultiMatch boost(double boost) {
this.boost = boost;
return this;
}
/**
* Set the zero terms.
*/
public MultiMatch zeroTerms(String zeroTerms) {
this.zeroTerms = zeroTerms;
return this;
}
/**
* Set the cutoff frequency.
*/
public MultiMatch cutoffFrequency(double cutoffFrequency) {
this.cutoffFrequency = cutoffFrequency;
return this;
}
/**
* Set the max expansions (for phrase prefix only).
*/
public MultiMatch maxExpansions(int maxExpansions) {
this.maxExpansions = maxExpansions;
return this;
}
/**
* Set the Analyzer to use for this expression.
*/
public MultiMatch analyzer(String analyzer) {
this.analyzer = analyzer;
return this;
}
/**
* Set the rewrite to use.
*/
public MultiMatch rewrite(String rewrite) {
this.rewrite = rewrite;
return this;
}
/**
* Return the type.
*/
public Type getType() {
return type;
}
/**
* Return the fields to search.
*/
public String[] getFields() {
return fields;
}
/**
* Return the tie breaker.
*/
public double getTieBreaker() {
return tieBreaker;
}
}
@@ -1,139 +0,0 @@
package io.ebean.search;
/**
* Text common terms query.
* <p>
* This maps to an ElasticSearch "common terms query".
* </p>
* <pre>{@code
*
* TextCommonTerms options = new TextCommonTerms()
* .cutoffFrequency(0.001)
* .minShouldMatch("50%")
* .lowFreqOperatorAnd(true)
* .highFreqOperatorAnd(true);
*
* List<Customer> customers = database.find(Customer.class)
* .text()
* .textCommonTerms("the brown", options)
* .findList();
*
* }</pre>
* <pre>{@code
*
* // ElasticSearch expression
*
* "common": {
* "body": {
* "query": "the brown",
* "cutoff_frequency": 0.001,
* "low_freq_operator": "and",
* "high_freq_operator": "and",
* "minimum_should_match": "50%"
* }
* }
*
* }</pre>
*/
public class TextCommonTerms {
protected double cutoffFrequency;
protected boolean lowFreqOperatorAnd;
protected boolean highFreqOperatorAnd;
protected String minShouldMatch;
protected String minShouldMatchLowFreq;
protected String minShouldMatchHighFreq;
/**
* Set the cutoff frequency.
*/
public TextCommonTerms cutoffFrequency(double cutoffFrequency) {
this.cutoffFrequency = cutoffFrequency;
return this;
}
/**
* Set to true if low frequency terms should use AND operator.
*/
public TextCommonTerms lowFreqOperatorAnd(boolean opAnd) {
this.lowFreqOperatorAnd = opAnd;
return this;
}
/**
* Set to true if high frequency terms should use AND operator.
*/
public TextCommonTerms highFreqOperatorAnd(boolean opAnd) {
this.highFreqOperatorAnd = opAnd;
return this;
}
/**
* Set the minimum should match.
*/
public TextCommonTerms minShouldMatch(String minShouldMatch) {
this.minShouldMatch = minShouldMatch;
return this;
}
/**
* Set the minimum should match for low frequency terms.
*/
public TextCommonTerms minShouldMatchLowFreq(String minShouldMatchLowFreq) {
this.minShouldMatchLowFreq = minShouldMatchLowFreq;
return this;
}
/**
* Set the minimum should match for high frequency terms.
*/
public TextCommonTerms minShouldMatchHighFreq(String minShouldMatchHighFreq) {
this.minShouldMatchHighFreq = minShouldMatchHighFreq;
return this;
}
/**
* Return true if low freq should use the AND operator.
*/
public boolean isLowFreqOperatorAnd() {
return lowFreqOperatorAnd;
}
/**
* Return true if high freq should use the AND operator.
*/
public boolean isHighFreqOperatorAnd() {
return highFreqOperatorAnd;
}
/**
* Return the cutoff frequency.
*/
public double getCutoffFrequency() {
return cutoffFrequency;
}
/**
* Return the minimum to match.
*/
public String getMinShouldMatch() {
return minShouldMatch;
}
/**
* Return the minimum to match for high frequency.
*/
public String getMinShouldMatchHighFreq() {
return minShouldMatchHighFreq;
}
/**
* Return the minimum to match for low frequency.
*/
public String getMinShouldMatchLowFreq() {
return minShouldMatchLowFreq;
}
}
@@ -1,398 +0,0 @@
package io.ebean.search;
/**
* Text query string options.
* <p>
* This maps to an ElasticSearch "query string query".
* </p>
* <pre>{@code
*
* TextQueryString options = new TextQueryString()
* .analyzeWildcard(true)
* .fields("name")
* .lenient(true)
* .opAnd();
*
* List<Customer> customers = database.find(Customer.class)
* .text()
* .textSimple("quick brown", options)
* .findList();
*
* }</pre>
* <pre>{@code
*
* // just use default options
* TextQueryString options = new TextQueryString();
*
* List<Customer> customers = database.find(Customer.class)
* .text()
* .textSimple("quick brown", options)
* .findList();
*
* }</pre>
*/
public class TextQueryString {
public static final int DEFAULT_FUZZY_MAX_EXPANSIONS = 50;
protected final String[] fields;
/**
* Only used when multiple fields set.
*/
protected boolean useDisMax = true;
/**
* Only used when multiple fields set.
*/
protected double tieBreaker;
protected String defaultField;
protected boolean operatorAnd;
protected String analyzer;
protected boolean allowLeadingWildcard = true;
protected boolean lowercaseExpandedTerms = true;
protected int fuzzyMaxExpansions = DEFAULT_FUZZY_MAX_EXPANSIONS;
protected String fuzziness;
protected int fuzzyPrefixLength;
protected double phraseSlop;
protected double boost;
protected boolean analyzeWildcard;
protected boolean autoGeneratePhraseQueries;
protected String minShouldMatch;
protected boolean lenient;
protected String locale;
protected String timeZone;
protected String rewrite;
/**
* Create with given fields.
*/
public static TextQueryString fields(String... fields) {
return new TextQueryString(fields);
}
/**
* Construct with the fields to use.
*/
public TextQueryString(String... fields) {
this.fields = fields;
}
/**
* Use the AND operator (rather than OR).
*/
public TextQueryString opAnd() {
this.operatorAnd = true;
return this;
}
/**
* Use the OR operator (rather than AND).
*/
public TextQueryString opOr() {
this.operatorAnd = false;
return this;
}
/**
* Set the locale.
*/
public TextQueryString locale(String locale) {
this.locale = locale;
return this;
}
/**
* Set lenient mode.
*/
public TextQueryString lenient(boolean lenient) {
this.lenient = lenient;
return this;
}
/**
* Set the minimum should match.
*/
public TextQueryString minShouldMatch(String minShouldMatch) {
this.minShouldMatch = minShouldMatch;
return this;
}
/**
* Set the analyzer.
*/
public TextQueryString analyzer(String analyzer) {
this.analyzer = analyzer;
return this;
}
/**
* Set useDisMax option (when multiple fields only).
*/
public TextQueryString useDisMax(boolean useDisMax) {
this.useDisMax = useDisMax;
return this;
}
/**
* Set tieBreaker option (when multiple fields only).
*/
public TextQueryString tieBreaker(double tieBreaker) {
this.tieBreaker = tieBreaker;
return this;
}
/**
* Set the default field.
*/
public TextQueryString defaultField(String defaultField) {
this.defaultField = defaultField;
return this;
}
/**
* Set allow leading wildcard mode.
*/
public TextQueryString allowLeadingWildcard(boolean allowLeadingWildcard) {
this.allowLeadingWildcard = allowLeadingWildcard;
return this;
}
/**
* Set lowercase expanded terms mode.
*/
public TextQueryString lowercaseExpandedTerms(boolean lowercaseExpandedTerms) {
this.lowercaseExpandedTerms = lowercaseExpandedTerms;
return this;
}
/**
* Set fuzzy max expansions.
*/
public TextQueryString fuzzyMaxExpansions(int fuzzyMaxExpansions) {
this.fuzzyMaxExpansions = fuzzyMaxExpansions;
return this;
}
/**
* Set fuzziness.
*/
public TextQueryString fuzziness(String fuzziness) {
this.fuzziness = fuzziness;
return this;
}
/**
* Set the fuzzy prefix length.
*/
public TextQueryString fuzzyPrefixLength(int fuzzyPrefixLength) {
this.fuzzyPrefixLength = fuzzyPrefixLength;
return this;
}
/**
* Set the phrase slop.
*/
public TextQueryString phraseSlop(double phraseSlop) {
this.phraseSlop = phraseSlop;
return this;
}
/**
* Set the boost.
*/
public TextQueryString boost(double boost) {
this.boost = boost;
return this;
}
/**
* Set the analyze wildcard mode.
*/
public TextQueryString analyzeWildcard(boolean analyzeWildcard) {
this.analyzeWildcard = analyzeWildcard;
return this;
}
/**
* Set the auto generate phrase queries mode.
*/
public TextQueryString autoGeneratePhraseQueries(boolean autoGeneratePhraseQueries) {
this.autoGeneratePhraseQueries = autoGeneratePhraseQueries;
return this;
}
/**
* Set the time zone.
*/
public TextQueryString timeZone(String timeZone) {
this.timeZone = timeZone;
return this;
}
/**
* Set the rewrite option.
*/
public TextQueryString rewrite(String rewrite) {
this.rewrite = rewrite;
return this;
}
/**
* Return the rewrite option.
*/
public String getRewrite() {
return rewrite;
}
/**
* Return the fields.
*/
public String[] getFields() {
return fields;
}
/**
* Return true if AND is the default operator.
*/
public boolean isOperatorAnd() {
return operatorAnd;
}
/**
* Return the analyzer.
*/
public String getAnalyzer() {
return analyzer;
}
/**
* Return the locale.
*/
public String getLocale() {
return locale;
}
/**
* Return lenient mode.
*/
public boolean isLenient() {
return lenient;
}
/**
* Return the minimum should match.
*/
public String getMinShouldMatch() {
return minShouldMatch;
}
/**
* Return the useDixMax mode.
*/
public boolean isUseDisMax() {
return useDisMax;
}
/**
* Return the tie breaker.
*/
public double getTieBreaker() {
return tieBreaker;
}
/**
* Return the default field.
*/
public String getDefaultField() {
return defaultField;
}
/**
* Return the allow leading wildcard mode.
*/
public boolean isAllowLeadingWildcard() {
return allowLeadingWildcard;
}
/**
* Return the lowercase expanded terms mode.
*/
public boolean isLowercaseExpandedTerms() {
return lowercaseExpandedTerms;
}
/**
* Return the fuzzy max expansions.
*/
public int getFuzzyMaxExpansions() {
return fuzzyMaxExpansions;
}
/**
* Return the fuzziness.
*/
public String getFuzziness() {
return fuzziness;
}
/**
* Return the fuzzy prefix length.
*/
public int getFuzzyPrefixLength() {
return fuzzyPrefixLength;
}
/**
* Return the phrase slop.
*/
public double getPhraseSlop() {
return phraseSlop;
}
/**
* Return the analyze wildcard mode.
*/
public boolean isAnalyzeWildcard() {
return analyzeWildcard;
}
/**
* Return the boost.
*/
public double getBoost() {
return boost;
}
/**
* Return the auto generate phase queries mode.
*/
public boolean isAutoGeneratePhraseQueries() {
return autoGeneratePhraseQueries;
}
/**
* Return the time zone.
*/
public String getTimeZone() {
return timeZone;
}
}
@@ -1,193 +0,0 @@
package io.ebean.search;
/**
* Simple text query options.
* <p>
* This maps to an ElasticSearch "simple text query".
* </p>
* <pre>{@code
*
* TextSimple options = new TextSimple()
* .analyzeWildcard(true)
* .fields("name")
* .lenient(true)
* .opAnd();
*
* List<Customer> customers = database.find(Customer.class)
* .text()
* .textSimple("quick brown", options)
* .findList();
*
* }</pre>
*/
public class TextSimple {
protected String[] fields;
protected boolean operatorAnd;
protected String analyzer;
protected String flags;
protected boolean lowercaseExpandedTerms = true;
protected boolean analyzeWildcard;
protected String locale;
protected boolean lenient;
protected String minShouldMatch;
/**
* Construct
*/
public TextSimple() {
}
/**
* Set the fields.
*/
public TextSimple fields(String... fields) {
this.fields = fields;
return this;
}
/**
* Use AND as the default operator.
*/
public TextSimple opAnd() {
this.operatorAnd = true;
return this;
}
/**
* Use OR as the default operator.
*/
public TextSimple opOr() {
this.operatorAnd = false;
return this;
}
/**
* Set the analyzer
*/
public TextSimple analyzer(String analyzer) {
this.analyzer = analyzer;
return this;
}
/**
* Set the flags.
*/
public TextSimple flags(String flags) {
this.flags = flags;
return this;
}
/**
* Set the false to not use lowercase expanded terms.
*/
public TextSimple lowercaseExpandedTerms(boolean lowercaseExpandedTerms) {
this.lowercaseExpandedTerms = lowercaseExpandedTerms;
return this;
}
/**
* Set to true to use analyze wildcard.
*/
public TextSimple analyzeWildcard(boolean analyzeWildcard) {
this.analyzeWildcard = analyzeWildcard;
return this;
}
/**
* Set the locale.
*/
public TextSimple locale(String locale) {
this.locale = locale;
return this;
}
/**
* Set the lenient mode.
*/
public TextSimple lenient(boolean lenient) {
this.lenient = lenient;
return this;
}
/**
* Set the minimum should match.
*/
public TextSimple minShouldMatch(String minShouldMatch) {
this.minShouldMatch = minShouldMatch;
return this;
}
/**
* Return lenient mode.
*/
public boolean isLenient() {
return lenient;
}
/**
* Return true to analyse wildcard.
*/
public boolean isAnalyzeWildcard() {
return analyzeWildcard;
}
/**
* Return lowercase expanded terms mode.
*/
public boolean isLowercaseExpandedTerms() {
return lowercaseExpandedTerms;
}
/**
* Return true if the default operator should be AND.
*/
public boolean isOperatorAnd() {
return operatorAnd;
}
/**
* Return the analyzer to use.
*/
public String getAnalyzer() {
return analyzer;
}
/**
* Return the fields.
*/
public String[] getFields() {
return fields;
}
/**
* Return the locale.
*/
public String getLocale() {
return locale;
}
/**
* Return the flags.
*/
public String getFlags() {
return flags;
}
/**
* Return the minimum should match.
*/
public String getMinShouldMatch() {
return minShouldMatch;
}
}
@@ -1,4 +0,0 @@
/**
* Provides text search expressions like Match, TextQueryString etc.
*/
package io.ebean.search;
-3
View File
@@ -30,13 +30,10 @@ module io.ebean.api {
exports io.ebean.config;
exports io.ebean.config.dbplatform;
exports io.ebean.event;
exports io.ebean.event.readaudit;
exports io.ebean.event.changelog;
exports io.ebean.common;
exports io.ebean.docstore;
exports io.ebean.plugin;
exports io.ebean.metric;
exports io.ebean.search;
exports io.ebean.service;
exports io.ebean.text;
exports io.ebean.text.json;
+26 -26
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</parent>
<name>ebean bom</name>
@@ -89,25 +89,25 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -125,13 +125,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -155,37 +155,37 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>kotlin-querybean-generator</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-redis</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-spring-txn</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<!-- platforms -->
@@ -193,79 +193,79 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-clickhouse</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-db2</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-h2</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-hana</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mariadb</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mysql</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-nuodb</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-oracle</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgres</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis-types</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlite</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlserver</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</parent>
<artifactId>ebean-core-type</artifactId>
@@ -16,7 +16,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
+6 -38
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</parent>
<artifactId>ebean-core</artifactId>
@@ -22,7 +22,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -46,19 +46,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.26.1-jakarta</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.13.1</version>
<version>14.0.0</version>
</dependency>
<!--
@@ -159,21 +147,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.26.1-jakarta</version>
<version>14.0.0</version>
<scope>test</scope>
</dependency>
@@ -234,26 +222,6 @@
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<doctitle>Ebean 12</doctitle>
<overview>src/main/java/io/ebean/overview.html</overview>
<excludePackageNames>io.ebeaninternal.*:io.ebeanservice:io.ebean.common:io.ebean.bean:io.ebean.service:io.ebean.metric:io.ebean.util:io.ebean.config.properties:io.ebean.config.dbplatform</excludePackageNames>
<linksource>true</linksource>
<overview>src/main/java/com/avaje/ebean/overview.html</overview>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
@@ -51,8 +51,4 @@ public interface LoadContext {
*/
void register(String path, BeanPropertyAssocMany<?> many, BeanCollection<?> bc);
/**
* Use soft-references for streaming queries, so unreachable entries can be garbage collected.
*/
void useReferences(boolean useReferences);
}
@@ -43,5 +43,4 @@ public interface LoadManyBuffer {
void configureQuery(SpiQuery<?> query);
boolean isUseDocStore();
}
@@ -99,7 +99,7 @@ public final class LoadManyRequest extends LoadRequest {
query.where().raw(extraWhere.replace("${ta}", "t0").replace("${mta}", "int_"));
}
query.setLazyLoadForParents(many);
many.addWhereParentIdIn(query, parentIdList(server), loadContext.isUseDocStore());
many.addWhereParentIdIn(query, parentIdList(server));
query.setPersistenceContext(loadContext.persistenceContext());
query.setLoadDescription(lazy ? "lazy" : "query", description());
if (lazy) {
@@ -3,6 +3,8 @@ package io.ebeaninternal.api;
import io.ebean.TxScope;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* Used internally to handle the scoping of transactions for methods.
@@ -47,6 +49,11 @@ public final class ScopeTrans {
private boolean nestedCommit;
private boolean nestedUseSavepoint;
/**
* The UserObjects when using in nested transactions.
*/
private Map<String, Object> userObjects;
public ScopeTrans(boolean rollbackOnChecked, boolean created, SpiTransaction transaction, TxScope txScope) {
this.rollbackOnChecked = rollbackOnChecked;
this.created = created;
@@ -218,4 +225,17 @@ public final class ScopeTrans {
return e instanceof RuntimeException || rollbackOnChecked;
}
public void putUserObject(String name, Object value) {
if (userObjects == null) {
userObjects = new HashMap<>();
}
userObjects.put(name, value);
}
public Object getUserObject(String name) {
if (userObjects == null) {
return null;
}
return userObjects.get(name);
}
}
@@ -2,7 +2,6 @@ package io.ebeaninternal.api;
import io.ebeaninternal.server.transaction.TransactionScopeManager;
import io.ebeaninternal.server.util.ArrayStack;
import jakarta.persistence.PersistenceException;
/**
@@ -173,4 +172,31 @@ public final class ScopedTransaction extends SpiTransactionProxy {
return current.caughtThrowable(e);
}
/**
* New user objects are always written to the current ScopeTrans.
*/
@Override
public void putUserObject(String name, Object value) {
current.putUserObject(name, value);
}
/**
* Returns the userObject in the stack, Herew we search
* the stack and return the first found userObject
*/
@Override
public Object getUserObject(String name) {
Object obj = current.getUserObject(name);
if (obj != null) {
return obj;
}
for (ScopeTrans trans : stack) {
obj = trans.getUserObject(name);
if (obj != null) {
return obj;
}
}
return transaction.getUserObject(name);
}
}
@@ -4,8 +4,6 @@ import io.avaje.lang.Nullable;
import io.ebean.*;
import io.ebean.bean.BeanCollectionLoader;
import io.ebean.bean.CallOrigin;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
import io.ebean.meta.MetricVisitor;
import io.ebean.plugin.SpiServer;
import io.ebeaninternal.api.SpiQuery.Type;
@@ -86,6 +84,11 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
*/
SpiTransactionManager transactionManager();
/**
* End the current transaction if it is active.
*/
void endTransaction();
/**
* Return all the descriptors.
*/
@@ -101,11 +104,6 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
*/
BeanDescriptor<?> descriptorById(String className);
/**
* Return BeanDescriptor using it's unique doc store queueId.
*/
BeanDescriptor<?> descriptorByQueueId(String queueId);
/**
* Return BeanDescriptors mapped to this table.
*/
@@ -190,17 +188,6 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
*/
boolean isSupportedType(java.lang.reflect.Type genericType);
/**
* Return the ReadAuditLogger to use for logging all read audit events.
*/
ReadAuditLogger readAuditLogger();
/**
* Return the ReadAuditPrepare used to populate the read audit events with
* user context information (user id, user ip address etc).
*/
ReadAuditPrepare readAuditPrepare();
/**
* Return the DataTimeZone to use when reading/writing timestamps via JDBC.
*/
@@ -349,10 +336,6 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
<T> FutureRowCount<T> findFutureCount(SpiQuery<T> query);
<T> FutureIds<T> findFutureIds(SpiQuery<T> query);
<T> FutureList<T> findFutureList(SpiQuery<T> query);
<T> PagedList<T> findPagedList(SpiQuery<T> query);
<T> Set<T> findSet(SpiQuery<T> query);
@@ -3,9 +3,6 @@ package io.ebeaninternal.api;
import io.ebean.Expression;
import io.ebean.event.BeanQueryRequest;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.expression.DocQueryContext;
import java.io.IOException;
/**
@@ -21,16 +18,6 @@ public interface SpiExpression extends Expression {
*/
void simplify();
/**
* Write the expression as an elastic search expression.
*/
void writeDocQuery(DocQueryContext context) throws IOException;
/**
* Return the nested path for this expression.
*/
String nestedPath(BeanDescriptor<?> desc);
/**
* Process "Many" properties populating ManyWhereJoins.
* <p>
@@ -2,7 +2,6 @@ package io.ebeaninternal.api;
import io.ebean.ExpressionList;
import io.ebean.Junction;
import io.ebeaninternal.server.expression.DocQueryContext;
import java.io.IOException;
import java.util.List;
@@ -32,11 +31,6 @@ public interface SpiExpressionList<T> extends ExpressionList<T>, SpiExpression {
*/
boolean isEmpty();
/**
* Write the top level where expressions taking into account possible extra idEquals expression.
*/
void writeDocQuery(DocQueryContext context, SpiExpression idEquals) throws IOException;
/**
* Apply firstRow maxRows limits on the filterMany query.
*/
@@ -1,17 +1,10 @@
package io.ebeaninternal.api;
import io.ebean.Junction;
import io.ebeaninternal.server.expression.DocQueryContext;
import java.io.IOException;
/**
* SPI methods for Junction.
*/
public interface SpiJunction<T> extends Junction<T> {
/**
* Write the Junction taking into account it is implied.
*/
void writeDocQueryJunction(DocQueryContext context) throws IOException;
}
@@ -11,7 +11,6 @@ import io.ebean.Query;
import io.ebean.bean.CallOrigin;
import io.ebean.bean.ObjectGraphNode;
import io.ebean.bean.PersistenceContext;
import io.ebean.event.readaudit.ReadEvent;
import io.ebean.plugin.BeanType;
import io.ebeaninternal.server.autotune.ProfilingListener;
import io.ebeaninternal.server.core.SpiOrmQueryRequest;
@@ -170,11 +169,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
*/
SOFT_DELETED(false),
/**
* Query runs against draft tables.
*/
DRAFT(false),
/**
* Query runs against current data (normal).
*/
@@ -292,17 +286,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
*/
SpiRawSql rawSql();
/**
* Return true if this query should be executed against the doc store.
*/
boolean isUseDocStore();
/**
* For doc store query return the document index name to search against.
* This is for partitioned indexes (like daily logstash indexes etc).
*/
String getDocIndexName();
/**
* Return the PersistenceContextScope that this query should use.
* <p>
@@ -377,11 +360,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
*/
boolean isAsOfQuery();
/**
* Return true if this is a 'As Draft' query.
*/
boolean isAsDraft();
/**
* Return true if this query includes soft deleted rows.
*/
@@ -510,11 +488,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
*/
NaturalKeyBindParam naturalKeyBindParam();
/**
* Prepare the query for docstore execution with nested paths.
*/
void prepareDocNested();
/**
* Set the query to be a delete query.
*/
@@ -730,11 +703,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
*/
SpiExpressionList<T> havingExpressions();
/**
* Return the text expressions.
*/
SpiExpressionList<T> textExpression();
/**
* Returns true if either firstRow or maxRows has been set.
*/
@@ -801,11 +769,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
*/
boolean tuneFetchProperties(OrmQueryDetail detail);
/**
* If this is a RawSql based entity set the default RawSql if not set.
*/
void setDefaultRawSqlIfRequired();
/**
* Set to true if this query has been tuned by autoTune.
*/
@@ -883,21 +846,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
*/
int bufferFetchSizeHint();
/**
* Return true if read auditing is disabled on this query.
*/
boolean isDisableReadAudit();
/**
* Set the readEvent for future queries (as prepared in foreground thread).
*/
void setFutureFetchAudit(ReadEvent event);
/**
* Read the readEvent for future queries (null otherwise).
*/
ReadEvent futureFetchAudit();
/**
* Return the base table to use if user defined on the query.
*/
@@ -9,7 +9,6 @@ import io.ebeaninternal.server.core.PersistDeferredRelationship;
import io.ebeaninternal.server.core.PersistRequestBean;
import io.ebeaninternal.server.persist.BatchControl;
import io.ebeaninternal.server.transaction.ProfileStream;
import io.ebeanservice.docstore.api.DocStoreTransaction;
import jakarta.persistence.PersistenceException;
import java.sql.Connection;
@@ -103,19 +102,6 @@ public interface SpiTransaction extends Transaction {
*/
Boolean isUpdateAllLoadedProperties();
/**
* Return the batchSize specifically set for this transaction or 0.
* <p>
* Returning 0 implies to use the system wide default batch size.
*/
DocStoreMode docStoreMode();
/**
* Return the batch size to us for ElasticSearch Bulk API calls
* as a result of this transaction.
*/
int getDocStoreBatchSize();
/**
* Return the batchSize specifically set for this transaction or 0.
* <p>
@@ -287,11 +273,6 @@ public interface SpiTransaction extends Transaction {
*/
void sendChangeLog(ChangeSet changeSet);
/**
* Return a document store transaction.
*/
DocStoreTransaction docStoreTransaction();
/**
* Set the current Tenant Id.
*/
@@ -2,14 +2,12 @@ package io.ebeaninternal.api;
import io.ebean.ProfileLocation;
import io.ebean.TransactionCallback;
import io.ebean.annotation.DocStoreMode;
import io.ebean.event.changelog.BeanChange;
import io.ebean.event.changelog.ChangeSet;
import io.ebeaninternal.server.core.PersistDeferredRelationship;
import io.ebeaninternal.server.core.PersistRequestBean;
import io.ebeaninternal.server.persist.BatchControl;
import io.ebeaninternal.server.transaction.ProfileStream;
import io.ebeanservice.docstore.api.DocStoreTransaction;
import jakarta.persistence.PersistenceException;
import java.sql.Connection;
@@ -112,32 +110,6 @@ public abstract class SpiTransactionProxy implements SpiTransaction {
return transaction.tenantId();
}
@Override
public DocStoreTransaction docStoreTransaction() {
return transaction.docStoreTransaction();
}
@Override
public DocStoreMode docStoreMode() {
return transaction.docStoreMode();
}
@Override
public void setDocStoreMode(DocStoreMode mode) {
transaction.setDocStoreMode(mode);
}
@Override
public int getDocStoreBatchSize() {
return transaction.getDocStoreBatchSize();
}
@Override
public void setDocStoreBatchSize(int batchSize) {
transaction.setDocStoreBatchSize(batchSize);
}
@Override
public boolean isLogSql() {
return transaction.isLogSql();
@@ -6,7 +6,6 @@ import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.BeanDescriptorManager;
import io.ebeaninternal.server.transaction.DeleteByIdMap;
import io.ebeaninternal.server.transaction.TransactionManager;
import io.ebeanservice.docstore.api.DocStoreUpdates;
import java.io.Serializable;
import java.util.ArrayList;
@@ -125,18 +124,6 @@ public final class TransactionEvent implements Serializable {
return changeSet;
}
/**
* Add any relevant PersistRequestBean's to DocStoreUpdates for later processing.
*/
public void addDocStoreUpdates(DocStoreUpdates docStoreUpdates) {
List<PersistRequestBean<?>> requests = listenerNotify();
if (requests != null) {
for (PersistRequestBean<?> persistRequestBean : requests) {
persistRequestBean.addDocStoreUpdates(docStoreUpdates);
}
}
}
/**
* Return the CacheChangeSet that we add cache notification messages to.
* <p>
@@ -15,7 +15,6 @@ public final class CachedBeanData implements Externalizable {
private long whenCreated;
private long version;
private String discValue;
private Map<String, Object> data;
/**
* The sharable bean is effectively transient (near cache only).
@@ -25,10 +24,9 @@ public final class CachedBeanData implements Externalizable {
/**
* Construct from a loaded bean.
*/
public CachedBeanData(Object sharableBean, String discValue, Map<String, Object> data, long version) {
public CachedBeanData(Object sharableBean, Map<String, Object> data, long version) {
this.whenCreated = System.currentTimeMillis();
this.sharableBean = sharableBean;
this.discValue = discValue;
this.data = data;
this.version = version;
}
@@ -43,11 +41,6 @@ public final class CachedBeanData implements Externalizable {
public void writeExternal(ObjectOutput out) throws IOException {
out.writeLong(version);
out.writeLong(whenCreated);
boolean hasDisc = discValue != null;
out.writeBoolean(hasDisc);
if (hasDisc) {
out.writeUTF(discValue);
}
out.writeInt(data.size());
for (Map.Entry<String, Object> entry : data.entrySet()) {
out.writeUTF(entry.getKey());
@@ -59,9 +52,6 @@ public final class CachedBeanData implements Externalizable {
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
version = in.readLong();
whenCreated = in.readLong();
if (in.readBoolean()) {
discValue = in.readUTF();
}
data = new LinkedHashMap<>();
int count = in.readInt();
for (int i = 0; i < count; i++) {
@@ -85,7 +75,7 @@ public final class CachedBeanData implements Externalizable {
Map<String, Object> copy = new HashMap<>();
copy.putAll(data);
copy.putAll(changes);
return new CachedBeanData(null, discValue, copy, version);
return new CachedBeanData(null, copy, version);
}
/**
@@ -102,13 +92,6 @@ public final class CachedBeanData implements Externalizable {
return version;
}
/**
* Return the raw discriminator value.
*/
public String getDiscValue() {
return discValue;
}
/**
* Return a sharable (immutable read only) bean. Near cache only use.
*/
@@ -41,7 +41,7 @@ public final class CachedBeanDataFromBean {
long version = desc.getVersion(bean);
EntityBean sharableBean = createSharableBean(desc, bean, ebi);
return new CachedBeanData(sharableBean, desc.discValue(), data, version);
return new CachedBeanData(sharableBean, data, version);
}
private static EntityBean createSharableBean(BeanDescriptor<?> desc, EntityBean bean, EntityBeanIntercept beanEbi) {
@@ -14,9 +14,6 @@ public final class CachedBeanDataToBean {
// any future lazy loading skips L2 bean cache
ebi.setLoadedFromCache(true);
BeanProperty idProperty = desc.idProperty();
if (desc.inheritInfo() != null) {
desc = desc.inheritInfo().readType(bean.getClass()).desc();
}
if (idProperty != null) {
// load the id property
loadProperty(bean, cacheBeanData, ebi, idProperty, context);
@@ -1,54 +0,0 @@
package io.ebeaninternal.server.cache;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
/**
* Bean Id value plus discriminator type.
* <p>
* Put into L2 cache such that we know the type of a bean with inheritance.
*/
public final class CachedBeanId implements Externalizable {
private String discValue;
private Object id;
public CachedBeanId(String discValue, Object id) {
this.discValue = discValue;
this.id = id;
}
/**
* Construct from serialisation.
*/
public CachedBeanId() {
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(discValue);
out.writeObject(id);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
discValue = in.readUTF();
id = in.readObject();
}
@Override
public String toString() {
return discValue + ":" + id;
}
public String getDiscValue() {
return discValue;
}
public Object getId() {
return id;
}
}
@@ -178,12 +178,11 @@ final class DefaultBeanLoader {
desc.contextPut(pc, id, bean);
ebi.setPersistenceContext(pc);
}
boolean draft = desc.isDraftInstance(bean);
if (embeddedOwnerIndex == -1) {
if (desc.lazyLoadMany(ebi)) {
return;
}
if (!draft && Mode.LAZYLOAD_BEAN == mode && desc.isBeanCaching()) {
if (Mode.LAZYLOAD_BEAN == mode && desc.isBeanCaching()) {
// lazy loading and the bean cache is active
if (desc.cacheBeanLoad(bean, ebi, id, pc)) {
return;
@@ -192,9 +191,7 @@ final class DefaultBeanLoader {
}
SpiQuery<?> query = server.createQuery(desc.type());
query.setLazyLoadProperty(ebi.lazyLoadProperty());
if (draft) {
query.asDraft();
} else if (mode == SpiQuery.Mode.LAZYLOAD_BEAN && desc.isSoftDelete()) {
if (mode == SpiQuery.Mode.LAZYLOAD_BEAN && desc.isSoftDelete()) {
query.setIncludeSoftDeletes();
}
if (embeddedOwnerIndex > -1) {
@@ -92,16 +92,12 @@ public final class DefaultContainer implements SpiContainer {
BootupClasses bootupClasses = bootupClasses(config);
boolean online = true;
if (config.isDocStoreOnly()) {
config.databasePlatform(new DatabasePlatform());
} else {
TenantMode tenantMode = config.getTenantMode();
if (TenantMode.DB != tenantMode) {
setDataSource(config);
if (!tenantMode.isDynamicDataSource()) {
// check the autoCommit and Transaction Isolation
online = checkDataSource(config);
}
TenantMode tenantMode = config.getTenantMode();
if (TenantMode.DB != tenantMode) {
setDataSource(config);
if (!tenantMode.isDynamicDataSource()) {
// check the autoCommit and Transaction Isolation
online = checkDataSource(config);
}
}
@@ -13,8 +13,6 @@ import io.ebean.config.*;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.event.BeanPersistController;
import io.ebean.event.ShutdownManager;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
import io.ebean.meta.*;
import io.ebean.migration.auto.AutoMigrationRunner;
import io.ebean.plugin.BeanType;
@@ -30,11 +28,9 @@ import io.ebeaninternal.server.core.timezone.DataTimeZone;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.BeanDescriptorManager;
import io.ebeaninternal.server.deploy.BeanProperty;
import io.ebeaninternal.server.deploy.InheritInfo;
import io.ebeaninternal.server.dto.DtoBeanDescriptor;
import io.ebeaninternal.server.dto.DtoBeanManager;
import io.ebeaninternal.server.el.ElFilter;
import io.ebeaninternal.server.grammer.EqlParser;
import io.ebeaninternal.server.query.*;
import io.ebeaninternal.server.querydefn.*;
import io.ebeaninternal.server.rawsql.SpiRawSql;
@@ -43,7 +39,6 @@ import io.ebeaninternal.server.transaction.RemoteTransactionEvent;
import io.ebeaninternal.server.transaction.TransactionManager;
import io.ebeaninternal.util.ParamTypeHelper;
import io.ebeaninternal.util.ParamTypeHelper.TypeInfo;
import io.ebeanservice.docstore.api.DocStoreIntegration;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.NonUniqueResultException;
@@ -93,8 +88,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
private final DtoBeanManager dtoBeanManager;
private final BeanDescriptorManager descriptorManager;
private final AutoTuneService autoTuneService;
private final ReadAuditPrepare readAuditPrepare;
private final ReadAuditLogger readAuditLogger;
private final CQueryEngine cqueryEngine;
private final List<Plugin> serverPlugins;
private final SpiDdlGenerator ddlGenerator;
@@ -104,7 +97,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
private final DefaultBeanLoader beanLoader;
private final EncryptKeyManager encryptKeyManager;
private final SpiJsonContext jsonContext;
private final DocumentStore documentStore;
private final MetaInfoManager metaInfoManager;
private final CurrentTenantProvider currentTenantProvider;
private final SpiLogManager logManager;
@@ -146,16 +138,12 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
this.relationalQueryEngine = config.createRelationalQueryEngine();
this.dtoQueryEngine = config.createDtoQueryEngine();
this.autoTuneService = config.createAutoTuneService(this);
this.readAuditPrepare = config.getReadAuditPrepare();
this.readAuditLogger = config.getReadAuditLogger();
this.beanLoader = new DefaultBeanLoader(this);
this.jsonContext = config.createJsonContext(this);
this.dataTimeZone = config.getDataTimeZone();
this.clockService = config.getClockService();
DocStoreIntegration docStoreComponents = config.createDocStoreIntegration(this);
this.transactionManager = config.createTransactionManager(this, docStoreComponents.updateProcessor());
this.documentStore = docStoreComponents.documentStore();
this.transactionManager = config.createTransactionManager(this);
this.queryPlanManager = config.initQueryPlanManager(transactionManager);
this.metaInfoManager = new DefaultMetaInfoManager(this, this.config.getMetricNaming());
this.serverPlugins = config.getPlugins();
@@ -189,9 +177,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
* Execute all the plugins with an online flag indicating the DB is up or not.
*/
public void executePlugins(boolean online) {
if (!config.isDocStoreOnly()) {
ddlGenerator.execute(online);
}
ddlGenerator.execute(online);
for (Plugin plugin : serverPlugins) {
plugin.online(online);
}
@@ -283,16 +269,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return transactionManager.readOnlyDataSource();
}
@Override
public ReadAuditPrepare readAuditPrepare() {
return readAuditPrepare;
}
@Override
public ReadAuditLogger readAuditLogger() {
return readAuditLogger;
}
/**
* Run any initialisation required before registering with the ClusterManager.
*/
@@ -618,25 +594,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return (T) existing;
}
}
InheritInfo inheritInfo = desc.inheritInfo();
if (inheritInfo == null || inheritInfo.isConcrete()) {
return (T) desc.contextRef(pc, null, false, id);
}
return referenceFindOne(type, id, desc);
}
private <T> T referenceFindOne(Class<T> type, Object id, BeanDescriptor<?> desc) {
BeanProperty idProp = desc.idProperty();
if (idProp == null) {
throw new PersistenceException("No ID properties for this type? " + desc);
}
// we actually need to do a query because we don't know the type without the discriminator
// value, just select the id property and discriminator column (auto added)
T bean = find(type).select(idProp.name()).setId(id).findOne();
if (bean == null) {
throw new EntityNotFoundException("Could not find reference bean " + id + " for " + desc);
}
return bean;
return (T) desc.contextRef(pc, null, false, id);
}
@Override
@@ -756,16 +714,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
currentTransaction().flush();
}
@Override
public void commitTransaction() {
currentTransaction().commit();
}
@Override
public void rollbackTransaction() {
currentTransaction().rollback();
}
@Override
public void endTransaction() {
Transaction transaction = transactionManager.inScope();
@@ -848,29 +796,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return query;
}
@Override
public <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
BeanDescriptor<T> desc = desc(beanType);
String named = desc.namedQuery(namedQuery);
if (named != null) {
return createQuery(beanType, named);
}
SpiRawSql rawSql = desc.namedRawSql(namedQuery);
if (rawSql != null) {
DefaultOrmQuery<T> query = createQuery(beanType);
query.setRawSql(rawSql);
return query;
}
throw new PersistenceException("No named query called " + namedQuery + " for bean:" + beanType.getName());
}
@Override
public <T> DefaultOrmQuery<T> createQuery(Class<T> beanType, String eql) {
DefaultOrmQuery<T> query = createQuery(beanType);
EqlParser.parse(eql, query);
return query;
}
@Override
public <T> DefaultOrmQuery<T> createQuery(Class<T> beanType) {
return new DefaultOrmQuery<>(desc(beanType), this, expressionFactory);
@@ -887,16 +812,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return new DefaultDtoQuery<>(this, descriptor, sql.trim());
}
@Override
public <T> DtoQuery<T> createNamedDtoQuery(Class<T> dtoType, String namedQuery) {
DtoBeanDescriptor<T> descriptor = dtoBeanManager.descriptor(dtoType);
String sql = descriptor.namedRawSql(namedQuery);
if (sql == null) {
throw new PersistenceException("No named query called " + namedQuery + " for bean:" + dtoType.getName());
}
return new DefaultDtoQuery<>(this, descriptor, sql);
}
@Override
public <T> DtoQuery<T> findDto(Class<T> dtoType, SpiQuery<?> ormQuery) {
DtoBeanDescriptor<T> descriptor = dtoBeanManager.descriptor(dtoType);
@@ -960,7 +875,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
transaction = currentServerTransaction();
}
if (!query.isRawSql()) {
query.setDefaultRawSqlIfRequired();
if (!query.isAutoTunable() || !autoTuneService.tuneQuery(query)) {
// use deployment FetchType.LAZY/EAGER annotations
// to define the 'default' select clause
@@ -1043,9 +957,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
SpiOrmQueryRequest<T> request = buildQueryRequest(query);
request.prepareQuery();
if (request.isUseDocStore()) {
return docStore().find(request);
}
try {
request.initTransIfRequired();
return (T) request.findId();
@@ -1289,60 +1200,12 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return queryFuture;
}
@Override
public <T> FutureIds<T> findFutureIds(SpiQuery<T> query) {
SpiQuery<T> copy = query.copy();
copy.usingFuture();
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(SpiQuery<T> query) {
SpiQuery<T> spiQuery = query.copy();
spiQuery.usingFuture();
// FutureList query always run in it's own persistence content
spiQuery.setPersistenceContext(new DefaultPersistenceContext());
if (!spiQuery.isDisableReadAudit()) {
BeanDescriptor<T> desc = descriptorManager.descriptor(spiQuery.getBeanType());
desc.readAuditFutureList(spiQuery);
}
// Create a new transaction solely to execute the findList() at some future time
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(SpiQuery<T> query) {
int maxRows = query.getMaxRows();
if (maxRows == 0) {
throw new PersistenceException("maxRows must be specified for findPagedList() query");
}
if (query.isUseDocStore()) {
return docStore().findPagedList(createQueryRequest(Type.LIST, query));
}
return new LimitOffsetPagedList<>(this, query);
}
@@ -1370,10 +1233,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
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;
}
request.initTransIfRequired();
request.findEach(consumer);
// no try finally - findEach guarantee's cleanup of the transaction if required
@@ -1382,10 +1241,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
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;
// }
request.initTransIfRequired();
request.findEach(batch, consumer);
// no try finally - findEach guarantee's cleanup of the transaction if required
@@ -1394,10 +1249,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
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;
}
request.initTransIfRequired();
request.findEachWhile(consumer);
// no try finally - findEachWhile guarantee's cleanup of the transaction if required
@@ -1432,9 +1283,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
if (result != null) {
return (List<T>) result;
}
if (request.isUseDocStore()) {
return docStore().findList(request);
}
try {
request.initTransIfRequired();
return request.findList();
@@ -1703,54 +1551,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}, transaction);
}
@Override
public <T> List<T> publish(Query<T> query, @Nullable Transaction transaction) {
return executeInTrans((txn) -> persister.publish(query, txn), transaction);
}
@Nullable
@Override
public <T> T publish(Class<T> beanType, Object id) {
return publish(beanType, id, null);
}
@Override
public <T> List<T> publish(Query<T> query) {
return publish(query, null);
}
@Nullable
@Override
public <T> T publish(Class<T> beanType, Object id, @Nullable Transaction transaction) {
Query<T> query = find(beanType).setId(id);
List<T> liveBeans = publish(query, transaction);
return (liveBeans.size() == 1) ? liveBeans.get(0) : null;
}
@Override
public <T> List<T> draftRestore(Query<T> query, @Nullable Transaction transaction) {
return executeInTrans((txn) -> persister.draftRestore(query, txn), transaction);
}
@Nullable
@Override
public <T> T draftRestore(Class<T> beanType, Object id, @Nullable Transaction transaction) {
Query<T> query = find(beanType).setId(id);
List<T> beans = draftRestore(query, transaction);
return (beans.size() == 1) ? beans.get(0) : null;
}
@Nullable
@Override
public <T> T draftRestore(Class<T> beanType, Object id) {
return draftRestore(beanType, id, null);
}
@Override
public <T> List<T> draftRestore(Query<T> query) {
return draftRestore(query, null);
}
private EntityBean checkEntityBean(Object bean) {
return (EntityBean) Objects.requireNonNull(bean);
}
@@ -2059,16 +1859,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return descriptorManager.beanTypes(tableName);
}
@Override
public BeanType<?> beanTypeForQueueId(String queueId) {
return descriptorByQueueId(queueId);
}
@Override
public BeanDescriptor<?> descriptorByQueueId(String queueId) {
return descriptorManager.descriptorByQueueId(queueId);
}
/**
* Return the SPI bean types for the given bean class.
*/
@@ -2175,11 +1965,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return callStackFactory.createCallOrigin();
}
@Override
public DocumentStore docStore() {
return documentStore;
}
@Override
public JsonContext json() {
// immutable thread safe so return shared instance
@@ -1,69 +0,0 @@
package io.ebeaninternal.server.core;
import io.ebeaninternal.api.CoreLog;
import io.ebeaninternal.server.dto.DtoNamedQueries;
import io.ebeaninternal.xmapping.api.XmapDto;
import io.ebeaninternal.xmapping.api.XmapEbean;
import io.ebeaninternal.xmapping.api.XmapRawSql;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static java.lang.System.Logger.Level.ERROR;
/**
* Reads the Xml deployment information.
*/
final class InternalConfigXmlMap {
private final List<XmapEbean> xmlEbeanList;
private final ClassLoader classLoader;
private final Map<Class<?>, DtoNamedQueries> dtoNamedQueries = new HashMap<>();
InternalConfigXmlMap(List<XmapEbean> xmlEbeanList, ClassLoader classLoader) {
this.xmlEbeanList = xmlEbeanList;
this.classLoader = classLoader;
initDtoMapping();
}
void initDtoMapping() {
if (xmlEbeanList != null) {
for (XmapEbean mapping : xmlEbeanList) {
List<XmapDto> dtoList = mapping.getDto();
for (XmapDto dto : dtoList) {
readDtoMapping(dto);
}
}
}
}
/**
* Return the XML deployment information for entity beans.
*/
List<XmapEbean> xmlDeployment() {
return xmlEbeanList;
}
/**
* Return the named queries for Dto beans.
*/
Map<Class<?>, DtoNamedQueries> readDtoMapping() {
return dtoNamedQueries;
}
private void readDtoMapping(XmapDto dto) {
Class<?> dtoClass;
try {
dtoClass = Class.forName(dto.getClazz(), false, classLoader);
} catch (Exception e) {
CoreLog.internal.log(ERROR, "Could not load dto bean class " + dto.getClazz() + " for ebean xml entry");
return;
}
DtoNamedQueries namedQueries = dtoNamedQueries.computeIfAbsent(dtoClass, aClass -> new DtoNamedQueries());
for (XmapRawSql sql : dto.getRawSql()) {
namedQueries.addRawSql(sql.getName(), sql.getQuery());
}
}
}
@@ -11,8 +11,6 @@ import io.ebean.config.dbplatform.DbHistorySupport;
import io.ebean.event.changelog.ChangeLogListener;
import io.ebean.event.changelog.ChangeLogPrepare;
import io.ebean.event.changelog.ChangeLogRegister;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
import io.ebean.plugin.Plugin;
import io.ebean.plugin.SpiServer;
import io.ebeaninternal.api.*;
@@ -29,7 +27,6 @@ import io.ebeaninternal.server.core.timezone.*;
import io.ebeaninternal.server.deploy.BeanDescriptorManager;
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedPropertyFactory;
import io.ebeaninternal.server.deploy.parse.DeployCreateProperties;
import io.ebeaninternal.server.deploy.parse.DeployInherit;
import io.ebeaninternal.server.deploy.parse.DeployUtil;
import io.ebeaninternal.server.dto.DtoBeanManager;
import io.ebeaninternal.server.expression.DefaultExpressionFactory;
@@ -42,18 +39,10 @@ import io.ebeaninternal.server.persist.DefaultPersister;
import io.ebeaninternal.server.persist.platform.MultiValueBind;
import io.ebeaninternal.server.persist.platform.PostgresMultiValueBind;
import io.ebeaninternal.server.query.*;
import io.ebeaninternal.server.readaudit.DefaultReadAuditLogger;
import io.ebeaninternal.server.readaudit.DefaultReadAuditPrepare;
import io.ebeaninternal.server.json.DJsonContext;
import io.ebeaninternal.server.transaction.*;
import io.ebeaninternal.server.type.DefaultTypeManager;
import io.ebeaninternal.server.type.TypeManager;
import io.ebeaninternal.xmapping.api.XmapEbean;
import io.ebeaninternal.xmapping.api.XmapService;
import io.ebeanservice.docstore.api.DocStoreFactory;
import io.ebeanservice.docstore.api.DocStoreIntegration;
import io.ebeanservice.docstore.api.DocStoreUpdateProcessor;
import io.ebeanservice.docstore.none.NoneDocStoreFactory;
import java.util.*;
@@ -72,7 +61,6 @@ public final class InternalConfiguration {
private final DatabaseBuilder.Settings config;
private final BootupClasses bootupClasses;
private final DatabasePlatform databasePlatform;
private final DeployInherit deployInherit;
private final TypeManager typeManager;
private final DtoBeanManager dtoBeanManager;
private final ClockService clockService;
@@ -89,7 +77,6 @@ public final class InternalConfiguration {
private final ExpressionFactory expressionFactory;
private final SpiBackgroundExecutor backgroundExecutor;
private final JsonFactory jsonFactory;
private final DocStoreFactory docStoreFactory;
private final List<Plugin> plugins = new ArrayList<>();
private final MultiValueBind multiValueBind;
private final SpiLogManager logManager;
@@ -106,7 +93,6 @@ public final class InternalConfiguration {
this.clockService = new ClockService(config.settings().getClock());
this.tableModState = new TableModState();
this.logManager = initLogManager();
this.docStoreFactory = initDocStoreFactory(service(DocStoreFactory.class));
this.jsonFactory = config.getJsonFactory();
this.clusterManager = clusterManager;
this.backgroundExecutor = backgroundExecutor;
@@ -115,32 +101,24 @@ public final class InternalConfiguration {
this.expressionFactory = initExpressionFactory(config);
this.typeManager = new DefaultTypeManager(config, bootupClasses);
this.multiValueBind = createMultiValueBind(databasePlatform.platform());
this.deployInherit = new DeployInherit(bootupClasses);
this.deployCreateProperties = new DeployCreateProperties(typeManager);
this.deployUtil = new DeployUtil(typeManager, config);
this.serverCachePlugin = initServerCachePlugin();
this.cacheManager = initCacheManager();
final InternalConfigXmlMap xmlMap = initExternalMapping();
this.dtoBeanManager = new DtoBeanManager(typeManager, xmlMap.readDtoMapping());
this.dtoBeanManager = new DtoBeanManager(typeManager);
this.beanDescriptorManager = new BeanDescriptorManager(this);
Map<String, String> asOfTableMapping = beanDescriptorManager.deploy(xmlMap.xmlDeployment());
Map<String, String> draftTableMap = beanDescriptorManager.draftTableMap();
Map<String, String> asOfTableMapping = beanDescriptorManager.deploy();
beanDescriptorManager.scheduleBackgroundTrim();
this.dataTimeZone = initDataTimeZone();
this.binder = getBinder(typeManager, databasePlatform, dataTimeZone);
this.cQueryEngine = new CQueryEngine(config, databasePlatform, binder, asOfTableMapping, draftTableMap);
this.cQueryEngine = new CQueryEngine(config, databasePlatform, binder, asOfTableMapping);
}
public boolean isJacksonCorePresent() {
return jacksonCorePresent;
}
private InternalConfigXmlMap initExternalMapping() {
final List<XmapEbean> xmEbeans = readExternalMapping();
return new InternalConfigXmlMap(xmEbeans, config.getClassLoadConfig().getClassLoader());
}
private <S> S service(Class<S> cls) {
S service = config.getServiceObject(cls);
if (service != null) {
@@ -150,14 +128,6 @@ public final class InternalConfiguration {
}
}
private List<XmapEbean> readExternalMapping() {
final XmapService xmapService = service(XmapService.class);
if (xmapService == null) {
return Collections.emptyList();
}
return xmapService.read(config.getClassLoadConfig().getClassLoader(), config.getMappingLocations());
}
private SpiLogManager initLogManager() {
// allow plugin - i.e. capture executed SQL for testing/asserts
SpiLoggerFactory loggerFactory = service(SpiLoggerFactory.class);
@@ -178,17 +148,6 @@ public final class InternalConfiguration {
return new DefaultExpressionFactory(config.isExpressionEqualsWithNullAsNoop(), nativeIlike);
}
private DocStoreFactory initDocStoreFactory(DocStoreFactory service) {
return service == null ? new NoneDocStoreFactory() : service;
}
/**
* Return the doc store factory.
*/
public DocStoreFactory getDocStoreFactory() {
return docStoreFactory;
}
ClockService getClockService() {
return clockService;
}
@@ -245,22 +204,6 @@ public final class InternalConfiguration {
return plugin((listener != null) ? listener : jacksonCorePresent ? new DefaultChangeLogListener() : null);
}
/**
* Return the ReadAuditLogger implementation to use.
*/
ReadAuditLogger getReadAuditLogger() {
ReadAuditLogger found = bootupClasses.getReadAuditLogger();
return plugin(found != null ? found : jacksonCorePresent ? new DefaultReadAuditLogger() : null);
}
/**
* Return the ReadAuditPrepare implementation to use.
*/
ReadAuditPrepare getReadAuditPrepare() {
ReadAuditPrepare found = bootupClasses.getReadAuditPrepare();
return plugin(found != null ? found : new DefaultReadAuditPrepare());
}
/**
* For 'As Of' queries return the number of bind variables per predicate.
*/
@@ -347,10 +290,6 @@ public final class InternalConfiguration {
return beanDescriptorManager;
}
public DeployInherit getDeployInherit() {
return deployInherit;
}
public DeployCreateProperties getDeployCreateProperties() {
return deployCreateProperties;
}
@@ -372,29 +311,19 @@ public final class InternalConfiguration {
return new GeneratedPropertyFactory(offlineMode, config, bootupClasses.getIdGenerators());
}
/**
* Create the DocStoreIntegration components for the given server.
*/
DocStoreIntegration createDocStoreIntegration(SpiServer server) {
return plugin(docStoreFactory.create(server));
}
/**
* Create the TransactionManager taking into account autoCommit mode.
*/
TransactionManager createTransactionManager(SpiServer server, DocStoreUpdateProcessor indexUpdateProcessor) {
TransactionManager createTransactionManager(SpiServer server) {
TransactionScopeManager scopeManager = createTransactionScopeManager();
boolean notifyL2CacheInForeground = cacheManager.isLocalL2Caching() || config.isNotifyL2CacheInForeground();
TransactionManagerOptions options =
new TransactionManagerOptions(server, notifyL2CacheInForeground, config, scopeManager, clusterManager, backgroundExecutor,
indexUpdateProcessor, beanDescriptorManager, dataSource(), profileHandler(), logManager,
beanDescriptorManager, dataSource(), profileHandler(), logManager,
tableModState, cacheNotify, clockService);
if (config.isDocStoreOnly()) {
return new DocStoreTransactionManager(options);
}
return new TransactionManager(options);
}
@@ -114,7 +114,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return server.databasePlatform().escapeLikeString(value);
}
@Override
public void executeSecondaryQueries(boolean forEach) {
// disable lazy loading leaves loadContext null
if (loadContext != null) {
@@ -148,11 +147,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return loadContext;
}
@Override
public boolean isUseDocStore() {
return query.isUseDocStore();
}
/**
* Run BeanQueryAdapter preQuery() if needed.
*/
@@ -225,7 +219,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
persistenceContext.beginIterate();
}
loadContext = new DLoadContext(this, secondaryQueries);
loadContext.useReferences(Type.ITERATE == query.type());
}
/**
@@ -248,23 +241,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
}
}
/**
* Return the JsonReadOptions taking into account lazy loading and persistence context.
*/
@Override
public JsonReadOptions createJsonReadOptions() {
persistenceContext = persistenceContext(query, transaction);
if (query.persistenceContext() == null) {
query.setPersistenceContext(persistenceContext);
}
JsonReadOptions jsonRead = new JsonReadOptions();
jsonRead.setPersistenceContext(persistenceContext);
if (!query.isDisableLazyLoading()) {
loadContext = new DLoadContext(this, secondaryQueries);
jsonRead.setLoadContext(loadContext);
}
return jsonRead;
}
/**
* Get the TransactionContext either explicitly set on the query or
@@ -639,17 +615,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
}
Object cached = beanDescriptor.queryCacheGet(cacheKey);
if (cached != null && isAuditReads() && readAuditQueryType()) {
if (cached instanceof BeanCollection) {
// raw sql can't use L2 cache so normal queries only in here
Collection<T> actualDetails = ((BeanCollection<T>) cached).actualDetails();
List<Object> ids = new ArrayList<>(actualDetails.size());
for (T bean : actualDetails) {
ids.add(beanDescriptor.idForJson(bean));
}
beanDescriptor.readAuditMany(queryPlanKey.partialKey(), "l2-query-cache", ids);
}
}
if (Boolean.FALSE.equals(query.isReadOnly())) {
// return shallow copies if readonly is explicitly set to false
if (cached instanceof BeanCollection) {
@@ -665,24 +630,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return cached;
}
/**
* Return true if the query type contains bean data (not just ids etc) and hence we want to include
* it in read auditing. Return false for row count and find ids queries.
*/
private boolean readAuditQueryType() {
Type type = query.type();
switch (type) {
case BEAN:
case ITERATE:
case LIST:
case SET:
case MAP:
return true;
default:
return false;
}
}
public void putToQueryCache(Object result) {
beanDescriptor.queryCachePut(cacheKey, new QueryCacheEntry(result, dependentTables, transaction.startNanoTime()));
}
@@ -709,15 +656,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return (batchSize > 0) ? batchSize : server.lazyLoadBatchSize();
}
/**
* Return true if read auditing is on for this query request.
* <p>
* This means that read audit is on for this bean type and that query has not explicitly disabled it.
*/
public boolean isAuditReads() {
return beanDescriptor.isReadAuditing() && !query.isDisableReadAudit();
}
/**
* Return the base table alias for this query.
*/
@@ -773,4 +711,10 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
public int forwardOnlyFetchSize() {
return queryEngine.forwardOnlyFetchSize();
}
public void clearContext() {
if (!transaction.isAutoPersistUpdates()) {
beanDescriptor.contextClear(transaction.persistenceContext());
}
}
}
@@ -2,7 +2,6 @@ package io.ebeaninternal.server.core;
import io.ebean.InsertOptions;
import io.ebean.ValuePair;
import io.ebean.annotation.DocStoreMode;
import io.ebean.bean.EntityBean;
import io.ebean.bean.EntityBeanIntercept;
import io.ebean.bean.PreGetterCallback;
@@ -17,21 +16,16 @@ import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
import io.ebeaninternal.server.deploy.id.ImportedId;
import io.ebeaninternal.server.persist.*;
import io.ebeaninternal.server.transaction.BeanPersistIdMap;
import io.ebeanservice.docstore.api.DocStoreUpdate;
import io.ebeanservice.docstore.api.DocStoreUpdateContext;
import io.ebeanservice.docstore.api.DocStoreUpdates;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.OptimisticLockException;
import jakarta.persistence.PersistenceException;
import java.io.IOException;
import java.sql.Statement;
import java.util.*;
/**
* PersistRequest for insert update or delete of a bean.
*/
public final class PersistRequestBean<T> extends PersistRequest implements BeanPersistRequest<T>, DocStoreUpdate, PreGetterCallback, SpiProfileTransactionEvent {
public final class PersistRequestBean<T> extends PersistRequest implements BeanPersistRequest<T>, PreGetterCallback, SpiProfileTransactionEvent {
private final BeanManager<T> beanManager;
private final BeanDescriptor<T> beanDescriptor;
@@ -45,10 +39,8 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
*/
private final Object parentBean;
private final boolean dirty;
private final boolean publish;
private int flags;
private boolean saveRecurse;
private DocStoreMode docStoreMode;
private final ConcurrencyMode concurrencyMode;
/**
* The unique id used for logging summary.
@@ -139,7 +131,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
this.parentBean = parentBean;
this.controller = beanDescriptor.persistController();
this.type = type;
this.docStoreMode = calcDocStoreMode(transaction, type);
this.flags = flags;
if (Flags.isRecurse(flags)) {
this.persistCascade = t.isPersistCascade();
@@ -155,10 +146,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
}
}
this.concurrencyMode = beanDescriptor.concurrencyMode(intercept);
this.publish = Flags.isPublish(flags);
if (isMarkDraftDirty(publish)) {
beanDescriptor.setDraftDirty(entityBean, true);
}
this.dirty = intercept.isDirty();
}
@@ -187,29 +174,11 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
profileBase(type.profileEventId, offset, beanDescriptor.name(), flushCount);
}
/**
* Return the document store event that should be used for this request.
* <p>
* Used to check if the Transaction has set the mode to IGNORE when doing large batch inserts that we
* don't want to send to the doc store.
*/
private DocStoreMode calcDocStoreMode(SpiTransaction txn, Type type) {
DocStoreMode txnMode = (txn == null) ? null : txn.docStoreMode();
return beanDescriptor.docStoreMode(type, txnMode);
}
@Override
public boolean isCascade() {
return Flags.isRecurse(flags);
}
/**
* Return true if the draftDirty property should be set to true for this request.
*/
private boolean isMarkDraftDirty(boolean publish) {
return !publish && type != Type.DELETE && beanDescriptor.isDraftable();
}
/**
* Set the transaction from prior persist request.
* Only used when hard deleting draft & associated live beans.
@@ -224,9 +193,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
* Init the transaction and also check for batch on cascade escalation.
*/
public void initTransIfRequiredWithBatchCascade() {
if (createImplicitTransIfRequired()) {
docStoreMode = calcDocStoreMode(transaction, type);
}
createImplicitTransIfRequired();
checkBatchEscalationOnCascade();
}
@@ -427,21 +394,14 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
* Set the cache notify status.
*/
private void setNotifyCache() {
this.notifyCache = beanDescriptor.isCacheNotify(type, publish);
this.notifyCache = beanDescriptor.isCacheNotify(type);
}
/**
* Return true if this change should notify persist listener or doc store (and keep the request).
*/
private boolean isNotifyListeners() {
return isNotifyPersistListener() || isDocStoreNotify();
}
/**
* Return true if this request should update the document store.
*/
private boolean isDocStoreNotify() {
return docStoreMode != DocStoreMode.IGNORE;
return isNotifyPersistListener();
}
private boolean isNotifyPersistListener() {
@@ -470,46 +430,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
}
}
/**
* Process the persist request updating the document store.
*/
@Override
public void docStoreUpdate(DocStoreUpdateContext txn) throws IOException {
switch (type) {
case INSERT:
beanDescriptor.docStoreInsert(idValue, this, txn);
break;
case UPDATE:
case DELETE_SOFT:
beanDescriptor.docStoreUpdate(idValue, this, txn);
break;
case DELETE:
beanDescriptor.docStoreDeleteById(idValue, txn);
break;
default:
throw new IllegalStateException("Invalid type " + type);
}
}
/**
* Add this event to the queue entries in IndexUpdates.
*/
@Override
public void addToQueue(DocStoreUpdates docStoreUpdates) {
switch (type) {
case INSERT:
case UPDATE:
case DELETE_SOFT:
docStoreUpdates.queueIndex(beanDescriptor.docStoreQueueId(), idValue);
break;
case DELETE:
docStoreUpdates.queueDelete(beanDescriptor.docStoreQueueId(), idValue);
break;
default:
throw new IllegalStateException("Invalid type " + type);
}
}
public void addToPersistMap(BeanPersistIdMap beanPersistMap) {
beanPersistMap.add(beanDescriptor, type, idValue);
}
@@ -652,28 +572,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
return beanDescriptor.createRef(beanId(), null);
}
/**
* Return true if the bean type is a Draftable.
*/
public boolean isDraftable() {
return beanDescriptor.isDraftable();
}
/**
* Return true if this request is a hard delete of a draftable bean.
* If this is true Ebean is expected to auto-publish and delete the associated live bean.
*/
public boolean isHardDeleteDraft() {
if (type == Type.DELETE && beanDescriptor.isDraftable() && !beanDescriptor.isDraftableElement()) {
// deleting a top level draftable bean
if (beanDescriptor.isLiveInstance(entityBean)) {
throw new PersistenceException("Explicit Delete is not allowed on a 'live' bean - only draft beans");
}
return true;
}
return false;
}
/**
* Return true if this was a hard/permanent delete request (and should cascade as such).
*/
@@ -681,16 +579,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
return (type == Type.DELETE && beanDescriptor.isSoftDelete());
}
/**
* Checks for @Draftable entity beans with @Draft property that the bean is a 'draft'.
* Save or Update is not allowed to execute using 'live' beans - must use publish().
*/
public void checkDraft() {
if (beanDescriptor.isDraftable() && beanDescriptor.isLiveInstance(entityBean)) {
throw new PersistenceException("Save or update is not allowed on a 'live' bean - only draft beans");
}
}
/**
* Return the parent bean for cascading save with unidirectional relationship.
*/
@@ -876,7 +764,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
setNotifyCache();
boolean isChangeLog = beanDescriptor.isChangeLog();
if (type == Type.UPDATE) {
// get the dirty properties for notify cache & orphanRemoval of vanilla collection detection
// get the dirty properties for update notification to the doc store
dirtyProperties = intercept.dirtyProperties();
}
if (isChangeLog) {
@@ -938,20 +826,19 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
}
private void logSummaryMessage() {
String draft = (beanDescriptor.isDraftable() && !publish) ? " draft[true]" : "";
String name = beanDescriptor.name();
switch (type) {
case INSERT:
transaction.logSummary("Inserted [{0}] [{1}]{2}", name, (idValue == null ? "" : idValue), draft);
transaction.logSummary("Inserted [{0}] [{1}]", name, (idValue == null ? "" : idValue));
break;
case UPDATE:
transaction.logSummary("Updated [{0}] [{1}]{2}", name, idValue , draft);
transaction.logSummary("Updated [{0}] [{1}]", name, idValue);
break;
case DELETE:
transaction.logSummary("Deleted [{0}] [{1}]{2}", name, idValue , draft);
transaction.logSummary("Deleted [{0}] [{1}]", name, idValue);
break;
case DELETE_SOFT:
transaction.logSummary("SoftDelete [{0}] [{1}]{2}", name, idValue , draft);
transaction.logSummary("SoftDelete [{0}] [{1}]", name, idValue);
break;
default:
break;
@@ -989,9 +876,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
private void postInsert() {
// mark all properties as loaded after an insert to support immediate update
beanDescriptor.setAllLoaded(entityBean);
if (!publish) {
beanDescriptor.setDraft(entityBean);
}
if (transaction.isAutoPersistUpdates() && idValue != null) {
// with getGeneratedKeys off we will not have a idValue
beanDescriptor.contextPut(transaction.persistenceContext(), idValue, entityBean);
@@ -1088,32 +972,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
}
}
/**
* For requests that update document store add this event to either the list
* of queue events or list of update events.
*/
public void addDocStoreUpdates(DocStoreUpdates docStoreUpdates) {
if (type == Type.UPDATE) {
beanDescriptor.docStoreUpdateEmbedded(this, docStoreUpdates);
}
switch (docStoreMode) {
case UPDATE: {
docStoreUpdates.addPersist(this);
return;
}
case QUEUE: {
if (type == Type.DELETE) {
docStoreUpdates.queueDelete(beanDescriptor.docStoreQueueId(), idValue);
} else {
docStoreUpdates.queueIndex(beanDescriptor.docStoreQueueId(), idValue);
}
}
break;
default:
break;
}
}
/**
* Determine if all loaded properties should be used for an update.
* <p>
@@ -1139,13 +997,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
return flags;
}
/**
* Return true if this request is a 'publish' action.
*/
public boolean isPublish() {
return publish;
}
/**
* Return the key for an update persist request.
*/
@@ -1162,17 +1013,14 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
key.append('v');
}
}
if (publish) {
key.append('p');
}
return key.toString();
}
/**
* Return the table to update depending if the request is a 'publish' one or normal.
* Return the table to update.
*/
public String updateTable() {
return publish ? beanDescriptor.baseTable() : beanDescriptor.draftTable();
return beanDescriptor.baseTable();
}
/**
@@ -1241,30 +1089,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
return 0;
}
/**
* Persist to the document store now (via buffer, not post commit).
*/
public void docStorePersist() {
idValue = beanDescriptor.getId(entityBean);
if (type == Type.UPDATE) {
dirtyProperties = intercept.dirtyProperties();
}
// processing now so set IGNORE (unlike DB + DocStore processing with post-commit)
docStoreMode = DocStoreMode.IGNORE;
try {
docStoreUpdate(transaction.docStoreTransaction().obtain());
postExecute();
if (type == Type.UPDATE
&& beanDescriptor.isDocStoreEmbeddedInvalidation()
&& transaction.isPersistCascade()) {
// queue embedded/nested updates for later processing
beanDescriptor.docStoreUpdateEmbedded(this, transaction.docStoreTransaction().queue());
}
} catch (IOException e) {
throw new PersistenceException("Error persisting doc store bean", e);
}
}
/**
* Use a common 'now' value across both when created and when updated etc.
*/
@@ -1384,7 +1208,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
* Return the SQL used to fetch the last inserted id value.
*/
public String selectLastInsertedId() {
return beanDescriptor.selectLastInsertedId(publish);
return beanDescriptor.selectLastInsertedId();
}
/**
@@ -77,10 +77,13 @@ public final class PersistRequestOrmUpdate extends PersistRequest {
*/
@Override
public void postExecute() {
OrmUpdateType ormUpdateType = ormUpdate.ormUpdateType();
if (OrmUpdateType.INSERT != ormUpdateType && !transaction.isAutoPersistUpdates()) {
beanDescriptor.contextClear(transaction.persistenceContext());
}
if (startNanos > 0) {
persistExecute.collectOrmUpdate(label, startNanos);
}
OrmUpdateType ormUpdateType = ormUpdate.ormUpdateType();
String tableName = ormUpdate.baseTable();
if (transaction.isLogSummary()) {
transaction.logSummary("{0} table[{1}] rows[{2}] bind[{3}]", ormUpdateType, tableName, rowCount, bindLog);
@@ -3,10 +3,13 @@ package io.ebeaninternal.server.core;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiSqlUpdate;
import io.ebeaninternal.api.SpiTransaction;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.persist.BatchControl;
import io.ebeaninternal.server.persist.PersistExecute;
import io.ebeaninternal.server.persist.TrimLogSql;
import java.util.List;
/**
* Persist request specifically for CallableSql.
*/
@@ -156,6 +159,14 @@ public final class PersistRequestUpdateSql extends PersistRequest {
*/
@Override
public void postExecute() {
if (sqlType != SqlType.SQL_INSERT && !transaction.isAutoPersistUpdates()) {
List<BeanDescriptor<?>> descriptors = server.descriptors(tableName);
if (descriptors != null) {
for (BeanDescriptor<?> descriptor : descriptors) {
descriptor.contextClear(transaction.persistenceContext());
}
}
}
if (startNanos > 0) {
persistExecute.collectSqlUpdate(label, startNanos);
}
@@ -78,16 +78,6 @@ public interface Persister {
*/
int executeCallable(CallableSql callable, Transaction t);
/**
* Publish the draft beans matching the given query.
*/
<T> List<T> publish(Query<T> query, Transaction transaction);
/**
* Restore the draft beans back to the matching live beans.
*/
<T> List<T> draftRestore(Query<T> query, Transaction transaction);
/**
* Visit the metrics.
*/
@@ -5,7 +5,6 @@ import io.ebean.Version;
import io.ebean.event.BeanQueryRequest;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeanservice.docstore.api.DocQueryRequest;
import java.util.Collection;
import java.util.List;
@@ -17,7 +16,7 @@ import java.util.function.Predicate;
/**
* Defines the ORM query request api.
*/
public interface SpiOrmQueryRequest<T> extends BeanQueryRequest<T>, DocQueryRequest<T> {
public interface SpiOrmQueryRequest<T> extends BeanQueryRequest<T> {
/**
* Return the query.
@@ -178,11 +177,6 @@ public interface SpiOrmQueryRequest<T> extends BeanQueryRequest<T>, DocQueryRequ
*/
void markNotQueryOnly();
/**
* Return true if this query is expected to use the doc store.
*/
boolean isUseDocStore();
/**
* Return true if delete by statement is allowed for this type given cascade rules etc.
*/
@@ -9,8 +9,6 @@ import io.ebean.event.*;
import io.ebean.event.changelog.ChangeLogListener;
import io.ebean.event.changelog.ChangeLogPrepare;
import io.ebean.event.changelog.ChangeLogRegister;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
import io.ebean.util.AnnotationUtil;
import io.ebeaninternal.api.CoreLog;
@@ -68,14 +66,10 @@ public class BootupClasses implements Predicate<Class<?>> {
private Class<? extends ChangeLogPrepare> changeLogPrepareClass;
private Class<? extends ChangeLogListener> changeLogListenerClass;
private Class<? extends ChangeLogRegister> changeLogRegisterClass;
private Class<? extends ReadAuditPrepare> readAuditPrepareClass;
private Class<? extends ReadAuditLogger> readAuditLoggerClass;
private ChangeLogPrepare changeLogPrepare;
private ChangeLogListener changeLogListener;
private ChangeLogRegister changeLogRegister;
private ReadAuditPrepare readAuditPrepare;
private ReadAuditLogger readAuditLogger;
public BootupClasses() {
}
@@ -173,19 +167,11 @@ public class BootupClasses implements Predicate<Class<?>> {
}
public void addChangeLogInstances(DatabaseBuilder.Settings config) {
readAuditPrepare = config.getReadAuditPrepare();
readAuditLogger = config.getReadAuditLogger();
changeLogPrepare = config.getChangeLogPrepare();
changeLogListener = config.getChangeLogListener();
changeLogRegister = config.getChangeLogRegister();
// if not already set create the implementations found
// via classpath scanning
if (readAuditPrepare == null && readAuditPrepareClass != null) {
readAuditPrepare = create(readAuditPrepareClass, false);
}
if (readAuditLogger == null && readAuditLoggerClass != null) {
readAuditLogger = create(readAuditLoggerClass, false);
}
if (changeLogPrepare == null && changeLogPrepareClass != null) {
changeLogPrepare = create(changeLogPrepareClass, false);
}
@@ -252,14 +238,6 @@ public class BootupClasses implements Predicate<Class<?>> {
return changeLogRegister;
}
public ReadAuditPrepare getReadAuditPrepare() {
return readAuditPrepare;
}
public ReadAuditLogger getReadAuditLogger() {
return readAuditLogger;
}
public List<IdGenerator> getIdGenerators() {
return createAdd(idGeneratorInstances, idGeneratorCandidates);
}
@@ -424,15 +402,6 @@ public class BootupClasses implements Predicate<Class<?>> {
interesting = true;
}
if (ReadAuditPrepare.class.isAssignableFrom(cls)) {
readAuditPrepareClass = (Class<? extends ReadAuditPrepare>) cls;
interesting = true;
}
if (ReadAuditLogger.class.isAssignableFrom(cls)) {
readAuditLoggerClass = (Class<? extends ReadAuditLogger>) cls;
interesting = true;
}
return interesting;
}
@@ -1,101 +0,0 @@
package io.ebeaninternal.server.deploy;
import io.ebean.bean.EntityBean;
import io.ebean.bean.PersistenceContext;
import io.ebeaninternal.server.query.SqlJoinType;
import io.ebeaninternal.server.query.SqlTreeJoin;
import java.sql.SQLException;
/**
* Helper for BeanPropertyAssocOne imported reference but with inheritance.
*/
final class AssocOneHelpRefInherit extends AssocOneHelp {
private final InheritInfo inherit;
AssocOneHelpRefInherit(BeanPropertyAssocOne<?> property) {
super(property);
this.inherit = property.targetInheritInfo;
}
@Override
void loadIgnore(DbReadContext ctx) {
property.targetIdBinder.loadIgnore(ctx);
ctx.dataReader().incrementPos(1);
}
/**
* Read and set a Reference bean.
*/
@Override
Object read(DbReadContext ctx) throws SQLException {
// read discriminator to determine the type
InheritInfo rowInheritInfo = inherit.readType(ctx);
BeanDescriptor<?> desc;
if (rowInheritInfo != null) {
desc = rowInheritInfo.desc();
} else if (!inherit.hasChildren()) {
desc = inherit.desc();
} else {
// ignore the id property
property.targetIdBinder.loadIgnore(ctx);
return null;
}
Object id = property.targetIdBinder.read(ctx);
if (id == null) {
return null;
}
// check transaction context to see if it already exists
PersistenceContext pc = ctx.persistenceContext();
Object existing = desc.contextGet(pc, id);
if (existing != null) {
return existing;
}
// for inheritance hierarchy create the correct type for this row...
boolean disableLazyLoading = ctx.isDisableLazyLoading();
Object ref = desc.contextRef(pc, ctx.isReadOnly(), disableLazyLoading, id);
if (!disableLazyLoading) {
ctx.registerBeanInherit(property, ((EntityBean) ref)._ebean_getIntercept());
}
return ref;
}
void appendFrom(DbSqlContext ctx, SqlJoinType joinType) {
// add join to support the discriminator column
String relativePrefix = ctx.relativePrefix(property.name);
ctx.addExtraJoin(new Extra(relativePrefix, joinType));
}
/**
* Extra join to support the discriminator column.
*/
final class Extra implements SqlTreeJoin {
final String relativePrefix;
final SqlJoinType joinType;
Extra(String relativePrefix, SqlJoinType joinType) {
this.relativePrefix = relativePrefix;
this.joinType = joinType;
}
@Override
public void addJoin(DbSqlContext ctx) {
// add join to support the discriminator column *IF* join is not already present
property.tableJoin.addJoin(joinType, relativePrefix, ctx);
}
}
/**
* Append columns for foreign key columns.
*/
@Override
void appendSelect(DbSqlContext ctx, boolean subQuery) {
if (!subQuery) {
// add discriminator column
String relativePrefix = ctx.relativePrefix(property.name());
String tableAlias = ctx.tableAlias(relativePrefix);
ctx.appendColumn(tableAlias, property.targetInheritInfo.getDiscriminatorColumn());
}
property.importedId.sqlAppend(ctx);
}
}
@@ -14,13 +14,9 @@ import io.ebean.event.*;
import io.ebean.event.changelog.BeanChange;
import io.ebean.event.changelog.ChangeLogFilter;
import io.ebean.event.changelog.ChangeType;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
import io.ebean.event.readaudit.ReadEvent;
import io.ebean.meta.MetaQueryPlan;
import io.ebean.meta.MetricVisitor;
import io.ebean.meta.QueryPlanInit;
import io.ebean.plugin.BeanDocType;
import io.ebean.plugin.BeanType;
import io.ebean.plugin.ExpressionPath;
import io.ebean.plugin.Property;
@@ -45,15 +41,8 @@ import io.ebeaninternal.server.query.*;
import io.ebeaninternal.server.querydefn.DefaultOrmQuery;
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
import io.ebeaninternal.server.querydefn.OrmQueryProperties;
import io.ebeaninternal.server.rawsql.SpiRawSql;
import io.ebeaninternal.util.SortByClause;
import io.ebeaninternal.util.SortByClauseParser;
import io.ebeanservice.docstore.api.DocStoreBeanAdapter;
import io.ebeanservice.docstore.api.DocStoreUpdateContext;
import io.ebeanservice.docstore.api.DocStoreUpdates;
import io.ebeanservice.docstore.api.mapping.DocMappingBuilder;
import io.ebeanservice.docstore.api.mapping.DocPropertyMapping;
import io.ebeanservice.docstore.api.mapping.DocumentMapping;
import jakarta.persistence.PersistenceException;
import java.io.IOException;
@@ -89,8 +78,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
private final ConcurrentHashMap<String, STreeProperty> dynamicProperty = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Map<String, String>> pathMaps = new ConcurrentHashMap<>();
private final Map<String, SpiRawSql> namedRawSql;
private final Map<String, String> namedQuery;
private final boolean multiValueSupported;
private boolean batchEscalateOnCascadeInsert;
private boolean batchEscalateOnCascadeDelete;
@@ -108,7 +95,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
* getGeneratedKeys is not supported.
*/
private final String selectLastInsertedId;
private final String selectLastInsertedIdDraft;
private final boolean autoTunable;
private final ConcurrencyMode concurrencyMode;
private final IndexDefinition[] indexDefinitions;
@@ -120,18 +106,12 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
private final TableJoin primaryKeyJoin;
private final BeanProperty softDeleteProperty;
private final boolean softDelete;
private final String draftTable;
private final PartitionMeta partitionMeta;
private final TablespaceMeta tablespaceMeta;
private final String storageEngine;
private final String dbComment;
private final boolean readAuditing;
private final boolean draftable;
private final boolean draftableElement;
private final BeanProperty unmappedJson;
private final BeanProperty tenant;
private final BeanProperty draft;
private final BeanProperty draftDirty;
private final LinkedHashMap<String, BeanProperty> propMap;
/**
* Map of DB column to property path (for nativeSql mapping).
@@ -154,7 +134,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
private final BeanQueryAdapter queryAdapter;
private final BeanFindController beanFinder;
private final ChangeLogFilter changeLogFilter;
final InheritInfo inheritInfo;
private final boolean abstractType;
private final BeanProperty idProperty;
private final int idPropertyIndex;
@@ -166,10 +145,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
* Properties that are initialised in the constructor need to be 'unloaded' to support partial object queries.
*/
private final int[] unloadProperties;
/**
* Properties local to this type (not from a super type).
*/
private final BeanProperty[] propertiesLocal;
/**
* Scalar mutable properties (need to dirty check on update).
*/
@@ -223,13 +198,8 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
private final String name;
private final String baseTableAlias;
private final boolean cacheSharableBeans;
private final String docStoreQueueId;
private final BeanDescriptorDraftHelp<T> draftHelp;
private final BeanDescriptorCacheHelp<T> cacheHelp;
private final BeanDescriptorJsonHelp<T> jsonHelp;
private DocStoreBeanAdapter<T> docStoreAdapter;
private DocumentMapping docMapping;
private boolean docStoreEmbeddedInvalidation;
private final String defaultSelectClause;
private SpiEbeanServer ebeanServer;
@@ -245,9 +215,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
this.rootBeanType = PersistenceContextUtil.root(beanType);
this.prototypeEntityBean = createPrototypeEntityBean(beanType);
this.iudMetrics = new BeanIudMetrics(name);
this.namedQuery = deploy.getNamedQuery();
this.namedRawSql = deploy.getNamedRawSql();
this.inheritInfo = deploy.getInheritInfo();
this.beanFinder = deploy.getBeanFinder();
this.persistController = deploy.getPersistController();
this.persistListener = deploy.getPersistListener();
@@ -261,14 +228,9 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
this.idGeneratedValue = deploy.isIdGeneratedValue();
this.idGenerator = deploy.getIdGenerator();
this.selectLastInsertedId = deploy.getSelectLastInsertedId();
this.selectLastInsertedIdDraft = deploy.getSelectLastInsertedIdDraft();
this.concurrencyMode = deploy.getConcurrencyMode();
this.indexDefinitions = deploy.getIndexDefinitions();
this.readAuditing = deploy.isReadAuditing();
this.draftable = deploy.isDraftable();
this.draftableElement = deploy.isDraftableElement();
this.historySupport = deploy.isHistorySupport();
this.draftTable = deploy.getDraftTable();
this.baseTable = InternString.intern(deploy.getBaseTable());
this.baseTableAsOf = deploy.getBaseTableAsOf();
this.primaryKeyJoin = deploy.getPrimaryKeyJoin();
@@ -290,14 +252,11 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
this.versionProperty = listHelper.getVersionProperty();
this.unmappedJson = listHelper.getUnmappedJson();
this.tenant = listHelper.getTenant();
this.draft = listHelper.getDraft();
this.draftDirty = listHelper.getDraftDirty();
this.propMap = listHelper.getPropertyMap();
this.propertiesTransient = listHelper.getTransients();
this.propertiesNonTransient = listHelper.getNonTransients();
this.propertiesBaseScalar = listHelper.getBaseScalar();
this.propertiesEmbedded = listHelper.getEmbedded();
this.propertiesLocal = listHelper.getLocal();
this.propertiesMutable = listHelper.getMutable();
this.unidirectional = listHelper.getUnidirectional();
this.orderColumn = listHelper.getOrderColumn();
@@ -320,9 +279,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
this.cacheSharableBeans = noRelationships && deploy.getCacheOptions().isReadOnly();
this.cacheHelp = new BeanDescriptorCacheHelp<>(this, owner.cacheManager(), deploy.getCacheOptions(), cacheSharableBeans, propertiesOneImported);
this.jsonHelp = initJsonHelp();
this.draftHelp = new BeanDescriptorDraftHelp<>(this);
this.docStoreAdapter = owner.createDocStoreBeanAdapter(this, deploy);
this.docStoreQueueId = docStoreAdapter.queueId();
// Check if there are no cascade save associated beans ( subject to change
// in initialiseOther()). Note that if we are in an inheritance hierarchy
// then we also need to check every BeanDescriptors in the InheritInfo as
@@ -482,17 +438,10 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
* as they are used to get the imported and exported properties.
*/
void initialiseId(BeanDescriptorInitContext initContext) {
if (draftable) {
initContext.addDraft(baseTable, draftTable);
}
if (historySupport) {
// add mapping (used to swap out baseTable for asOf queries)
initContext.addHistory(baseTable, baseTableAsOf);
}
if (inheritInfo != null) {
inheritInfo.setDescriptor(this);
}
// initialise just the Id property only
if (idProperty != null) {
idProperty.initialise(initContext);
@@ -503,10 +452,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
* Initialise the exported and imported parts for associated properties.
*/
public void initialiseOther(BeanDescriptorInitContext initContext) {
for (BeanPropertyAssocMany<?> many : propertiesManyToMany) {
// register associated draft table for M2M intersection
many.registerDraftIntersectionTable(initContext);
}
if (historySupport) {
// history support on this bean so check all associated intersection tables
// and if they are not excluded register the associated 'with history' table
@@ -607,7 +552,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
}
}
}
docStoreEmbeddedInvalidation = docStoreAdapter.hasEmbeddedInvalidation();
}
private void addUniqueColumns(IndexDefinition indexDef) {
@@ -643,11 +587,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
for (BeanPropertyAssocOne<?> one : propertiesOne) {
one.initialisePostTarget();
}
if (inheritInfo != null && !inheritInfo.isRoot()) {
docStoreAdapter = (DocStoreBeanAdapter<T>) inheritInfo.getRoot().desc().docStoreAdapter();
}
docMapping = docStoreAdapter.createDocMapping();
docStoreAdapter.registerPaths();
cacheHelp.deriveNotifyFlags();
}
@@ -675,18 +614,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
return type == PersistRequest.Type.INSERT ? batchEscalateOnCascadeInsert : batchEscalateOnCascadeDelete;
}
void initInheritInfo() {
if (inheritInfo != null) {
// need to check every BeanDescriptor in the inheritance hierarchy
if (saveRecurseSkippable) {
saveRecurseSkippable = inheritInfo.isSaveRecurseSkippable();
}
if (deleteRecurseSkippable) {
deleteRecurseSkippable = inheritInfo.isDeleteRecurseSkippable();
}
}
}
public void metricPersistBatch(PersistRequest.Type type, long startNanos, int size) {
iudMetrics.addBatch(type, startNanos, size);
}
@@ -723,20 +650,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
}
}
/**
* Return the ReadAuditLogger for logging read audit events.
*/
public ReadAuditLogger readAuditLogger() {
return ebeanServer.readAuditLogger();
}
/**
* Return the ReadAuditPrepare for preparing read audit events prior to logging.
*/
private ReadAuditPrepare readAuditPrepare() {
return ebeanServer.readAuditPrepare();
}
public boolean isChangeLog() {
return changeLogFilter != null;
}
@@ -939,166 +852,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
return defaultSelectClause;
}
/**
* Return true if this object is the root level object in its entity
* inheritance.
*/
@Override
public boolean isInheritanceRoot() {
return inheritInfo == null || inheritInfo.isRoot();
}
/**
* Return true if this type maps to a root type of a doc store document (not embedded or ignored).
*/
@Override
public boolean isDocStoreMapped() {
return docStoreAdapter.mapped();
}
/**
* Return true if this bean type has embedded doc store invalidation.
*/
public boolean isDocStoreEmbeddedInvalidation() {
return docStoreEmbeddedInvalidation;
}
/**
* Return the queueId used to uniquely identify this type when queuing an index updateAdd.
*/
@Override
public String docStoreQueueId() {
return docStoreQueueId;
}
@Override
public DocumentMapping docMapping() {
return docMapping;
}
/**
* Return the doc store helper for this bean type.
*/
@Override
public BeanDocType<T> docStore() {
return docStoreAdapter;
}
/**
* Return doc store adapter for internal use for processing persist requests.
*/
public DocStoreBeanAdapter<T> docStoreAdapter() {
return docStoreAdapter;
}
/**
* Build the Document mapping recursively with the given prefix relative to the root of the document.
*/
public void docStoreMapping(final DocMappingBuilder mapping, final String prefix) {
if (prefix != null && idProperty != null) {
// id property not included in the
idProperty.docStoreMapping(mapping, prefix);
}
if (inheritInfo != null) {
String discCol = inheritInfo.getDiscriminatorColumn();
if (Types.VARCHAR == inheritInfo.getDiscriminatorType()) {
mapping.add(new DocPropertyMapping(discCol, DocPropertyType.ENUM));
} else {
mapping.add(new DocPropertyMapping(discCol, DocPropertyType.INTEGER));
}
}
for (BeanProperty prop : propertiesNonTransient) {
prop.docStoreMapping(mapping, prefix);
}
if (inheritInfo != null) {
inheritInfo.visitChildren(inheritInfo1 -> {
for (BeanProperty localProperty : inheritInfo1.localProperties()) {
localProperty.docStoreMapping(mapping, prefix);
}
});
}
}
/**
* Return the root bean type if part of inheritance hierarchy.
*/
@Override
public BeanType<?> root() {
if (inheritInfo != null && !inheritInfo.isRoot()) {
return inheritInfo.getRoot().desc();
}
return this;
}
/**
* Return the full name taking into account inheritance.
*/
public String rootName() {
if (inheritInfo != null && !inheritInfo.isRoot()) {
return inheritInfo.getRoot().desc().name();
}
return name;
}
/**
* Return the named ORM query.
*/
public String namedQuery(String name) {
return namedQuery.get(name);
}
/**
* Return the named RawSql query.
*/
public SpiRawSql namedRawSql(String named) {
return namedRawSql.get(named);
}
/**
* Return the type of DocStoreMode that should occur for this type of persist request
* given the transactions requested mode.
*/
public DocStoreMode docStoreMode(PersistRequest.Type persistType, DocStoreMode txnMode) {
return docStoreAdapter.mode(persistType, txnMode);
}
public void docStoreInsert(Object idValue, PersistRequestBean<T> persistRequest, DocStoreUpdateContext bulkUpdate) throws IOException {
docStoreAdapter.insert(idValue, persistRequest, bulkUpdate);
}
public void docStoreUpdate(Object idValue, PersistRequestBean<T> persistRequest, DocStoreUpdateContext bulkUpdate) throws IOException {
docStoreAdapter.update(idValue, persistRequest, bulkUpdate);
}
/**
* Check if this update invalidates an embedded part of a doc store document.
*/
public void docStoreUpdateEmbedded(PersistRequestBean<T> request, DocStoreUpdates docStoreUpdates) {
docStoreAdapter.updateEmbedded(request, docStoreUpdates);
}
public void docStoreDeleteById(Object idValue, DocStoreUpdateContext txn) throws IOException {
docStoreAdapter.deleteById(idValue, txn);
}
public T publish(T draftBean, T liveBean) {
return draftHelp.publish(draftBean, liveBean);
}
/**
* Reset properties on the draft bean based on @DraftDirty and @DraftReset.
*/
public boolean draftReset(T draftBean) {
return draftHelp.draftReset(draftBean);
}
/**
* Return the draft dirty boolean property or null if there is not one assigned to this bean type.
*/
BeanProperty draftDirty() {
return draftDirty;
}
/**
* Prepare the query for multi-tenancy check for document store only use.
*/
@@ -1109,9 +862,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
tenant.addTenant(query, tenantId);
}
}
if (isDocStoreOnly()) {
query.setUseDocStore(true);
}
}
/**
@@ -1151,11 +901,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
/**
* Return true if the persist request needs to notify the cache.
*/
public boolean isCacheNotify(PersistRequest.Type type, boolean publish) {
if (draftable && !publish) {
// no caching when editing draft beans
return false;
}
public boolean isCacheNotify(PersistRequest.Type type) {
return cacheHelp.isCacheNotify(type);
}
@@ -1372,52 +1118,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
cacheHelp.cacheBeanUpdate(key, changes, updateNaturalKey, version);
}
/**
* Prepare the read audit of a findFutureList() query.
*/
public void readAuditFutureList(SpiQuery<T> spiQuery) {
if (isReadAuditing()) {
ReadEvent event = new ReadEvent(fullName);
// prepare in the foreground thread while we have the user context
// information (query is processed/executed later in bg thread)
readAuditPrepare(event);
spiQuery.setFutureFetchAudit(event);
}
}
/**
* Write a bean read to the read audit log.
*/
public void readAuditBean(String queryKey, String bindLog, Object bean) {
ReadEvent event = new ReadEvent(fullName, queryKey, bindLog, idForJson(bean));
readAuditPrepare(event);
readAuditLogger().auditBean(event);
}
private void readAuditPrepare(ReadEvent event) {
ReadAuditPrepare prepare = readAuditPrepare();
if (prepare != null) {
prepare.prepare(event);
}
}
/**
* Write a many bean read to the read audit log.
*/
public void readAuditMany(String queryKey, String bindLog, List<Object> ids) {
ReadEvent event = new ReadEvent(fullName, queryKey, bindLog, ids);
readAuditPrepare(event);
readAuditLogger().auditMany(event);
}
/**
* Write a futureList many read to the read audit log.
*/
public void readAuditFutureMany(ReadEvent event) {
// this has already been prepared (in foreground thread)
readAuditLogger().auditMany(event);
}
/**
* Return the base table alias. This is always the first letter of the bean name.
*/
@@ -1795,17 +1495,11 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
if (d != null) {
Object shareableBean = d.getSharableBean();
if (shareableBean != null) {
if (isReadAuditing()) {
readAuditBean("ref", "", shareableBean);
}
return (T) shareableBean;
}
}
}
try {
if (inheritInfo != null && !inheritInfo.isConcrete()) {
return findReferenceBean(id, pc);
}
EntityBean eb = createEntityBean();
id = convertSetId(id, eb);
EntityBeanIntercept ebi = eb._ebean_getIntercept();
@@ -1840,9 +1534,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
* Create a non read only reference bean without checking cacheSharableBeans.
*/
public T createReference(Object id, PersistenceContext pc) {
if (inheritInfo != null && !inheritInfo.isConcrete()) {
return findReferenceBean(id, pc);
}
return createRef(id, pc);
}
@@ -1941,17 +1632,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
* visible.
*/
public BeanPropertyAssocOne<?> unidirectional() {
BeanDescriptor<?> other = this;
while (true) {
if (other.unidirectional != null) {
return other.unidirectional;
}
if (other.inheritInfo != null && !other.inheritInfo.isRoot()) {
other = other.inheritInfo.getParent().desc();
continue;
}
return null;
}
return unidirectional;
}
/**
@@ -2056,6 +1737,13 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
pc.clear(rootBeanType, idValue);
}
/**
* Clear a bean from the persistence context.
*/
public void contextClear(PersistenceContext pc) {
pc.clear(rootBeanType);
}
/**
* Delete a bean from the persistence context (such that we don't fetch it in the same transaction).
*/
@@ -2208,9 +1896,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
if (lazyLoadProperty == -1) {
return false;
}
if (inheritInfo != null) {
return descOf(ebi.owner().getClass()).lazyLoadMany(ebi, lazyLoadProperty, parent);
}
return lazyLoadMany(ebi, lazyLoadProperty, parent);
}
@@ -2238,13 +1923,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
return false;
}
/**
* Return the correct BeanDescriptor based on the bean class type.
*/
BeanDescriptor<?> descOf(Class<?> type) {
return inheritInfo.readType(type).desc();
}
/**
* Return a Comparator for local sorting of lists.
*
@@ -2437,13 +2115,8 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
BeanProperty _findBeanProperty(String propName) {
BeanProperty prop = propMap.get(propName);
if (prop == null) {
if ("_$IdClass$".equals(propName)) {
return idProperty;
} else if (inheritInfo != null) {
// search in sub types...
return inheritInfo.findSubTypeProperty(propName);
}
if (prop == null && "_$IdClass$".equals(propName)) {
return idProperty;
}
return prop;
}
@@ -2477,45 +2150,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
return autoTunable;
}
/**
* Returns the Inheritance mapping information. This will be null if this type
* of bean is not involved in any ORM inheritance mapping.
*/
@Override
public InheritInfo inheritInfo() {
return inheritInfo;
}
@Override
public boolean hasInheritance() {
return inheritInfo != null;
}
@Override
public String discColumn() {
return inheritInfo.getDiscriminatorColumn();
}
/**
* Return the discriminator value for this bean type (or null when there is no inheritance).
*/
public String discValue() {
return inheritInfo == null ? null : inheritInfo.getDiscriminatorStringValue();
}
@Override
@SuppressWarnings("unchecked")
public T createBeanUsingDisc(Object discValue) {
return (T) inheritInfo.getType(discValue.toString()).desc().createBean();
}
@Override
public void addInheritanceWhere(Query<?> query) {
if (inheritInfo != null && !inheritInfo.isRoot()) {
query.where().eq(inheritInfo.getDiscriminatorColumn(), inheritInfo.getDiscriminatorValue());
}
}
/**
* Return true if this is an embedded bean.
*/
@@ -2708,8 +2342,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
@Override
public String baseTable(SpiQuery.TemporalMode mode) {
switch (mode) {
case DRAFT:
return draftTable;
case VERSIONS:
return baseTableVersionsBetween;
case AS_OF:
@@ -2719,20 +2351,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
}
}
/**
* Return the associated draft table.
*/
public String draftTable() {
return draftTable;
}
/**
* Return true if read auditing is on this entity bean.
*/
public boolean isReadAuditing() {
return readAuditing;
}
@Override
public boolean isSoftDelete() {
return softDelete;
@@ -2764,20 +2382,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
}
}
/**
* Return true if this entity type is draftable.
*/
public boolean isDraftable() {
return draftable;
}
/**
* Return true if this entity type is a draftable element (child).
*/
public boolean isDraftableElement() {
return draftableElement;
}
@Override
public Map<String, String> pathMap(String prefix) {
return pathMaps.computeIfAbsent(prefix, s -> {
@@ -2843,28 +2447,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
}
}
/**
* Set the draft to true for this entity bean instance.
* This bean is being loaded via asDraft() query.
*/
@Override
public void setDraft(EntityBean entityBean) {
if (draft != null) {
draft.setValue(entityBean, true);
}
}
/**
* Return true if the bean is considered a 'draft' instance (not 'live').
*/
public boolean isDraftInstance(EntityBean entityBean) {
if (draft != null) {
return Boolean.TRUE == draft.getValue(entityBean);
}
// no draft property - so return false
return false;
}
@Override
public boolean isToManyDirty(EntityBean bean) {
final EntityBeanIntercept ebi = bean._ebean_getIntercept();
@@ -2879,39 +2461,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
return false;
}
/**
* Return true if the bean is draftable and considered a 'live' instance.
*/
public boolean isLiveInstance(EntityBean entityBean) {
if (draft != null) {
return Boolean.FALSE == draft.getValue(entityBean);
}
// no draft property - so return false
return false;
}
/**
* If there is a @DraftDirty property set it's value on the bean.
*/
public void setDraftDirty(EntityBean entityBean, boolean value) {
if (draftDirty != null) {
// check to see if the dirty property has already
// been set and if so do not set the value
if (!entityBean._ebean_getIntercept().isChangedProperty(draftDirty.propertyIndex())) {
draftDirty.setValueIntercept(entityBean, value);
}
}
}
/**
* Optimise the draft query fetching any draftable element relationships.
*/
public void draftQueryOptimise(Query<T> query) {
// use per query PersistenceContext to ensure fresh beans loaded
query.setPersistenceContextScope(PersistenceContextScope.QUERY);
draftHelp.draftQueryOptimise(query);
}
/**
* Return true if this entity bean has history support.
*/
@@ -2957,8 +2506,8 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
* This is only used with Identity columns and getGeneratedKeys is not
* supported.
*/
public String selectLastInsertedId(boolean publish) {
return publish ? selectLastInsertedId : selectLastInsertedIdDraft;
public String selectLastInsertedId() {
return selectLastInsertedId;
}
/**
@@ -3328,13 +2877,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
return propertiesBaseScalar;
}
/**
* Return the properties local to this type for inheritance.
*/
public BeanProperty[] propertiesLocal() {
return propertiesLocal;
}
/**
* Return the properties set as generated values on insert.
*/
@@ -3397,27 +2939,4 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
return propertiesUnique;
}
@Override
public List<BeanType<?>> inheritanceChildren() {
if (hasInheritance()) {
return inheritInfo().getChildren()
.stream()
.map(InheritInfo::desc)
.collect(Collectors.toList());
} else {
return Collections.emptyList();
}
}
@Override
public BeanType<?> inheritanceParent() {
return inheritInfo() == null ? null : inheritInfo().getParent().desc();
}
@Override
public void visitAllInheritanceChildren(Consumer<BeanType<?>> visitor) {
if (hasInheritance()) {
inheritInfo().visitChildren(info -> visitor.accept(info.desc()));
}
}
}
@@ -449,44 +449,7 @@ final class BeanDescriptorCacheHelp<T> {
}
void beanPutAll(Collection<EntityBean> beans) {
if (desc.inheritInfo != null) {
Class<?> aClass = theClassOf(beans);
// check if all beans have the same class
for (EntityBean bean : beans) {
if (!bean.getClass().equals(aClass)) {
aClass = null;
break;
}
}
if (aClass == null) {
// there are different bean types in the collection, so we add one by one to the cache
for (EntityBean bean : beans) {
desc.descOf(bean.getClass()).cacheBeanPutDirect(bean);
}
} else {
desc.descOf(aClass).cacheBeanPutAllDirect(beans);
}
} else {
beanCachePutAllDirect(beans);
}
}
private Class<?> theClassOf(Collection<EntityBean> beans) {
if (beans instanceof List) {
return ((List<?>) beans).get(0).getClass();
}
return beans.iterator().next().getClass();
}
/**
* Put a bean into the bean cache.
*/
void beanCachePut(EntityBean bean) {
if (desc.inheritInfo != null) {
desc.descOf(bean.getClass()).cacheBeanPutDirect(bean);
} else {
beanCachePutDirect(bean);
}
beanCachePutAllDirect(beans);
}
void beanCachePutAllDirect(Collection<EntityBean> beans) {
@@ -520,6 +483,13 @@ final class BeanDescriptorCacheHelp<T> {
}
}
/**
* Put a bean into the bean cache.
*/
void beanCachePut(EntityBean bean) {
beanCachePutDirect(bean);
}
/**
* Put the bean into the bean cache.
*/
@@ -594,9 +564,6 @@ final class BeanDescriptorCacheHelp<T> {
if (beanLog.isLoggable(TRACE)) {
beanLog.log(TRACE, " GET {0}({1}) - hit shared bean", cacheName, id);
}
if (desc.isReadAuditing()) {
desc.readAuditBean("l2", "", bean);
}
return (T) bean;
}
}
@@ -607,19 +574,7 @@ final class BeanDescriptorCacheHelp<T> {
* Load the entity bean taking into account inheritance.
*/
private EntityBean loadBean(Object id, Boolean readOnly, CachedBeanData data, PersistenceContext context) {
String discValue = data.getDiscValue();
if (discValue == null) {
return loadBeanDirect(id, readOnly, data, context);
} else {
return rootDescriptor(discValue).cacheBeanLoadDirect(id, readOnly, data, context);
}
}
/**
* Return the root BeanDescriptor for inheritance.
*/
private BeanDescriptor<?> rootDescriptor(String discValue) {
return desc.inheritInfo.readType(discValue).desc();
return loadBeanDirect(id, readOnly, data, context);
}
/**
@@ -648,9 +603,6 @@ final class BeanDescriptorCacheHelp<T> {
}
CachedBeanDataToBean.load(desc, bean, data, context);
if (desc.isReadAuditing()) {
desc.readAuditBean("l2", "", bean);
}
return bean;
}
@@ -658,12 +610,7 @@ final class BeanDescriptorCacheHelp<T> {
* Load the embedded bean checking for inheritance.
*/
EntityBean embeddedBeanLoad(CachedBeanData data, PersistenceContext context) {
String discValue = data.getDiscValue();
if (discValue == null) {
return embeddedBeanLoadDirect(data, context);
} else {
return rootDescriptor(discValue).cacheEmbeddedBeanLoadDirect(data, context);
}
return embeddedBeanLoadDirect(data, context);
}
/**
@@ -1,99 +0,0 @@
package io.ebeaninternal.server.deploy;
import io.ebean.Query;
import io.ebean.bean.EntityBean;
import java.util.ArrayList;
import java.util.List;
/**
* Helper for BeanDescriptor that manages draft entity beans.
*
* @param <T> The entity bean type
*/
final class BeanDescriptorDraftHelp<T> {
private final BeanDescriptor<T> desc;
private final BeanProperty draftDirty;
private final BeanProperty[] resetProperties;
BeanDescriptorDraftHelp(BeanDescriptor<T> desc) {
this.desc = desc;
this.draftDirty = desc.draftDirty();
this.resetProperties = resetProperties();
}
/**
* Return the properties that are reset on draft beans after publish.
*/
private BeanProperty[] resetProperties() {
List<BeanProperty> list = new ArrayList<>();
for (BeanProperty prop : desc.propertiesNonMany()) {
if (prop.isDraftReset()) {
list.add(prop);
}
}
return list.toArray(new BeanProperty[0]);
}
/**
* Set the value of all the 'reset properties' to null on the draft bean.
*/
boolean draftReset(T draftBean) {
EntityBean draftEntityBean = (EntityBean) draftBean;
if (draftDirty != null) {
// set @DraftDirty property to false
draftDirty.setValueIntercept(draftEntityBean, false);
}
// set to null on all @DraftReset properties
for (BeanProperty resetProperty : resetProperties) {
resetProperty.setValueIntercept(draftEntityBean, null);
}
// return true if the bean is dirty (and should be persisted)
return draftEntityBean._ebean_getIntercept().isDirty();
}
/**
* Transfer the values from the draftBean to the liveBean.
* <p>
* This will recursive transfer values to all @DraftableElement properties.
* </p>
*/
@SuppressWarnings("unchecked")
public T publish(T draftBean, T liveBean) {
if (liveBean == null) {
liveBean = (T) desc.createEntityBean();
}
EntityBean draft = (EntityBean) draftBean;
EntityBean live = (EntityBean) liveBean;
BeanProperty idProperty = desc.idProperty();
if (idProperty != null) {
idProperty.publish(draft, live);
}
for (BeanProperty prop : desc.propertiesNonMany()) {
prop.publish(draft, live);
}
for (BeanPropertyAssocMany<?> many : desc.propertiesMany()) {
if (many.targetDescriptor().isDraftable()) {
many.publishMany(draft, live);
}
}
return liveBean;
}
/**
* Fetch draftable element relationships.
*/
void draftQueryOptimise(Query<T> query) {
for (BeanPropertyAssocOne<?> anOne : desc.propertiesOne()) {
if (anOne.targetDescriptor().isDraftableElement()) {
query.fetch(anOne.name());
}
}
for (BeanPropertyAssocMany<?> aMany : desc.propertiesMany()) {
if (aMany.targetDescriptor().isDraftableElement()) {
query.fetch(aMany.name());
}
}
}
}
@@ -5,20 +5,14 @@ import java.util.Map;
class BeanDescriptorInitContext {
private final Map<String, String> withHistoryTables;
private final Map<String, String> draftTables;
private final String asOfViewSuffix;
private String embeddedPrefix;
BeanDescriptorInitContext(Map<String, String> withHistoryTables, Map<String, String> draftTables, String asOfViewSuffix) {
BeanDescriptorInitContext(Map<String, String> withHistoryTables, String asOfViewSuffix) {
this.withHistoryTables = withHistoryTables;
this.draftTables = draftTables;
this.asOfViewSuffix = asOfViewSuffix;
}
void addDraft(String baseTable, String draftTable) {
draftTables.put(baseTable, draftTable);
}
void addHistory(String baseTable, String baseTableAsOf) {
withHistoryTables.put(baseTable, baseTableAsOf);
}
@@ -27,10 +21,6 @@ class BeanDescriptorInitContext {
withHistoryTables.put(intersectionTableName, intersectionTableName + asOfViewSuffix);
}
void addDraftIntersection(String intersectionPublishTable, String intersectionDraftTable) {
draftTables.put(intersectionPublishTable, intersectionDraftTable);
}
public void setEmbeddedPrefix(String embeddedPrefix) {
this.embeddedPrefix = embeddedPrefix;
}
@@ -19,24 +19,14 @@ import static io.ebeaninternal.server.persist.DmlUtil.isNullOrZero;
final class BeanDescriptorJsonHelp<T> {
private final BeanDescriptor<T> desc;
private final InheritInfo inheritInfo;
BeanDescriptorJsonHelp(BeanDescriptor<T> desc) {
this.desc = desc;
this.inheritInfo = desc.inheritInfo;
}
void jsonWrite(SpiJsonWriter writeJson, EntityBean bean, String key) throws IOException {
writeJson.writeStartObject(key);
if (inheritInfo == null) {
jsonWriteProperties(writeJson, bean);
} else {
InheritInfo localInheritInfo = inheritInfo.readType(bean.getClass());
String discValue = localInheritInfo.getDiscriminatorStringValue();
String discColumn = localInheritInfo.getDiscriminatorColumn();
writeJson.gen().writeStringField(discColumn, discValue);
localInheritInfo.desc().jsonWriteProperties(writeJson, bean);
}
jsonWriteProperties(writeJson, bean);
writeJson.writeEndObject();
}
@@ -45,11 +35,7 @@ final class BeanDescriptorJsonHelp<T> {
}
void jsonWriteDirty(SpiJsonWriter writeJson, EntityBean bean, boolean[] dirtyProps) throws IOException {
if (inheritInfo == null) {
jsonWriteDirtyProperties(writeJson, bean, dirtyProps);
} else {
desc.descOf(bean.getClass()).jsonWriteDirtyProperties(writeJson, bean, dirtyProps);
}
jsonWriteDirtyProperties(writeJson, bean, dirtyProps);
}
void jsonWriteDirtyProperties(SpiJsonWriter writeJson, EntityBean bean, boolean[] dirtyProps) throws IOException {
@@ -80,31 +66,7 @@ final class BeanDescriptorJsonHelp<T> {
throw new JsonParseException(parser, "Unexpected token " + token + " - expecting start_object", parser.getCurrentLocation());
}
}
if (desc.inheritInfo == null || !withInheritance) {
return jsonReadObject(jsonRead, path, target);
}
ObjectNode node = jsonRead.mapper().readTree(parser);
if (node.isNull()) {
return null;
}
JsonParser newParser = node.traverse();
SpiJsonReader newReader = jsonRead.forJson(newParser);
// check for the discriminator value to determine the correct sub type
String discColumn = inheritInfo.getRoot().getDiscriminatorColumn();
JsonNode discNode = node.get(discColumn);
if (discNode == null || discNode.isNull()) {
if (!desc.isAbstractType()) {
return desc.jsonReadObject(newReader, path, target);
}
String msg = "Error reading inheritance discriminator - expected [" + discColumn + "] but no json key?";
throw new JsonParseException(newParser, msg, parser.getCurrentLocation());
}
BeanDescriptor<T> inheritDesc = (BeanDescriptor<T>) inheritInfo.readType(discNode.asText()).desc();
return inheritDesc.jsonReadObject(newReader, path, target);
return jsonReadObject(jsonRead, path, target);
}
private T jsonReadObject(SpiJsonReader readJson, String path, T target) throws IOException {
@@ -3,7 +3,6 @@ package io.ebeaninternal.server.deploy;
import io.ebean.BackgroundExecutor;
import io.ebean.DatabaseBuilder;
import io.ebean.Model;
import io.ebean.RawSqlBuilder;
import io.ebean.annotation.ConstraintMode;
import io.ebean.bean.BeanCollection;
import io.ebean.bean.EntityBean;
@@ -36,12 +35,6 @@ import io.ebeaninternal.server.properties.BeanPropertiesReader;
import io.ebeaninternal.server.properties.BeanPropertyAccess;
import io.ebeaninternal.server.properties.EnhanceBeanPropertyAccess;
import io.ebeaninternal.server.type.TypeManager;
import io.ebeaninternal.xmapping.api.XmapEbean;
import io.ebeaninternal.xmapping.api.XmapEntity;
import io.ebeaninternal.xmapping.api.XmapNamedQuery;
import io.ebeaninternal.xmapping.api.XmapRawSql;
import io.ebeanservice.docstore.api.DocStoreBeanAdapter;
import io.ebeanservice.docstore.api.DocStoreFactory;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.PersistenceException;
@@ -67,7 +60,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
private final ReadAnnotations readAnnotations;
private final TransientProperties transientProperties;
private final DeployInherit deplyInherit;
private final BeanPropertyAccess beanPropertyAccess = new EnhanceBeanPropertyAccess();
private final DeployUtil deployUtil;
private final PersistControllerManager persistControllerManager;
@@ -83,7 +75,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
private final ChangeLogListener changeLogListener;
private final ChangeLogRegister changeLogRegister;
private final ChangeLogPrepare changeLogPrepare;
private final DocStoreFactory docStoreFactory;
private final MultiValueBind multiValueBind;
private final TypeManager typeManager;
private final BootupClasses bootupClasses;
@@ -91,7 +82,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
private final List<BeanDescriptor<?>> elementDescriptors = new ArrayList<>();
private final Map<Class<?>, BeanTable> beanTableMap = new HashMap<>();
private final Map<String, BeanDescriptor<?>> descMap = new HashMap<>();
private final Map<String, BeanDescriptor<?>> descQueueMap = new HashMap<>();
private final Map<String, BeanManager<?>> beanManagerMap = new HashMap<>();
private final Map<String, List<BeanDescriptor<?>>> tableToDescMap = new HashMap<>();
private final Map<String, List<BeanDescriptor<?>>> tableToViewDescMap = new HashMap<>();
@@ -112,10 +102,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
* Map of base tables to 'with history views' used to support 'as of' queries.
*/
private final Map<String, String> asOfTableMap = new HashMap<>();
/**
* Map of base tables to 'draft' tables.
*/
private final Map<String, String> draftTableMap = new HashMap<>();
// temporary collections used during startup and then cleared
private Map<Class<?>, DeployBeanInfo<?>> deployInfoMap = new HashMap<>();
@@ -129,7 +115,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
this.config = config.getConfig();
this.serverName = InternString.intern(this.config.getName());
this.cacheManager = config.getCacheManager();
this.docStoreFactory = config.getDocStoreFactory();
this.backgroundExecutor = config.getBackgroundExecutor();
this.dataSource = this.config.getDataSource();
this.encryptKeyManager = this.config.getEncryptKeyManager();
@@ -144,7 +129,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
this.createProperties = config.getDeployCreateProperties();
this.namingConvention = this.config.getNamingConvention();
this.dbIdentity = config.getDatabasePlatform().dbIdentity();
this.deplyInherit = config.getDeployInherit();
this.deployUtil = config.getDeployUtil();
this.typeManager = deployUtil.typeManager();
this.beanManagerFactory = new BeanManagerFactory(config.getDatabasePlatform());
@@ -221,15 +205,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
return config;
}
@Override
public <T> DocStoreBeanAdapter<T> createDocStoreBeanAdapter(BeanDescriptor<T> descriptor, DeployBeanDescriptor<T> deploy) {
return docStoreFactory.createAdapter(descriptor, deploy);
}
public BeanDescriptor<?> descriptorByQueueId(String queueId) {
return descQueueMap.get(queueId);
}
@Override
public SpiBeanType beanType(Class<?> entityType) {
return descriptor(entityType);
@@ -275,24 +250,15 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
return idBinderFactory.createIdBinder(idProperty);
}
/**
* Return the map of base tables to draft tables.
*/
public Map<String, String> draftTableMap() {
return draftTableMap;
}
/**
* Deploy returning the asOfTableMap (which is required by the SQL builders).
*/
public Map<String, String> deploy(List<XmapEbean> mappings) {
public Map<String, String> deploy() {
try {
createListeners();
readEntityDeploymentInitial();
readXmlMapping(mappings);
readEntityBeanTable();
readEntityDeploymentAssociations();
readInheritedIdGenerators();
// creates the BeanDescriptors
readEntityRelationships();
List<BeanDescriptor<?>> list = new ArrayList<>(descMap.values());
@@ -316,56 +282,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
}
}
private void readXmlMapping(List<XmapEbean> mappings) {
if (mappings != null) {
ClassLoader classLoader = config.getClassLoadConfig().getClassLoader();
for (XmapEbean mapping : mappings) {
List<XmapEntity> entityDeploy = mapping.getEntity();
for (XmapEntity deploy : entityDeploy) {
readEntityMapping(classLoader, deploy);
}
}
}
}
private void readEntityMapping(ClassLoader classLoader, XmapEntity entityDeploy) {
String entityClassName = entityDeploy.getClazz();
Class<?> entityClass;
try {
entityClass = Class.forName(entityClassName, false, classLoader);
} catch (Exception e) {
log.log(ERROR, "Could not load entity bean class " + entityClassName + " for ebean.xml entry");
return;
}
DeployBeanInfo<?> info = deployInfoMap.get(entityClass);
if (info == null) {
log.log(ERROR, "No entity bean for ebean.xml entry " + entityClassName);
} else {
for (XmapRawSql sql : entityDeploy.getRawSql()) {
RawSqlBuilder builder;
try {
builder = RawSqlBuilder.parse(sql.getQuery());
} catch (RuntimeException e) {
builder = RawSqlBuilder.unparsed(sql.getQuery());
}
for (Map.Entry<String, String> columnMapping : sql.getColumnMapping().entrySet()) {
builder.columnMapping(columnMapping.getKey(), columnMapping.getValue());
}
for (Map.Entry<String, String> aliasMapping : sql.getAliasMapping().entrySet()) {
builder.tableAliasMapping(aliasMapping.getKey(), aliasMapping.getValue());
}
info.addRawSql(sql.getName(), builder.create());
}
for (XmapNamedQuery namedQuery : entityDeploy.getNamedQuery()) {
info.addNamedQuery(namedQuery.getName(), namedQuery.getQuery());
}
}
}
/**
* Return the Encrypt key given the table and column name.
*/
@@ -399,7 +315,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
* Return the BeanDescriptors mapped to the table.
*/
public List<BeanDescriptor<?>> descriptors(String tableName) {
return tableToDescMap.get(tableName.toLowerCase());
return tableName == null ? Collections.emptyList() : tableToDescMap.get(tableName.toLowerCase());
}
/**
@@ -473,7 +389,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
// now that all the BeanDescriptors are in their map
// we can initialise them which sorts out circular
// dependencies for OneToMany and ManyToOne etc
BeanDescriptorInitContext initContext = new BeanDescriptorInitContext(asOfTableMap, draftTableMap, asOfViewSuffix);
BeanDescriptorInitContext initContext = new BeanDescriptorInitContext(asOfTableMap, asOfViewSuffix);
// PASS 1:
// initialise the ID properties of all the beans
@@ -483,12 +399,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
d.initialiseId(initContext);
}
// PASS 2:
// now initialise all the inherit info
for (BeanDescriptor<?> d : descMap.values()) {
d.initInheritInfo();
}
// PASS 2: Was to initialise all the inherit info
// PASS 3:
// now initialise all the associated properties
for (BeanDescriptor<?> d : descMap.values()) {
@@ -620,9 +531,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
private void registerDescriptor(DeployBeanInfo<?> info) {
BeanDescriptor<?> desc = new BeanDescriptor<>(this, info.getDescriptor());
descMap.put(desc.type().getName(), desc);
if (desc.isDocStoreMapped()) {
descQueueMap.put(desc.docStoreQueueId(), desc);
}
for (BeanPropertyAssocMany<?> many : desc.propertiesMany()) {
if (many.isElementCollection()) {
elementDescriptors.add(many.elementDescriptor());
@@ -692,20 +600,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
}
}
private void readInheritedIdGenerators() {
for (DeployBeanInfo<?> info : deployInfoMap.values()) {
DeployBeanDescriptor<?> descriptor = info.getDescriptor();
InheritInfo inheritInfo = descriptor.getInheritInfo();
if (inheritInfo != null && !inheritInfo.isRoot()) {
DeployBeanInfo<?> rootBeanInfo = deployInfoMap.get(inheritInfo.getRoot().getType());
PlatformIdGenerator rootIdGen = rootBeanInfo.getDescriptor().getIdGenerator();
if (rootIdGen != null) {
descriptor.setIdGenerator(rootIdGen);
}
}
}
}
/**
* Create the BeanTable from the deployment information gathered so far.
*/
@@ -728,9 +622,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
for (DeployBeanInfo<?> info : deployInfoMap.values()) {
secondaryPropsJoins(info);
}
for (DeployBeanInfo<?> info : deployInfoMap.values()) {
setInheritanceInfo(info);
}
for (DeployBeanInfo<?> info : deployInfoMap.values()) {
if (!info.isEmbedded()) {
registerDescriptor(info);
@@ -738,28 +629,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
}
}
/**
* Sets the inheritance info.
*/
private void setInheritanceInfo(DeployBeanInfo<?> info) {
for (DeployBeanPropertyAssocOne<?> oneProp : info.getDescriptor().propertiesAssocOne()) {
if (!oneProp.isTransient()) {
DeployBeanInfo<?> assoc = deployInfoMap.get(oneProp.getTargetType());
if (assoc != null) {
oneProp.getTableJoin().setInheritInfo(assoc.getDescriptor().getInheritInfo());
}
}
}
for (DeployBeanPropertyAssocMany<?> manyProp : info.getDescriptor().propertiesAssocMany()) {
if (!manyProp.isTransient()) {
DeployBeanInfo<?> assoc = deployInfoMap.get(manyProp.getTargetType());
if (assoc != null) {
manyProp.getTableJoin().setInheritInfo(assoc.getDescriptor().getInheritInfo());
}
}
}
}
private void secondaryPropsJoins(DeployBeanInfo<?> info) {
DeployBeanDescriptor<?> descriptor = info.getDescriptor();
for (DeployBeanProperty prop : descriptor.propertiesBase()) {
@@ -893,13 +762,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
orderProperty.setDbUpdateable(orderColumn.isUpdatable());
orderProperty.setDbRead(true);
orderProperty.setOwningType(targetDesc.getBeanType());
final InheritInfo targetInheritInfo = targetDesc.getInheritInfo();
if (targetInheritInfo != null) {
for (InheritInfo child : targetInheritInfo.getChildren()) {
final DeployBeanDescriptor<?> childDescriptor = deployInfoMap.get(child.getType()).getDescriptor();
childDescriptor.setOrderColumn(orderProperty);
}
}
targetDesc.setOrderColumn(orderProperty);
}
@@ -1015,13 +877,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
// skip mapping check
return;
}
DeployBeanDescriptor<?> targetDesc = targetDescriptor(prop);
if (targetDesc.isDraftableElement()) {
// automatically turning on orphan removal and CascadeType.ALL
prop.setModifyListenMode(BeanCollection.ModifyListenMode.REMOVALS);
prop.getCascadeInfo().setSaveDelete(true, true);
}
if (prop.hasOrderColumn()) {
makeOrderColumn(prop);
}
@@ -1047,6 +902,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
String mappedBy = prop.getMappedBy();
// get the mappedBy property
DeployBeanDescriptor<?> targetDesc = targetDescriptor(prop);
DeployBeanPropertyAssocOne<?> mappedAssocOne = mappedManyToOne(prop, targetDesc, mappedBy);
DeployTableJoin tableJoin = prop.getTableJoin();
if (!tableJoin.hasJoinColumns()) {
@@ -1088,9 +944,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
// get the bean descriptor that holds the mappedBy property
String mappedBy = prop.getMappedBy();
if (mappedBy == null) {
if (targetDescriptor(prop).isDraftable()) {
prop.setIntersectionDraftTable();
}
return;
}
@@ -1115,10 +968,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
DeployTableJoin inverseJoin = new DeployTableJoin();
mappedIntJoin.copyTo(inverseJoin, false, intTableName);
prop.setInverseJoin(inverseJoin);
if (targetDesc.isDraftable()) {
prop.setIntersectionDraftTable();
}
}
private DeployBeanPropertyAssocMany<?> mappedManyToMany(DeployBeanPropertyAssocMany<?> prop, String mappedBy, DeployBeanDescriptor<?> targetDesc) {
@@ -1160,9 +1009,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
beanLifecycleAdapterFactory.addLifecycleMethods(desc);
// set bean controller, finder and listener
setBeanControllerFinderListener(desc);
deplyInherit.process(desc);
desc.checkInheritanceMapping();
createProperties.createProperties(desc);
DeployBeanInfo<T> info = new DeployBeanInfo<>(deployUtil, desc);
readAnnotations.readInitial(info);
@@ -1235,8 +1081,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
if (identityMode.isIdentity()) {
// used when getGeneratedKeys is not supported (SQL Server 2000, SAP Hana)
String selectLastInsertedId = dbIdentity.getSelectLastInsertedId(desc.getBaseTable());
String selectLastInsertedIdDraft = (!desc.isDraftable()) ? selectLastInsertedId : dbIdentity.getSelectLastInsertedId(desc.getDraftTable());
desc.setSelectLastInsertedId(selectLastInsertedId, selectLastInsertedIdDraft);
desc.setSelectLastInsertedId(selectLastInsertedId);
return;
}
@@ -7,7 +7,6 @@ import io.ebean.core.type.ScalarType;
import io.ebeaninternal.server.cache.SpiCacheManager;
import io.ebeaninternal.server.deploy.id.IdBinder;
import io.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
import io.ebeanservice.docstore.api.DocStoreBeanAdapter;
/**
* Provides a method to find a BeanDescriptor.
@@ -57,11 +56,6 @@ public interface BeanDescriptorMap {
*/
IdBinder createIdBinder(BeanProperty id);
/**
* Create a doc store specific adapter for this bean type.
*/
<T> DocStoreBeanAdapter<T> createDocStoreBeanAdapter(BeanDescriptor<T> descriptor, DeployBeanDescriptor<T> deploy);
/**
* Return the scalarType for the given JDBC type.
*/
@@ -36,10 +36,6 @@ import io.ebeaninternal.server.query.SqlBeanLoad;
import io.ebeaninternal.server.query.SqlJoinType;
import io.ebeaninternal.server.type.*;
import io.ebeaninternal.util.ValueUtil;
import io.ebeanservice.docstore.api.mapping.DocMappingBuilder;
import io.ebeanservice.docstore.api.mapping.DocPropertyMapping;
import io.ebeanservice.docstore.api.mapping.DocPropertyOptions;
import io.ebeanservice.docstore.api.support.DocStructure;
import jakarta.persistence.PersistenceException;
import java.io.DataInput;
@@ -143,7 +139,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
@SuppressWarnings("rawtypes")
final ScalarType scalarType;
private final DocPropertyOptions docOptions;
/**
* The length or precision for DB column.
*/
@@ -171,10 +166,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
final boolean jsonDeserialize;
private final boolean unmappedJson;
private final boolean tenantId;
private final boolean draft;
private final boolean draftOnly;
private final boolean draftDirty;
private final boolean draftReset;
private final boolean softDelete;
private final String softDeleteDbSet;
private final String softDeleteDbPredicate;
@@ -201,10 +192,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
this.excludedFromHistory = deploy.isExcludedFromHistory();
this.unmappedJson = deploy.isUnmappedJson();
this.tenantId = deploy.isTenantId();
this.draft = deploy.isDraft();
this.draftDirty = deploy.isDraftDirty();
this.draftOnly = deploy.isDraftOnly();
this.draftReset = deploy.isDraftReset();
this.secondaryTable = deploy.isSecondaryTable();
if (secondaryTable) {
this.secondaryTableJoin = new TableJoin(deploy.getSecondaryTableJoin());
@@ -243,7 +230,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
this.lob = isLobType(dbType);
this.propertyType = deploy.getPropertyType();
this.field = deploy.getField();
this.docOptions = deploy.getDocPropertyOptions();
this.elPlaceHolder = tableAliasIntern(descriptor, deploy.getElPlaceHolder(), false, null);
this.elPlaceHolderEncrypted = tableAliasIntern(descriptor, deploy.getElPlaceHolder(), dbEncrypted, dbColumn);
this.elPrefix = deploy.getElPrefix();
@@ -296,10 +282,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
this.aggregation = null;
this.excludedFromHistory = source.excludedFromHistory;
this.tenantId = source.tenantId;
this.draft = source.draft;
this.draftDirty = source.draftDirty;
this.draftOnly = source.draftOnly;
this.draftReset = source.draftReset;
this.softDelete = source.softDelete;
this.softDeleteDbSet = source.softDeleteDbSet;
this.softDeleteDbPredicate = source.softDeleteDbPredicate;
@@ -338,7 +320,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
this.lob = isLobType(dbType);
this.propertyType = source.type();
this.field = source.field();
this.docOptions = source.docOptions;
this.unmappedJson = source.unmappedJson;
this.elPrefix = override.replace(source.elPrefix, source.dbColumn);
this.elPlaceHolder = override.replace(source.elPlaceHolder, source.dbColumn);
@@ -483,7 +464,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
ctx.appendFormulaSelect(aggregation);
} else if (formula) {
ctx.appendFormulaSelect(sqlFormulaSelect);
} else if (!isTransient && !ignoreDraftOnlyProperty(ctx.isDraftQuery())) {
} else if (!isTransient) {
if (secondaryTableJoin != null) {
ctx.pushTableAlias(ctx.relativePrefix(secondaryTableJoinPrefix));
}
@@ -590,17 +571,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
return local;
}
/**
* Copy/set the property value from the draft bean to the live bean.
*/
public void publish(EntityBean draftBean, EntityBean liveBean) {
if (!version && !draftOnly) {
// set property value from draft to live
Object value = getValueIntercept(draftBean);
setValueIntercept(liveBean, value);
}
}
/**
* Return the DB literal expression to set the deleted state to true.
*/
@@ -1090,16 +1060,8 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
/**
* Return true if this property is loadable from a resultSet.
*/
public boolean isLoadProperty(boolean draftQuery) {
return !ignoreDraftOnlyProperty(draftQuery) && (!isTransient || formula);
}
/**
* Return true if this is a draftOnly property on a non-asDraft query and as such this
* property should not be included in a sql query.
*/
private boolean ignoreDraftOnlyProperty(boolean draftQuery) {
return draftOnly && !draftQuery;
public boolean isLoadProperty() {
return !isTransient || formula;
}
/**
@@ -1248,36 +1210,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
return tenantId;
}
/**
* Return true if this property only exists on the draft table.
*/
public boolean isDraftOnly() {
return draftOnly;
}
/**
* Return true if this property is a boolean flag on a draftable bean
* indicating if the instance is a draft or live bean.
*/
public boolean isDraft() {
return draft;
}
/**
* Return true if this property is a boolean flag only on the draft table
* indicating that when the draft is different from the published row.
*/
public boolean isDraftDirty() {
return draftDirty;
}
/**
* Return true if this property is reset/cleared on publish (on the draft bean).
*/
boolean isDraftReset() {
return draftReset;
}
/**
* Return true if this property is the soft delete property.
*/
@@ -1344,15 +1276,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
return name;
}
/**
* Append this property to the document store based on includeByDefault setting.
*/
public void docStoreInclude(boolean includeByDefault, DocStructure docStructure) {
if (includeByDefault) {
docStructure.addProperty(name);
}
}
public boolean isJsonSerialize() {
return jsonSerialize;
}
@@ -1462,24 +1385,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
}
}
/**
* Add to the document mapping if this property is included for this index.
*/
public void docStoreMapping(DocMappingBuilder mapping, String prefix) {
if (mapping.includesProperty(prefix, name)) {
DocPropertyType type = scalarType.docType();
DocPropertyOptions options = docOptions.copy();
if (isKeywordType(type, options)) {
type = DocPropertyType.KEYWORD;
}
mapping.add(new DocPropertyMapping(name, type, options));
}
}
private boolean isKeywordType(DocPropertyType type, DocPropertyOptions docOptions) {
return type == DocPropertyType.TEXT && (docOptions.isCode() || id || discriminator);
}
public void merge(EntityBean bean, EntityBean existing) {
// do nothing unless Many property
}
@@ -4,9 +4,6 @@ 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;
import io.ebean.util.SplitName;
import io.ebeaninternal.api.CoreLog;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
@@ -24,9 +21,6 @@ import io.ebeaninternal.server.query.STreePropertyAssoc;
import io.ebeaninternal.server.query.STreeType;
import io.ebeaninternal.server.query.SqlJoinType;
import io.ebeaninternal.server.querydefn.DefaultOrmQuery;
import io.ebeanservice.docstore.api.mapping.DocMappingBuilder;
import io.ebeanservice.docstore.api.mapping.DocPropertyMapping;
import io.ebeanservice.docstore.api.support.DocStructure;
import jakarta.persistence.PersistenceException;
import java.util.ArrayList;
@@ -45,7 +39,6 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
*/
BeanDescriptor<T> targetDescriptor;
IdBinder targetIdBinder;
InheritInfo targetInheritInfo;
String targetIdProperty;
/**
* Derived list of exported property and matching foreignKey
@@ -69,7 +62,6 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
*/
final BeanTable beanTable;
final String mappedBy;
private final String docStoreDoc;
private final String extraWhere;
private final int fetchPreference;
private boolean saveRecurseSkippable;
@@ -83,7 +75,6 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
this.extraWhere = InternString.intern(deploy.getExtraWhere());
this.beanTable = deploy.getBeanTable();
this.mappedBy = InternString.intern(deploy.getMappedBy());
this.docStoreDoc = deploy.getDocStoreDoc();
this.tableJoin = new TableJoin(deploy.getTableJoin());
this.targetType = deploy.getTargetType();
this.cascadeInfo = deploy.getCascadeInfo();
@@ -100,7 +91,6 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
extraWhere = source.extraWhere;
beanTable = source.beanTable;
mappedBy = source.mappedBy;
docStoreDoc = source.docStoreDoc;
targetType = source.targetType;
cascadeInfo = source.cascadeInfo;
fetchPreference = source.fetchPreference;
@@ -121,7 +111,6 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
targetDescriptor = descriptor.descriptor(targetType);
if (!isTransient) {
targetIdBinder = targetDescriptor.idBinder();
targetInheritInfo = targetDescriptor.inheritInfo();
saveRecurseSkippable = targetDescriptor.isSaveRecurseSkippable();
if (!targetIdBinder.isComplexId()) {
targetIdProperty = targetIdBinder.idSelect();
@@ -310,59 +299,6 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
return extraWhere;
}
/**
* Return the elastic search doc for this embedded property.
*/
private String docStoreDoc() {
return docStoreDoc;
}
/**
* Determine if and how the associated bean is included in the doc store document.
*/
@Override
public void docStoreInclude(boolean includeByDefault, DocStructure docStructure) {
String embeddedDoc = docStoreDoc();
if (embeddedDoc == null) {
// not annotated so use include by default
// which is *ToOne included and *ToMany excluded
if (includeByDefault) {
docStoreIncludeByDefault(docStructure.doc());
}
} else {
// explicitly annotated to be included
if (embeddedDoc.isEmpty()) {
embeddedDoc = "*";
}
// add in a nested way
PathProperties embDoc = PathProperties.parse(embeddedDoc);
docStructure.addNested(name, embDoc);
}
}
/**
* Include the property in the document store by default.
*/
void docStoreIncludeByDefault(PathProperties pathProps) {
pathProps.addToPath(null, name);
}
@Override
public void docStoreMapping(DocMappingBuilder mapping, String prefix) {
if (mapping.includesPath(prefix, name)) {
String fullName = SplitName.add(prefix, name);
DocPropertyType type = isMany() ? DocPropertyType.LIST : DocPropertyType.OBJECT;
DocPropertyMapping nested = new DocPropertyMapping(name, type);
mapping.push(nested);
targetDescriptor.docStoreMapping(mapping, fullName);
mapping.pop();
if (!nested.children().isEmpty()) {
mapping.add(nested);
}
}
}
/**
* Return true if this association is updateable.
*/
@@ -41,8 +41,6 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
* Join for manyToMany intersection table.
*/
private final TableJoin intersectionJoin;
private final String intersectionPublishTable;
private final String intersectionDraftTable;
private final boolean orphanRemoval;
private IntersectionTable intersectionTable;
/**
@@ -102,13 +100,6 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
this.mapKey = deploy.getMapKey();
this.fetchOrderBy = deploy.getFetchOrderBy();
this.intersectionJoin = deploy.createIntersectionTableJoin();
if (intersectionJoin != null) {
this.intersectionPublishTable = intersectionJoin.getTable();
this.intersectionDraftTable = deploy.getIntersectionDraftTable();
} else {
this.intersectionPublishTable = null;
this.intersectionDraftTable = null;
}
this.inverseJoin = deploy.createInverseTableJoin();
this.modifyListenMode = deploy.getModifyListenMode();
this.jsonHelp = descriptor.isJacksonCorePresent() ? new BeanPropertyAssocManyJsonHelp(this) : null;
@@ -186,11 +177,6 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
return manyToMany && !excludedFromHistory && descriptor.isHistorySupport();
}
@Override
protected void docStoreIncludeByDefault(PathProperties pathProps) {
// by default not including "Many" properties in document store
}
@Override
public void registerColumn(BeanDescriptor<?> desc, String prefix) {
if (targetDescriptor != null) {
@@ -352,13 +338,8 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
}
}
public void addWhereParentIdIn(SpiQuery<?> query, List<Object> parentIds, boolean useDocStore) {
if (useDocStore) {
// assumes the ManyToOne property is included
query.where().in(childMasterIdProperty, parentIds);
} else {
sqlHelp.addWhereParentIdIn(query, parentIds);
}
public void addWhereParentIdIn(SpiQuery<?> query, List<Object> parentIds) {
sqlHelp.addWhereParentIdIn(query, parentIds);
}
/**
@@ -375,7 +356,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
}
private IntersectionTable initIntersectionTable() {
IntersectionBuilder row = new IntersectionBuilder(intersectionPublishTable, intersectionDraftTable);
IntersectionBuilder row = new IntersectionBuilder(intersectionJoin.getTable());
for (ExportedProperty exportedProperty : exportedProperties) {
row.addColumn(exportedProperty.getForeignDbColumn());
}
@@ -434,7 +415,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
StringBuilder sb = new StringBuilder(50).append("from "); // use from to stop parsing on table name
SpiQuery<?> query = request.queryRequest().query();
if (hasJoinTable()) {
sb.append(query.isAsDraft() ? intersectionDraftTable : intersectionPublishTable);
sb.append(intersectionJoin.getTable());
} else {
sb.append(targetDescriptor.baseTable(query.temporalMode()));
}
@@ -764,37 +745,21 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
return row;
}
public IntersectionRow buildManyToManyDeleteChildren(EntityBean parentBean, boolean publish) {
String tableName = publish ? intersectionPublishTable : intersectionDraftTable;
public IntersectionRow buildManyToManyDeleteChildren(EntityBean parentBean) {
String tableName = intersectionJoin.getTable();
IntersectionRow row = new IntersectionRow(tableName);
buildExport(row, parentBean);
return row;
}
public IntersectionRow buildManyToManyMapBean(EntityBean parent, EntityBean other, boolean publish) {
String tableName = publish ? intersectionPublishTable : intersectionDraftTable;
public IntersectionRow buildManyToManyMapBean(EntityBean parent, EntityBean other) {
String tableName = intersectionJoin.getTable();
IntersectionRow row = new IntersectionRow(tableName);
buildExport(row, parent);
buildImport(row, other);
return row;
}
/**
* Register the mapping of intersection table to associated draft table.
*/
void registerDraftIntersectionTable(BeanDescriptorInitContext initContext) {
if (hasDraftIntersection()) {
initContext.addDraftIntersection(intersectionPublishTable, intersectionDraftTable);
}
}
/**
* Return true if the relationship is a ManyToMany with the intersection having an associated draft table.
*/
private boolean hasDraftIntersection() {
return intersectionDraftTable != null && !intersectionDraftTable.equals(intersectionPublishTable);
}
/**
* Bind the two side of a many to many to the given SqlUpdate.
*/
@@ -879,55 +844,6 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
jsonHelp.jsonRead(readJson, parentBean);
}
@SuppressWarnings("unchecked")
void publishMany(EntityBean draft, EntityBean live) {
// collections will not be null due to enhancement
BeanCollection<T> draftVal = (BeanCollection<T>) getValueIntercept(draft);
BeanCollection<T> liveVal = (BeanCollection<T>) getValueIntercept(live);
// Organise the existing live beans into map keyed by id
Map<Object, T> liveBeansAsMap = liveBeansAsMap(liveVal);
// publish from each draft to live bean creating new live beans as required
draftVal.size();
Collection<T> actualDetails = draftVal.actualDetails();
for (T bean : actualDetails) {
Object id = targetDescriptor.id(bean);
T liveBean = liveBeansAsMap.remove(id);
if (isManyToMany()) {
if (liveBean == null) {
// add new relationship (Map not allowed here)
liveVal.addBean(targetDescriptor.createReference(id, null));
}
} else {
// recursively publish the OneToMany child bean
T newLive = targetDescriptor.publish(bean, liveBean);
if (liveBean == null) {
// Map not allowed here
liveVal.addBean(newLive);
}
}
}
// anything remaining should be deleted (so remove from modify aware collection)
Collection<T> values = liveBeansAsMap.values();
for (T value : values) {
liveVal.removeBean(value);
}
}
@SuppressWarnings("unchecked")
private Map<Object, T> liveBeansAsMap(BeanCollection<?> liveVal) {
liveVal.size();
Collection<?> liveBeans = liveVal.actualDetails();
Map<Object, T> liveMap = new LinkedHashMap<>();
for (Object liveBean : liveBeans) {
Object id = targetDescriptor.id(liveBean);
liveMap.put(id, (T) liveBean);
}
return liveMap;
}
public boolean isIncludeCascadeSave() {
// Note ManyToMany always included as we always 'save'
// the relationship via insert/delete of intersection table
@@ -947,10 +863,6 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
return sqlHelp.insertElementCollection();
}
public boolean isTargetDocStoreMapped() {
return targetDescriptor.isDocStoreMapped();
}
void jsonWriteMapEntry(SpiJsonWriter ctx, Map.Entry<?, ?> entry) throws IOException {
if (elementDescriptor != null) {
elementDescriptor.jsonWriteMapEntry(ctx, entry);
@@ -17,7 +17,6 @@ import io.ebeaninternal.api.json.SpiJsonReader;
import io.ebeaninternal.api.json.SpiJsonWriter;
import io.ebeaninternal.server.cache.CacheChangeSet;
import io.ebeaninternal.server.cache.CachedBeanData;
import io.ebeaninternal.server.cache.CachedBeanId;
import io.ebeaninternal.server.core.DefaultSqlUpdate;
import io.ebeaninternal.server.deploy.id.ImportedId;
import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocOne;
@@ -125,6 +124,9 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
// no imported or exported information
} else if (!oneToOneExported) {
importedId = createImportedId(this, targetDescriptor, tableJoin);
if (importedId == null) {
throw new IllegalStateException("Missing @Id property on " + targetDescriptor);
}
if (importedId.isScalar()) {
// limit JoinColumn mapping to the @Id / primary key
TableJoinColumn[] columns = tableJoin.columns();
@@ -319,15 +321,6 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
public void buildRawSqlSelectChain(String prefix, List<String> selectChain) {
prefix = SplitName.add(prefix, name);
if (!embedded) {
InheritInfo inheritInfo = targetDescriptor.inheritInfo();
if (inheritInfo != null) {
// expect the discriminator column to be included in order
// to determine the inheritance type so we add it to the
// selectChain (so that it takes a position in the resultSet)
String discriminatorColumn = inheritInfo.getDiscriminatorColumn();
String discProperty = prefix + "." + discriminatorColumn;
selectChain.add(discProperty);
}
if (targetIdBinder == null) {
throw new IllegalStateException("No Id binding property for " + fullName()
+ ". Probably a missing @OneToOne mapping annotation on this relationship?");
@@ -420,19 +413,11 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
}
if (embedded) {
return targetDescriptor.cacheEmbeddedBeanExtract((EntityBean) ap);
} else if (targetInheritInfo != null) {
return createCacheBeanId(ap);
} else {
return targetDescriptor.idProperty().getCacheDataValue((EntityBean) ap);
}
}
private Object createCacheBeanId(Object bean) {
final BeanDescriptor<?> desc = targetDescriptor.descOf(bean.getClass());
final Object id = desc.idProperty().getCacheDataValue((EntityBean) bean);
return new CachedBeanId(desc.discValue(), id);
}
@Override
public String format(Object value) {
return targetDescriptor.idBinder().cacheKey(value);
@@ -446,20 +431,11 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
if (embedded) {
setValue(bean, targetDescriptor.cacheEmbeddedBeanLoad((CachedBeanData) cacheData, context));
} else {
if (cacheData instanceof CachedBeanId) {
setValue(bean, refInheritBean((CachedBeanId) cacheData, context));
} else {
setValue(bean, refBean(targetDescriptor, cacheData, context));
}
setValue(bean, refBean(targetDescriptor, cacheData, context));
}
}
}
private Object refInheritBean(CachedBeanId cacheId, PersistenceContext context) {
final InheritInfo rowInheritInfo = targetInheritInfo.readType(cacheId.getDiscValue());
return refBean(rowInheritInfo.desc(), cacheId.getId(), context);
}
private Object refBean(BeanDescriptor<?> desc, Object id, PersistenceContext context) {
if (id instanceof String) {
id = desc.idProperty().scalarType.parse((String) id);
@@ -718,11 +694,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
} else if (oneToOneExported) {
return new AssocOneHelpRefExported(this);
} else {
if (targetInheritInfo != null) {
return new AssocOneHelpRefInherit(this);
} else {
return new AssocOneHelpRefSimple(this, embeddedPrefix);
}
return new AssocOneHelpRefSimple(this, embeddedPrefix);
}
}
@@ -79,11 +79,6 @@ public interface DbReadContext {
*/
SpiQuery.Mode queryMode();
/**
* Return true if the underlying query is a 'asDraft' query.
*/
boolean isDraftQuery();
/**
* Return true if this request disables lazy loading.
*/
@@ -124,11 +124,6 @@ public interface DbSqlContext {
*/
int asOfTableCount();
/**
* Return true if the query is a 'asDraft' query.
*/
boolean isDraftQuery();
/**
* Start group by clause.
*/
@@ -1,78 +0,0 @@
package io.ebeaninternal.server.deploy;
import io.ebean.annotation.DocCode;
import io.ebean.annotation.DocProperty;
import io.ebean.annotation.DocSortable;
import io.ebeanservice.docstore.api.mapping.DocPropertyOptions;
/**
* The options for document property collected when reading deployment mapping.
*/
public final class DeployDocPropertyOptions {
private static final DocPropertyOptions EMPTY = new DocPropertyOptions();
private DocPropertyOptions mapping;
private void createOptions() {
if (mapping == null) {
mapping = new DocPropertyOptions();
}
}
/**
* Read the DocProperty deployment options.
*/
public void setDocProperty(DocProperty doc) {
createOptions();
mapping.apply(doc);
}
/**
* Read the DocSortable deployment options.
*/
public void setDocSortable(DocSortable doc) {
createOptions();
mapping.sortable(true);
setStore(doc.store());
setBoost(doc.boost());
setNullValue(doc.nullValue());
}
/**
* Read the DocCode deployment options.
*/
public void setDocCode(DocCode doc) {
createOptions();
mapping.code(true);
setStore(doc.store());
setBoost(doc.boost());
setNullValue(doc.nullValue());
}
private void setNullValue(String value) {
if (!value.isEmpty()) {
mapping.nullValue(value);
}
}
private void setBoost(float boost) {
if (Float.compare(boost, 1.0F) != 0) {
mapping.boost(boost);
}
}
private void setStore(boolean store) {
if (store) {
mapping.store(true);
}
}
/**
* Return the DocPropertyOptions with the collected options.
*/
public DocPropertyOptions create() {
return (mapping == null) ? EMPTY : mapping;
}
}
@@ -1,360 +0,0 @@
package io.ebeaninternal.server.deploy;
import io.ebean.bean.EntityBean;
import io.ebeaninternal.server.core.InternString;
import io.ebeaninternal.server.deploy.id.IdBinder;
import io.ebeaninternal.server.deploy.parse.DeployInheritInfo;
import io.ebeaninternal.server.query.SqlTreeProperties;
import jakarta.persistence.PersistenceException;
import java.lang.reflect.Modifier;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
/**
* Represents a node in the Inheritance tree. Holds information regarding Super Subclass support.
*/
public final class InheritInfo {
private final String discriminatorStringValue;
private final Object discriminatorValue;
private final String discriminatorColumn;
private final int discriminatorType;
private final int discriminatorLength;
private final String columnDefn;
private final String where;
private final Class<?> type;
private final List<InheritInfo> children = new ArrayList<>();
/**
* Map of discriminator values to InheritInfo.
*/
private final HashMap<String, InheritInfo> discMap;
/**
* Map of class types to InheritInfo (taking into account subclass proxy classes).
*/
private final HashMap<String, InheritInfo> typeMap;
private final InheritInfo parent;
private final InheritInfo root;
private BeanDescriptor<?> descriptor;
public InheritInfo(InheritInfo r, InheritInfo parent, DeployInheritInfo deploy) {
this.parent = parent;
this.type = deploy.getType();
this.discriminatorColumn = InternString.intern(deploy.getColumnName(parent));
this.discriminatorValue = deploy.getDiscriminatorObjectValue();
this.discriminatorStringValue = deploy.getDiscriminatorStringValue();
this.discriminatorType = deploy.getDiscriminatorType(parent);
this.discriminatorLength = deploy.getColumnLength(parent);
this.columnDefn = deploy.getColumnDefn();
this.where = InternString.intern(deploy.getWhere());
if (r == null) {
// this is a root node
root = this;
discMap = new HashMap<>();
typeMap = new HashMap<>();
registerWithRoot(this);
} else {
this.root = r;
// register with the root node...
discMap = null;
typeMap = null;
root.registerWithRoot(this);
}
}
/**
* Visit all the children in the inheritance tree.
*/
public void visitChildren(InheritInfoVisitor visitor) {
for (InheritInfo child : children) {
visitor.visit(child);
child.visitChildren(visitor);
}
}
/**
* Append check constraint values for the entire inheritance hierarchy.
*/
public void appendCheckConstraintValues(final String propertyName, final Set<String> checkConstraintValues) {
visitChildren(inheritInfo -> {
BeanProperty prop = inheritInfo.desc().beanProperty(propertyName);
if (prop != null) {
Set<String> values = prop.dbCheckConstraintValues();
if (values != null) {
checkConstraintValues.addAll(values);
}
}
});
}
/**
* return true if anything in the inheritance hierarchy has a relationship with a save cascade on
* it.
*/
boolean isSaveRecurseSkippable() {
return root.isNodeSaveRecurseSkippable();
}
private boolean isNodeSaveRecurseSkippable() {
if (!descriptor.isSaveRecurseSkippable()) {
return false;
}
for (InheritInfo child : children) {
if (!child.isNodeSaveRecurseSkippable()) {
return false;
}
}
return true;
}
/**
* return true if anything in the inheritance hierarchy has a relationship with a delete cascade
* on it.
*/
boolean isDeleteRecurseSkippable() {
return root.isNodeDeleteRecurseSkippable();
}
private boolean isNodeDeleteRecurseSkippable() {
if (!descriptor.isDeleteRecurseSkippable()) {
return false;
}
for (InheritInfo child : children) {
if (!child.isNodeDeleteRecurseSkippable()) {
return false;
}
}
return true;
}
/**
* Set the descriptor for this node.
*/
public void setDescriptor(BeanDescriptor<?> descriptor) {
this.descriptor = descriptor;
}
/**
* Return the associated BeanDescriptor for this node.
*/
public BeanDescriptor<?> desc() {
return descriptor;
}
/**
* Return the local properties for this node in the hierarchy.
*/
public BeanProperty[] localProperties() {
return descriptor.propertiesLocal();
}
/**
* Return the children.
*/
public List<InheritInfo> getChildren() {
return children;
}
/**
* Return true if this node has children.
* <p>
* When an inheritance node has no children then we don't need
* the discriminator column as the type is effectively known.
*/
public boolean hasChildren() {
return !children.isEmpty();
}
/**
* Get the bean property additionally looking in the sub types.
*/
BeanProperty findSubTypeProperty(String propertyName) {
BeanProperty prop;
for (InheritInfo childInfo : children) {
// recursively search this child bean descriptor
prop = childInfo.desc().findProperty(propertyName);
if (prop != null) {
return prop;
}
}
return null;
}
/**
* Add the local properties for each sub class below this one.
*/
public void addChildrenProperties(SqlTreeProperties selectProps) {
for (InheritInfo childInfo : children) {
selectProps.add(childInfo.descriptor.propertiesLocal());
childInfo.addChildrenProperties(selectProps);
}
}
/**
* Return the associated InheritInfo for this DB row read.
*/
public InheritInfo readType(DbReadContext ctx) throws SQLException {
return readType(ctx.dataReader().getString());
}
/**
* Return the associated InheritInfo for this discriminator value.
*/
InheritInfo readType(String discValue) {
if (discValue == null) {
return null;
}
InheritInfo typeInfo = root.getType(discValue);
if (typeInfo == null) {
throw new PersistenceException("Inheritance type for discriminator value [" + discValue + "] was not found?");
}
return typeInfo;
}
/**
* Return the associated InheritInfo for this bean type.
*/
public InheritInfo readType(Class<?> beanType) {
InheritInfo typeInfo = root.getTypeByClass(beanType);
if (typeInfo == null) {
throw new PersistenceException("Inheritance type for bean type [" + beanType.getName() + "] was not found?");
}
return typeInfo;
}
/**
* Create an EntityBean for this type.
*/
public EntityBean createEntityBean() {
return descriptor.createEntityBean();
}
/**
* Return the IdBinder for this type.
*/
public IdBinder getIdBinder() {
return descriptor.idBinder();
}
/**
* return the type.
*/
public Class<?> getType() {
return type;
}
/**
* Return the root node of the tree.
* <p>
* The root has a map of discriminator values to types.
* </p>
*/
public InheritInfo getRoot() {
return root;
}
/**
* Return the parent node.
*/
public InheritInfo getParent() {
return parent;
}
/**
* Return true if this is the root node.
*/
public boolean isRoot() {
return parent == null;
}
/**
* Return true if this is considered a concrete type in the inheritance hierarchy.
*/
public boolean isConcrete() {
return !Modifier.isAbstract(type.getModifiers());
}
/**
* For a discriminator get the inheritance information for this tree.
*/
public InheritInfo getType(String discValue) {
return discMap.get(discValue);
}
/**
* Return the InheritInfo for the given bean type.
*/
private InheritInfo getTypeByClass(Class<?> beanType) {
return typeMap.get(beanType.getName());
}
private void registerWithRoot(InheritInfo info) {
if (info.getDiscriminatorStringValue() != null) {
String stringDiscValue = info.getDiscriminatorStringValue();
discMap.put(stringDiscValue, info);
}
typeMap.put(info.getType().getName(), info);
}
/**
* Add a child node.
*/
public void addChild(InheritInfo childInfo) {
children.add(childInfo);
}
/**
* Return the derived where for the discriminator.
*/
public String getWhere() {
return where;
}
/**
* Return the column name of the discriminator.
*/
public String getDiscriminatorColumn() {
return discriminatorColumn;
}
/**
* Return the sql type of the discriminator value.
*/
public int getDiscriminatorType() {
return discriminatorType;
}
/**
* Return the length of the discriminator column.
*/
public int getColumnLength() {
return discriminatorLength;
}
/**
* Return the explicit column definition.
*/
public String getColumnDefn() {
return columnDefn;
}
/**
* Return the discriminator value for this node.
*/
String getDiscriminatorStringValue() {
return discriminatorStringValue;
}
public Object getDiscriminatorValue() {
return discriminatorValue;
}
@Override
public String toString() {
return "InheritInfo " + type.getName() + " disc:" + discriminatorStringValue;
}
}

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