mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0842a3f3e2 | ||
|
|
bd0cad723d | ||
|
|
c83c85efc3 | ||
|
|
b6b8f77213 | ||
|
|
770eb06cab | ||
|
|
180b4d6e46 | ||
|
|
5377454476 | ||
|
|
dbbf6dd566 | ||
|
|
4b9d4d0a90 | ||
|
|
90fc4466bf | ||
|
|
0d69377f8b | ||
|
|
359a55d7a5 | ||
|
|
b7804e7486 | ||
|
|
febb018036 | ||
|
|
dc0585246f | ||
|
|
22c1848f58 | ||
|
|
054ea26893 | ||
|
|
8c30b66d39 | ||
|
|
14f9fe68f7 | ||
|
|
d56ca5b841 | ||
|
|
3f97f0f212 | ||
|
|
60e0c552ab | ||
|
|
f889628677 | ||
|
|
128bd171f5 | ||
|
|
6402a346a1 | ||
|
|
0ab0f9c569 | ||
|
|
19e21e17cc | ||
|
|
7e60c66759 | ||
|
|
4f18dc339f | ||
|
|
60a2626f61 | ||
|
|
e3a6f12478 | ||
|
|
2e980b06f6 | ||
|
|
b27b5512e3 | ||
|
|
3a013d50d6 | ||
|
|
3ebfd2e9e6 | ||
|
|
f51b69445a | ||
|
|
96904d525f | ||
|
|
26fa885adb | ||
|
|
f4ca4ec476 | ||
|
|
327995526e | ||
|
|
dfbbdc7d58 | ||
|
|
35894b3d8f | ||
|
|
0f219b4cd0 | ||
|
|
bfe94786de | ||
|
|
6cab2498dc | ||
|
|
dbe81bdb6e | ||
|
|
2e2b3844fe | ||
|
|
78b77dcd82 | ||
|
|
90614adb2b | ||
|
|
019ef43fe7 | ||
|
|
cfb6f0a908 | ||
|
|
77aeda1753 | ||
|
|
2a24ec3d49 | ||
|
|
d9d09b31b4 | ||
|
|
56550a9534 | ||
|
|
f40beb8234 | ||
|
|
cb06052c86 | ||
|
|
e09265fbc5 | ||
|
|
dede93ca62 | ||
|
|
caf8bd0c0f | ||
|
|
01d89a01a5 | ||
|
|
b0da647b0e | ||
|
|
fbcd4c3133 | ||
|
|
3e41c5973b | ||
|
|
1933beed9b | ||
|
|
defb35b258 | ||
|
|
8a4024ecfc | ||
|
|
9756c9133e | ||
|
|
c07d5e2c97 | ||
|
|
00e594d4fa | ||
|
|
3bf316af2b | ||
|
|
b116d3da28 | ||
|
|
804618d699 | ||
|
|
0e9fe6a096 | ||
|
|
ded4b94e54 | ||
|
|
eb0812df16 | ||
|
|
9ccaa824e0 | ||
|
|
d6e46b15a3 | ||
|
|
bab9be0228 | ||
|
|
9331050a43 | ||
|
|
9bcd189730 | ||
|
|
428365ceb9 | ||
|
|
76c889c6d9 | ||
|
|
9e4007d25a | ||
|
|
9d7754b92d | ||
|
|
3c80032063 | ||
|
|
7dae937491 | ||
|
|
6ce5e865ca | ||
|
|
b0d8fa0286 | ||
|
|
83c85adbde | ||
|
|
a1b51fd8ef | ||
|
|
bcc4034371 | ||
|
|
3dde07fc9f | ||
|
|
87ada9e999 | ||
|
|
ea55f25d44 | ||
|
|
2231f723f8 | ||
|
|
7c16694d4b | ||
|
|
ea60ff47cf | ||
|
|
1f7912dab6 | ||
|
|
ec0c00eb72 | ||
|
|
dd99e32cc6 | ||
|
|
1decbe0152 | ||
|
|
d58e3d023f | ||
|
|
1598b40c36 | ||
|
|
66ef667a0a | ||
|
|
e821d66268 | ||
|
|
b8e164e04c | ||
|
|
9097466a7b | ||
|
|
99604d8ec3 | ||
|
|
95d37fc3dc | ||
|
|
76d85adc98 | ||
|
|
2f233db465 | ||
|
|
1ca73ca6aa | ||
|
|
d5e4c13fa8 | ||
|
|
b5ac31838c | ||
|
|
e3e9412eea | ||
|
|
d3427876b7 | ||
|
|
4b2976e31b | ||
|
|
5720ee65b3 | ||
|
|
7f441ce72e | ||
|
|
83e87b0c67 | ||
|
|
578feac87f | ||
|
|
42a64e715d | ||
|
|
12a3a180f4 | ||
|
|
8acd5bcb39 | ||
|
|
eb71756c65 | ||
|
|
8c8cadd471 | ||
|
|
222c49c59b | ||
|
|
1e860112e6 | ||
|
|
ffc21daaba | ||
|
|
f9adcb2c5a | ||
|
|
d051bba71f | ||
|
|
f414f04033 | ||
|
|
ac466ecd79 | ||
|
|
262a7f9bab | ||
|
|
bb02d74005 | ||
|
|
e9b2b8d266 | ||
|
|
fc16bde227 | ||
|
|
d1775dfcc4 | ||
|
|
3d5937f6da | ||
|
|
adca8cd8fa | ||
|
|
6d30e6310b | ||
|
|
79ed0a5f8e | ||
|
|
94b3a020d5 | ||
|
|
3e241907e6 | ||
|
|
c4af1d9b23 | ||
|
|
7702169762 | ||
|
|
8209d9e229 | ||
|
|
664120f369 | ||
|
|
e952b555e0 | ||
|
|
d99c50da75 | ||
|
|
d4bec166f7 | ||
|
|
9a4b9d4bec | ||
|
|
68a6e98292 | ||
|
|
d61bdb028b | ||
|
|
9ddadb1338 | ||
|
|
fa1f225e67 | ||
|
|
7a72adedfa | ||
|
|
3d3e5c2c34 | ||
|
|
708f429c21 | ||
|
|
bca49ed2e2 | ||
|
|
e103ec7706 | ||
|
|
9fc1bec6a9 | ||
|
|
f712635860 | ||
|
|
47a0e38eac | ||
|
|
870d90d055 | ||
|
|
ac1b30782a | ||
|
|
b63445e9c9 | ||
|
|
09f616aae8 | ||
|
|
994fb267ad | ||
|
|
53b1e4d682 | ||
|
|
c7f6c508a6 | ||
|
|
9109fd356f | ||
|
|
55477d4fab | ||
|
|
340281113f | ||
|
|
77610672a9 | ||
|
|
d8238735c1 | ||
|
|
f63b013ef9 | ||
|
|
6fe3ec9355 | ||
|
|
d1c21bf50a | ||
|
|
578560c2e2 | ||
|
|
0f9462b7b5 | ||
|
|
e89891038b | ||
|
|
2a7a2d4dd4 | ||
|
|
f499cc8c2c | ||
|
|
0dc4c6b11b | ||
|
|
f5d0777b86 | ||
|
|
81443b77bc | ||
|
|
2867c50090 | ||
|
|
c04171c1a5 | ||
|
|
e19cbdc2f6 | ||
|
|
3e2e84e8bf | ||
|
|
462d30bbb7 | ||
|
|
5466b889a7 | ||
|
|
d27d20dd1c | ||
|
|
b6edc54cd9 | ||
|
|
2929483b0d | ||
|
|
2ab7c3529a | ||
|
|
f409ea2431 | ||
|
|
e71be4e1b1 | ||
|
|
507aec20d9 | ||
|
|
6a2d0c233a | ||
|
|
a1db8794bb | ||
|
|
bac7cd1ee7 | ||
|
|
7ec0c72522 | ||
|
|
430926c5a9 | ||
|
|
a2389be4aa | ||
|
|
f21caa0755 | ||
|
|
e42d3dac18 | ||
|
|
4c47a84daf | ||
|
|
42aaceaafa | ||
|
|
e5f7a28d80 | ||
|
|
074a3bacc7 | ||
|
|
f52a18989c | ||
|
|
f415ee22b8 | ||
|
|
4878ca47b5 | ||
|
|
59a3766a53 | ||
|
|
15de44eef8 | ||
|
|
5ae9942dd5 | ||
|
|
bf375f1065 | ||
|
|
510e129ff6 | ||
|
|
1c32b9b0bc | ||
|
|
f25a20ff90 | ||
|
|
0ba6753c8c | ||
|
|
7efef027c0 | ||
|
|
3a84695130 | ||
|
|
3f6d6908e2 | ||
|
|
9f4bf6103f | ||
|
|
ad7bb7063d | ||
|
|
04b4fea559 | ||
|
|
eb824949fe | ||
|
|
34db4d0c1f | ||
|
|
54a3113dbc | ||
|
|
7635630808 | ||
|
|
e4018864ac | ||
|
|
75e69a0a23 | ||
|
|
6061f80dcc | ||
|
|
c60525a685 | ||
|
|
eef628531a | ||
|
|
33d9257a61 | ||
|
|
7b032351b1 | ||
|
|
265f865a7d | ||
|
|
73d30310fd | ||
|
|
e26fbbb11f | ||
|
|
a548c16789 | ||
|
|
ecf650c9bc | ||
|
|
b27b4e7038 | ||
|
|
58d190ef12 | ||
|
|
bffc9108f9 | ||
|
|
114a715432 | ||
|
|
67d98954b2 | ||
|
|
53e7aafb06 | ||
|
|
e207b4720b | ||
|
|
af6da23411 | ||
|
|
21f274fd34 | ||
|
|
1b8df12a01 | ||
|
|
b210d1a6a7 | ||
|
|
d53ca87d43 | ||
|
|
635820cab5 | ||
|
|
aedb0fdcac | ||
|
|
4db1925328 | ||
|
|
6f2a444954 | ||
|
|
59b6621077 | ||
|
|
15a39f62e6 | ||
|
|
40489706ce | ||
|
|
742f3b6dc4 | ||
|
|
753617a616 | ||
|
|
114da00d98 | ||
|
|
283ab7a1ac | ||
|
|
096988c19f | ||
|
|
baf727e8ea | ||
|
|
2eb6558145 | ||
|
|
d946504503 | ||
|
|
ed94edd96b | ||
|
|
6441030161 | ||
|
|
588527a5b9 | ||
|
|
06cad500c1 | ||
|
|
e29b57811b | ||
|
|
e6bf46e8c4 | ||
|
|
646f8cc66b | ||
|
|
4c9f0f23f0 | ||
|
|
ecfd831603 | ||
|
|
b8324905ae | ||
|
|
8cbcd1afad | ||
|
|
7970ea39f3 | ||
|
|
a399d4f2cd | ||
|
|
edb3759b3d | ||
|
|
7ee0610db1 | ||
|
|
82a6ec6957 | ||
|
|
cf1c08c4ac | ||
|
|
d32df16137 | ||
|
|
2bcbc6fa07 | ||
|
|
ba9158ec9c | ||
|
|
40a6693a4c | ||
|
|
1ec389864d | ||
|
|
63a23904ac | ||
|
|
1807fc201e | ||
|
|
2d03421de4 |
@@ -11,6 +11,7 @@ ebean-profiling*.xml
|
||||
/db
|
||||
/mydb.db
|
||||
profiling/
|
||||
.DS_Store
|
||||
|
||||
# Intellij project files
|
||||
*.iml
|
||||
|
||||
+11
-12
@@ -4,13 +4,13 @@ Overview of ebean.properties file
|
||||
|
||||
### DbMigration options
|
||||
|
||||
You can set individual values for different platforms when generating migrations
|
||||
You can set individual values for different platforms when generating migrations.
|
||||
|
||||
`dbmigration.platform.<PLATFORM>.databaseSequenceBatchSize`
|
||||
For DB's using sequences this is the number of sequence values prefetched.
|
||||
|
||||
`dbmigration.platform.<PLATFORM>.dbuuid`
|
||||
Control, how UUID generation should work - it affects DDL which column type is generated. Possible values:
|
||||
Control, how UUID generation should work - it affects which column type is generated in DDL. Possible values:
|
||||
- BINARY enforces binary UUID
|
||||
- VARCHAR enforces varchar UUID
|
||||
- BINARY_OPTIMIZED enforces binary-optimized UUID (makes sense only with Type1 ID)
|
||||
@@ -19,7 +19,7 @@ Control, how UUID generation should work - it affects DDL which column type is g
|
||||
- AUTO_VARCHAR (default) use varchar when platform does not support UUID
|
||||
|
||||
`dbmigration.platform.<PLATFORM>.uuidStoreAsBinary`
|
||||
Same as setting dbuuid to BINARY
|
||||
Same as setting dbuuid to BINARY.
|
||||
|
||||
`dbmigration.platform.<PLATFORM>.geometrySRID`
|
||||
The Geometry SRID value (default 4326).
|
||||
@@ -30,7 +30,6 @@ The ID type (IDENTITY, SEQUENCE, GENERATOR, EXTERNAL)
|
||||
`dbmigration.platform.<PLATFORM>.mapping`
|
||||
Adjust the mapping. For example `BOOLEAN=integer(32);BIT=tinyint(3)`
|
||||
|
||||
|
||||
`ebean.migration.applyPrefix`
|
||||
Set this to "V" to be compatible with FlywayDB.
|
||||
|
||||
@@ -50,7 +49,7 @@ Set to true if the DB migration should be generated on server start.
|
||||
The version of a pending drop that should be generated as the next migration.
|
||||
|
||||
`ebean.migration.includeGeneratedFileComment`
|
||||
TODO
|
||||
Adds the header about the migration files being generated when true. Reading 'THIS IS A GENERATED FILE - DO NOT MODIFY'
|
||||
|
||||
`ebean.migration.metaTable`
|
||||
For running migration the DB table that holds migration execution status. Default 'db_migration'
|
||||
@@ -65,17 +64,17 @@ Subdirectory the model xml files go into. Default 'model'
|
||||
Suffix. Default '.model.xml'
|
||||
|
||||
`ebean.migration.name`
|
||||
Description text that can be appended to the version to become the ddl script file name
|
||||
Description text that can be appended to the version to become the ddl script file name.
|
||||
|
||||
`ebean.migration.patchInsertOn`
|
||||
migration versions that should be added to history without running.
|
||||
Migration versions that should be added to history without running.
|
||||
|
||||
`ebean.migration.patchResetChecksumOn`
|
||||
migration versions that should have their checksum reset and not run.
|
||||
Use this if you get a 'Checksum mismatch' error.
|
||||
|
||||
`ebean.migration.placeholders`
|
||||
A comma and equals delimited placeholders that are substituted in SQL scripts when running migration (used by DB Migration runner only).
|
||||
A comma and equals delimited map of placeholders that are substituted in SQL scripts when running migration (used by DB Migration runner only).
|
||||
|
||||
`ebean.migration.platform`
|
||||
The database platform to generate migration DDL for.
|
||||
@@ -90,7 +89,7 @@ The migration version name (typically FlywayDb compatible). Example: 1.1.1_2
|
||||
### Ebean UUID options
|
||||
|
||||
`ebean.uuidVersion`
|
||||
Controls, how the UUIDs are generated. Possible values
|
||||
Controls how the UUIDs are generated. Possible values:
|
||||
- VERSION4 (default) generate random V4 UUIDs,
|
||||
- VERSION1 generate rfc4122 compliant Type 1 UUIDs (requires a state file)
|
||||
- VERSION1RND generate fake Type 1 UUIDs
|
||||
@@ -98,7 +97,7 @@ Controls, how the UUIDs are generated. Possible values
|
||||
Note, that V1 UUIDs in conjunction with AUTO_BINARY_OPTIMIZED will give you the best index performance, but you MUST understand how this works to avoid collisions.
|
||||
|
||||
`ebean.uuidStateFile`
|
||||
The state file that is Required to generate V1 UUIDs
|
||||
The state file that is required to generate V1 UUIDs.
|
||||
|
||||
|
||||
### DocStoreConfig
|
||||
@@ -107,7 +106,7 @@ The state file that is Required to generate V1 UUIDs
|
||||
True when the Document store integration is active/on.
|
||||
|
||||
`ebean.docstore.allowAllCertificates`
|
||||
Set to true such that the client allows connections to invalid/self signed SSL certificates.
|
||||
Set to true such that the client allows connections to invalid/self-signed SSL certificates.
|
||||
|
||||
`ebean.docstore.bulkBatchSize`
|
||||
The default batch size to use for the Bulk API calls.
|
||||
@@ -192,7 +191,7 @@ Suffix appended to the base table to derive the view that contains the union of
|
||||
Set to true if the DataSource uses autoCommit. Indicates that Ebean should use autoCommit friendly Transactions and TransactionManager.
|
||||
|
||||
`ebean.autoReadOnlyDataSource`
|
||||
When true create a read only DataSource using readOnlyDataSourceConfig defaulting values from dataSourceConfig
|
||||
When true create a read only DataSource using readOnlyDataSourceConfig defaulting values from dataSourceConfig.
|
||||
|
||||
`ebean.autostart`
|
||||
Should the server start all
|
||||
|
||||
@@ -120,3 +120,4 @@ To set this option as the global default for IntelliJ use:
|
||||
`Run - Edit Configurations -> Edit configuration templates -> JUnit -> modify options - Do not use module-path option`
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean-clickhouse</name>
|
||||
@@ -16,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -31,17 +32,23 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-clickhouse</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean-cockroach</name>
|
||||
@@ -16,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -31,17 +32,23 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean-db2</name>
|
||||
@@ -16,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -31,17 +32,23 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-db2</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean-h2</name>
|
||||
@@ -16,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -31,17 +32,23 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean-hana</name>
|
||||
@@ -16,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -31,17 +32,23 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-hana</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean-mariadb</name>
|
||||
@@ -16,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -31,17 +32,23 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mariadb</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean-mysql</name>
|
||||
@@ -16,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -31,17 +32,23 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mysql</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean-nuodb</name>
|
||||
@@ -16,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -31,17 +32,23 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-nuodb</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean-oracle</name>
|
||||
@@ -16,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -31,17 +32,23 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-oracle</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean-postgres</name>
|
||||
@@ -16,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -31,17 +32,23 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean-sqlite</name>
|
||||
@@ -16,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -31,17 +32,23 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlite</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean-sqlserver</name>
|
||||
@@ -16,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -31,17 +32,23 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean-yugabyte</name>
|
||||
@@ -16,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -31,17 +32,23 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean (all platforms)</name>
|
||||
@@ -16,31 +17,31 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-joda-time</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.18.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-jsonnode</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.18.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-mapper</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -49,17 +50,23 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-migration</artifactId>
|
||||
<version>${ebean-migration.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Technically optional but most expected to use query beans -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-all</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>composites</artifactId>
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean api</name>
|
||||
@@ -39,7 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-config</artifactId>
|
||||
<version>3.1</version>
|
||||
<version>3.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -33,11 +33,6 @@ import java.util.Optional;
|
||||
@NonNullApi
|
||||
public abstract class BeanFinder<I,T> {
|
||||
|
||||
/**
|
||||
* Migrate to using database rather than server.
|
||||
*/
|
||||
@Deprecated
|
||||
protected final Database server;
|
||||
protected final Database database;
|
||||
protected final Class<T> type;
|
||||
|
||||
@@ -50,7 +45,6 @@ public abstract class BeanFinder<I,T> {
|
||||
protected BeanFinder(Class<T> type, Database database) {
|
||||
this.type = type;
|
||||
this.database = database;
|
||||
this.server = database;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -267,15 +267,21 @@ public final class DB {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated for removal migrate using try-with-resources and commit on the transaction itself.
|
||||
* <p>
|
||||
* Commit the current transaction.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void commitTransaction() {
|
||||
getDefault().commitTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated for removal migrate to using try-with-resources and rollback on the transaction itself.
|
||||
* <p>
|
||||
* Rollback the current transaction.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void rollbackTransaction() {
|
||||
getDefault().rollbackTransaction();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.service.SpiInTuples;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Default implementation of SpiInTuples.
|
||||
*/
|
||||
final class DInTuples implements SpiInTuples {
|
||||
|
||||
private final String[] properties;
|
||||
private final int propertyCount;
|
||||
private final List<Object[]> entries = new ArrayList<>();
|
||||
|
||||
|
||||
DInTuples(String[] properties) {
|
||||
this.properties = properties;
|
||||
this.propertyCount = properties.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InTuples add(Object... values) {
|
||||
if (values.length != propertyCount) {
|
||||
throw new IllegalArgumentException("Require " + propertyCount + " values but got " + values.length);
|
||||
}
|
||||
entries.add(values);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first property name.
|
||||
*/
|
||||
@Override
|
||||
public String[] properties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the value pairs.
|
||||
*/
|
||||
@Override
|
||||
public List<Object[]> entries() {
|
||||
return Collections.unmodifiableList(entries);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -35,7 +35,7 @@ import java.util.concurrent.Callable;
|
||||
* <h5>The 'default' Database</h5>
|
||||
* <p>
|
||||
* One Database can be designated as the 'default' or 'primary' Database
|
||||
* (see {@link DatabaseConfig#setDefaultServer(boolean)}. Many methods on DB
|
||||
* (see {@link DatabaseConfig#setDefaultServer(boolean)}). Many methods on DB
|
||||
* such as {@link DB#find(Class)} etc are actually just a convenient way to
|
||||
* call methods on the 'default/primary' Database.
|
||||
*
|
||||
@@ -166,7 +166,7 @@ public interface Database {
|
||||
/**
|
||||
* Return the BeanState for a given entity bean.
|
||||
* <p>
|
||||
* This will return null if the bean is not an enhanced entity bean.
|
||||
* This will throw an IllegalArgumentException if the bean is not an enhanced entity bean.
|
||||
*/
|
||||
BeanState beanState(Object bean);
|
||||
|
||||
@@ -650,13 +650,19 @@ public interface Database {
|
||||
void flush();
|
||||
|
||||
/**
|
||||
* Deprecated for removal migrate using try-with-resources and commit on the transaction itself.
|
||||
* <p>
|
||||
* Commit the current transaction.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
void commitTransaction();
|
||||
|
||||
/**
|
||||
* Deprecated for removal migrate to using try-with-resources and rollback on the transaction itself.
|
||||
* <p>
|
||||
* Rollback the current transaction.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
void rollbackTransaction();
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,12 +38,15 @@ final class DbContext {
|
||||
}
|
||||
}
|
||||
} catch (BeanNotEnhancedException e) {
|
||||
String msg = "Bean is not enhanced? See https://ebean.io/docs/trouble-shooting#not-enhanced";
|
||||
log.log(ERROR, msg, e);
|
||||
throw e;
|
||||
|
||||
} catch (DataSourceConfigurationException e) {
|
||||
String msg = "Configuration error creating DataSource for the default Database." +
|
||||
" This typically means a missing application-test.yaml or missing ebean-test dependency." +
|
||||
" See https://ebean.io/docs/trouble-shooting#datasource";
|
||||
log.log(ERROR, msg, e);
|
||||
throw new DataSourceConfigurationException(msg, e);
|
||||
|
||||
} catch (Throwable e) {
|
||||
|
||||
@@ -205,4 +205,16 @@ public interface DtoQuery<T> extends CancelableQuery {
|
||||
* Use the explicit transaction to execute the query.
|
||||
*/
|
||||
DtoQuery<T> usingTransaction(Transaction transaction);
|
||||
|
||||
/**
|
||||
* Ensure that the master DataSource is used if there is a read only data source
|
||||
* being used (that is using a read replica database potentially with replication lag).
|
||||
* <p>
|
||||
* When the database is configured with a read-only DataSource via
|
||||
* say {@link io.ebean.config.DatabaseConfig#setReadOnlyDataSource(DataSource)} then
|
||||
* by default when a query is run without an active transaction, it uses the read-only data
|
||||
* source. We we use {@code usingMaster()} to instead ensure that the query is executed
|
||||
* against the master data source.
|
||||
*/
|
||||
DtoQuery<T> usingMaster();
|
||||
}
|
||||
|
||||
@@ -41,14 +41,14 @@ public final class Expr {
|
||||
* Equal To - property equal to the given value.
|
||||
*/
|
||||
public static Expression eq(String propertyName, Object value) {
|
||||
return DB.expressionFactory().eq(propertyName, value);
|
||||
return factory().eq(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not Equal To - property not equal to the given value.
|
||||
*/
|
||||
public static Expression ne(String propertyName, Object value) {
|
||||
return DB.expressionFactory().ne(propertyName, value);
|
||||
return factory().ne(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,7 +56,7 @@ public final class Expr {
|
||||
* using a lower() function to make it case insensitive).
|
||||
*/
|
||||
public static Expression ieq(String propertyName, String value) {
|
||||
return DB.expressionFactory().ieq(propertyName, value);
|
||||
return factory().ieq(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,28 +66,28 @@ public final class Expr {
|
||||
* </p>
|
||||
*/
|
||||
public static Expression inRange(String propertyName, Object value1, Object value2) {
|
||||
return DB.expressionFactory().inRange(propertyName, value1, value2);
|
||||
return factory().inRange(propertyName, value1, value2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Between - property between the two given values.
|
||||
*/
|
||||
public static Expression between(String propertyName, Object value1, Object value2) {
|
||||
return DB.expressionFactory().between(propertyName, value1, value2);
|
||||
return factory().between(propertyName, value1, value2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Between - value between two given properties.
|
||||
*/
|
||||
public static Expression between(String lowProperty, String highProperty, Object value) {
|
||||
return DB.expressionFactory().betweenProperties(lowProperty, highProperty, value);
|
||||
return factory().betweenProperties(lowProperty, highProperty, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater Than - property greater than the given value.
|
||||
*/
|
||||
public static Expression gt(String propertyName, Object value) {
|
||||
return DB.expressionFactory().gt(propertyName, value);
|
||||
return factory().gt(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,42 +95,42 @@ public final class Expr {
|
||||
* value.
|
||||
*/
|
||||
public static Expression ge(String propertyName, Object value) {
|
||||
return DB.expressionFactory().ge(propertyName, value);
|
||||
return factory().ge(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Less Than - property less than the given value.
|
||||
*/
|
||||
public static Expression lt(String propertyName, Object value) {
|
||||
return DB.expressionFactory().lt(propertyName, value);
|
||||
return factory().lt(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Less Than or Equal to - property less than or equal to the given value.
|
||||
*/
|
||||
public static Expression le(String propertyName, Object value) {
|
||||
return DB.expressionFactory().le(propertyName, value);
|
||||
return factory().le(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Null - property is null.
|
||||
*/
|
||||
public static Expression isNull(String propertyName) {
|
||||
return DB.expressionFactory().isNull(propertyName);
|
||||
return factory().isNull(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Not Null - property is not null.
|
||||
*/
|
||||
public static Expression isNotNull(String propertyName) {
|
||||
return DB.expressionFactory().isNotNull(propertyName);
|
||||
return factory().isNotNull(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Case insensitive {@link #exampleLike(Object)}
|
||||
*/
|
||||
public static ExampleExpression iexampleLike(Object example) {
|
||||
return DB.expressionFactory().iexampleLike(example);
|
||||
return factory().iexampleLike(example);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,14 +138,14 @@ public final class Expr {
|
||||
* LikeType.RAW (you need to add you own wildcards % and _).
|
||||
*/
|
||||
public static ExampleExpression exampleLike(Object example) {
|
||||
return DB.expressionFactory().exampleLike(example);
|
||||
return factory().exampleLike(example);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the query by Example expression specifying more options.
|
||||
*/
|
||||
public static ExampleExpression exampleLike(Object example, boolean caseInsensitive, LikeType likeType) {
|
||||
return DB.expressionFactory().exampleLike(example, caseInsensitive, likeType);
|
||||
return factory().exampleLike(example, caseInsensitive, likeType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,7 +153,7 @@ public final class Expr {
|
||||
* characters % (percentage) and _ (underscore).
|
||||
*/
|
||||
public static Expression like(String propertyName, String value) {
|
||||
return DB.expressionFactory().like(propertyName, value);
|
||||
return factory().like(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,14 +162,14 @@ public final class Expr {
|
||||
* a lower() function to make the expression case insensitive.
|
||||
*/
|
||||
public static Expression ilike(String propertyName, String value) {
|
||||
return DB.expressionFactory().ilike(propertyName, value);
|
||||
return factory().ilike(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts With - property like value%.
|
||||
*/
|
||||
public static Expression startsWith(String propertyName, String value) {
|
||||
return DB.expressionFactory().startsWith(propertyName, value);
|
||||
return factory().startsWith(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -177,14 +177,14 @@ public final class Expr {
|
||||
* lower() function to make the expression case insensitive.
|
||||
*/
|
||||
public static Expression istartsWith(String propertyName, String value) {
|
||||
return DB.expressionFactory().istartsWith(propertyName, value);
|
||||
return factory().istartsWith(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends With - property like %value.
|
||||
*/
|
||||
public static Expression endsWith(String propertyName, String value) {
|
||||
return DB.expressionFactory().endsWith(propertyName, value);
|
||||
return factory().endsWith(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,14 +192,14 @@ public final class Expr {
|
||||
* function to make the expression case insensitive.
|
||||
*/
|
||||
public static Expression iendsWith(String propertyName, String value) {
|
||||
return DB.expressionFactory().iendsWith(propertyName, value);
|
||||
return factory().iendsWith(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains - property like %value%.
|
||||
*/
|
||||
public static Expression contains(String propertyName, String value) {
|
||||
return DB.expressionFactory().contains(propertyName, value);
|
||||
return factory().contains(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,42 +207,42 @@ public final class Expr {
|
||||
* function to make the expression case insensitive.
|
||||
*/
|
||||
public static Expression icontains(String propertyName, String value) {
|
||||
return DB.expressionFactory().icontains(propertyName, value);
|
||||
return factory().icontains(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* For collection properties that are empty (have not existing elements).
|
||||
*/
|
||||
public static Expression isEmpty(String propertyName) {
|
||||
return DB.expressionFactory().isEmpty(propertyName);
|
||||
return factory().isEmpty(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* For collection properties that are not empty (have existing elements).
|
||||
*/
|
||||
public static Expression isNotEmpty(String propertyName) {
|
||||
return DB.expressionFactory().isNotEmpty(propertyName);
|
||||
return factory().isNotEmpty(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* In - property has a value in the array of values.
|
||||
*/
|
||||
public static Expression in(String propertyName, Object[] values) {
|
||||
return DB.expressionFactory().in(propertyName, values);
|
||||
return factory().in(propertyName, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* In - using a subQuery.
|
||||
*/
|
||||
public static Expression in(String propertyName, Query<?> subQuery) {
|
||||
return DB.expressionFactory().in(propertyName, subQuery);
|
||||
return factory().in(propertyName, subQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* In - property has a value in the collection of values.
|
||||
*/
|
||||
public static Expression in(String propertyName, Collection<?> values) {
|
||||
return DB.expressionFactory().in(propertyName, values);
|
||||
return factory().in(propertyName, values);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,14 +279,14 @@ public final class Expr {
|
||||
* }</pre>
|
||||
*/
|
||||
public static Expression inOrEmpty(String propertyName, Collection<?> values) {
|
||||
return DB.expressionFactory().inOrEmpty(propertyName, values);
|
||||
return factory().inOrEmpty(propertyName, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Id Equal to - ID property is equal to the value.
|
||||
*/
|
||||
public static Expression idEq(Object value) {
|
||||
return DB.expressionFactory().idEq(value);
|
||||
return factory().idEq(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -299,7 +299,7 @@ public final class Expr {
|
||||
* @param propertyMap a map keyed by property names.
|
||||
*/
|
||||
public static Expression allEq(Map<String, Object> propertyMap) {
|
||||
return DB.expressionFactory().allEq(propertyMap);
|
||||
return factory().allEq(propertyMap);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -310,7 +310,7 @@ public final class Expr {
|
||||
* </p>
|
||||
*/
|
||||
public static Expression raw(String raw, Object value) {
|
||||
return DB.expressionFactory().raw(raw, value);
|
||||
return factory().raw(raw, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -321,48 +321,48 @@ public final class Expr {
|
||||
* </p>
|
||||
*/
|
||||
public static Expression raw(String raw, Object[] values) {
|
||||
return DB.expressionFactory().raw(raw, values);
|
||||
return factory().raw(raw, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add raw expression with no parameters.
|
||||
*/
|
||||
public static Expression raw(String raw) {
|
||||
return DB.expressionFactory().raw(raw);
|
||||
return factory().raw(raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* And - join two expressions with a logical and.
|
||||
*/
|
||||
public static Expression and(Expression expOne, Expression expTwo) {
|
||||
return DB.expressionFactory().and(expOne, expTwo);
|
||||
return factory().and(expOne, expTwo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Or - join two expressions with a logical or.
|
||||
*/
|
||||
public static Expression or(Expression expOne, Expression expTwo) {
|
||||
return DB.expressionFactory().or(expOne, expTwo);
|
||||
return factory().or(expOne, expTwo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Negate the expression (prefix it with NOT).
|
||||
*/
|
||||
public static Expression not(Expression exp) {
|
||||
return DB.expressionFactory().not(exp);
|
||||
return factory().not(exp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of expressions that will be joined by AND's.
|
||||
*/
|
||||
public static <T> Junction<T> conjunction(Query<T> query) {
|
||||
return DB.expressionFactory().conjunction(query);
|
||||
return factory().conjunction(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of expressions that will be joined by OR's.
|
||||
*/
|
||||
public static <T> Junction<T> disjunction(Query<T> query) {
|
||||
return DB.expressionFactory().disjunction(query);
|
||||
return factory().disjunction(query);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,11 @@ import java.util.Map;
|
||||
*/
|
||||
public interface ExpressionFactory {
|
||||
|
||||
/**
|
||||
* Return a new ExpressionList.
|
||||
*/
|
||||
<T> ExpressionList<T> expressionList();
|
||||
|
||||
/**
|
||||
* Path exists - for the given path in a JSON document.
|
||||
*/
|
||||
@@ -369,6 +374,11 @@ public interface ExpressionFactory {
|
||||
*/
|
||||
Expression inPairs(Pairs pairs);
|
||||
|
||||
/**
|
||||
* In expression using multiple columns.
|
||||
*/
|
||||
Expression inTuples(InTuples pairs);
|
||||
|
||||
/**
|
||||
* In - property has a value in the array of values.
|
||||
*/
|
||||
|
||||
@@ -54,14 +54,12 @@ public interface ExpressionList<T> {
|
||||
Query<T> orderById(boolean orderById);
|
||||
|
||||
/**
|
||||
* Set the order by clause replacing the existing order by clause if there is
|
||||
* one.
|
||||
* <p>
|
||||
* This follows SQL syntax using commas between each property with the
|
||||
* optional asc and desc keywords representing ascending and descending order
|
||||
* respectively.
|
||||
* Deprecated migrate to {@link #orderBy(String)}
|
||||
*/
|
||||
ExpressionList<T> order(String orderByClause);
|
||||
@Deprecated(since = "13.19", forRemoval = true)
|
||||
default ExpressionList<T> order(String orderByClause) {
|
||||
return orderBy(orderByClause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the order by clause replacing the existing order by clause if there is
|
||||
@@ -74,15 +72,12 @@ public interface ExpressionList<T> {
|
||||
ExpressionList<T> orderBy(String orderBy);
|
||||
|
||||
/**
|
||||
* Return the OrderBy so that you can append an ascending or descending
|
||||
* property to the order by clause.
|
||||
* <p>
|
||||
* This will never return a null. If no order by clause exists then an 'empty'
|
||||
* OrderBy object is returned.
|
||||
* <p>
|
||||
* This is the same as <code>orderBy()</code>
|
||||
* Deprecated migrate to orderBy().
|
||||
*/
|
||||
OrderBy<T> order();
|
||||
@Deprecated(forRemoval = true)
|
||||
default OrderBy<T> order() {
|
||||
return orderBy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the OrderBy so that you can append an ascending or descending
|
||||
@@ -95,12 +90,6 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
OrderBy<T> orderBy();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to {@link #orderBy(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
Query<T> setOrderBy(String orderBy);
|
||||
|
||||
/**
|
||||
* Apply the path properties to the query replacing the select and fetch clauses.
|
||||
*/
|
||||
@@ -404,6 +393,7 @@ public interface ExpressionList<T> {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Nullable
|
||||
default <A> A findSingleAttribute() {
|
||||
List<A> list = findSingleAttributeList();
|
||||
return !list.isEmpty() ? list.get(0) : null;
|
||||
@@ -518,6 +508,8 @@ public interface ExpressionList<T> {
|
||||
ExpressionList<T> filterMany(String manyProperty);
|
||||
|
||||
/**
|
||||
* Deprecated for removal - migrate to filterManyRaw()
|
||||
* <p>
|
||||
* Add filter expressions to the many property.
|
||||
*
|
||||
* <pre>{@code
|
||||
@@ -534,8 +526,29 @@ public interface ExpressionList<T> {
|
||||
* @param expressions Filter expressions with and, or and ? or ?1 type bind parameters
|
||||
* @param params Bind parameters used in the expressions
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
ExpressionList<T> filterMany(String manyProperty, String expressions, Object... params);
|
||||
|
||||
/**
|
||||
* Add filter expressions for the many path. The expressions can include SQL functions if
|
||||
* desired and the property names are translated to column names.
|
||||
* <p>
|
||||
* The expressions can contain placeholders for bind values using <code>?</code> or <code>?1</code> style.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* new QCustomer()
|
||||
* .name.startsWith("Postgres")
|
||||
* .contacts.filterManyRaw("status = ? and firstName like ?", Contact.Status.NEW, "Rob%")
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param rawExpressions The raw expressions which can include ? and ?1 style bind parameter placeholders
|
||||
* @param params The parameter values to bind
|
||||
*/
|
||||
ExpressionList<T> filterManyRaw(String manyProperty, String rawExpressions, Object... params);
|
||||
|
||||
/**
|
||||
* Specify specific properties to fetch on the main/root bean (aka partial
|
||||
* object).
|
||||
@@ -1141,6 +1154,11 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> inPairs(Pairs pairs);
|
||||
|
||||
/**
|
||||
* In expression using multiple columns.
|
||||
*/
|
||||
ExpressionList<T> inTuples(InTuples pairs);
|
||||
|
||||
/**
|
||||
* EXISTS a raw SQL SubQuery.
|
||||
*
|
||||
|
||||
@@ -1,26 +1,9 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.avaje.lang.Nullable;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* The extended API for Database.
|
||||
* <p>
|
||||
* Deprecated in favour of using {@link Query#usingTransaction(Transaction)} instead.
|
||||
* <p>
|
||||
* This provides the finder methods that take an explicit transaction rather than obtaining
|
||||
* the transaction from the usual mechanism (which is ThreadLocal based).
|
||||
* <p>
|
||||
* Note that in all cases the transaction supplied can be null and in this case the Database
|
||||
* will use the normal mechanism to obtain the transaction to use.
|
||||
*/
|
||||
public interface ExtendedServer {
|
||||
|
||||
@@ -35,162 +18,4 @@ public interface ExtendedServer {
|
||||
@Deprecated
|
||||
void setClock(Clock clock);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> boolean exists(Query<T> ormQuery, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> int findCount(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<A, T> List<A> findIds(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> Stream<T> findStream(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> void findEach(Query<T> query, Consumer<T> consumer, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> void findEach(Query<T> query, int batch, Consumer<List<T>> consumer, Transaction t);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> void findEachWhile(Query<T> query, Predicate<T> consumer, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> List<Version<T>> findVersions(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> List<T> findList(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> FutureRowCount<T> findFutureCount(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> FutureIds<T> findFutureIds(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> FutureList<T> findFutureList(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> PagedList<T> findPagedList(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> Set<T> findSet(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<K, T> Map<K, T> findMap(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<A, T> List<A> findSingleAttributeList(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<A, T> Set<A> findSingleAttributeSet(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
<T> T findOne(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> Optional<T> findOneOrEmpty(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> int delete(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> int update(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
List<SqlRow> findList(SqlQuery query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
void findEach(SqlQuery query, Consumer<SqlRow> consumer, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
void findEachWhile(SqlQuery query, Predicate<SqlRow> consumer, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link SqlQuery#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
SqlRow findOne(SqlQuery query, Transaction transaction);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package io.ebean;
|
||||
|
||||
/**
|
||||
* IN expression using multiple columns.
|
||||
* <p>
|
||||
* Currently this is not supported with SQLServer or DB2.
|
||||
* <p>
|
||||
* Produces SQL expression in the form of (A,B,C) IN ((a0,b0,c0), (a1,b1,c1), ... )
|
||||
* where A,B,C are the properties in the tuples.
|
||||
*/
|
||||
public interface InTuples {
|
||||
|
||||
/**
|
||||
* Create given the properties in the tuples.
|
||||
*/
|
||||
static InTuples of(String... properties) {
|
||||
return new DInTuples(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create given the properties in the tuples.
|
||||
*/
|
||||
static InTuples of(Query.Property<?>... properties) {
|
||||
String[] props = new String[properties.length];
|
||||
for (int i = 0; i < properties.length; i++) {
|
||||
props[i] = properties[i].toString();
|
||||
}
|
||||
return new DInTuples(props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a tuple entry. All values must be non-null.
|
||||
*/
|
||||
InTuples add(Object... values);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package io.ebean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Helper methods for Lists.
|
||||
*/
|
||||
public final class Lists {
|
||||
|
||||
private Lists() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Partition the source List into sub-lists with a maximum size.
|
||||
* <p>
|
||||
* The sub-lists will all be the max size except for the last sub-list
|
||||
* which can potentially be smaller.
|
||||
*
|
||||
* @param source The source list
|
||||
* @param max The max size of each partition
|
||||
* @param <T> The list element type
|
||||
* @return List of sub-list partitions
|
||||
*/
|
||||
public static <T> List<List<T>> partition(List<T> source, int max) {
|
||||
final int totalCount = source.size();
|
||||
if (totalCount == 0) {
|
||||
return Collections.emptyList();
|
||||
} else if (totalCount <= max) {
|
||||
return List.of(source);
|
||||
}
|
||||
final int numOfPartitions = (totalCount + max - 1) / max; // round up
|
||||
final var dest = new ArrayList<List<T>>(numOfPartitions);
|
||||
for (int i = 0; i < numOfPartitions; i++) {
|
||||
final int from = i * max;
|
||||
final int to = Math.min(from + max, totalCount);
|
||||
dest.add(source.subList(from, to));
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
}
|
||||
@@ -333,10 +333,10 @@ public class OrderBy<T> implements Serializable {
|
||||
sb.append(property);
|
||||
}
|
||||
if (!ascending) {
|
||||
sb.append(" ").append("desc");
|
||||
sb.append(' ').append("desc");
|
||||
}
|
||||
if (nulls != null) {
|
||||
sb.append(" ").append(nulls).append(" ").append(highLow);
|
||||
sb.append(' ').append(nulls).append(' ').append(highLow);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -30,23 +30,6 @@ public interface ProfileLocation {
|
||||
return XServiceProvider.profileLocationFactory().create(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated in favor of {@link #create(String)}.
|
||||
*/
|
||||
@Deprecated
|
||||
static ProfileLocation create(int lineNumber, String label) {
|
||||
return create(label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated for removal - not used.
|
||||
* Create and return a new ProfileLocation with a given location.
|
||||
*/
|
||||
@Deprecated
|
||||
static ProfileLocation createAt(String location) {
|
||||
return XServiceProvider.profileLocationFactory().createAt(location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the description returning true if this is the initial call.
|
||||
*/
|
||||
|
||||
@@ -4,12 +4,14 @@ import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
@@ -670,6 +672,16 @@ public interface Query<T> extends CancelableQuery {
|
||||
*/
|
||||
Query<T> apply(FetchPath fetchPath);
|
||||
|
||||
/**
|
||||
* Apply changes to the query conditional on the supplied predicate.
|
||||
* <p>
|
||||
* Typically, the changes are extra predicates etc.
|
||||
*
|
||||
* @param predicate The predicate which when true the changes are applied
|
||||
* @param apply The changes to apply to the query
|
||||
*/
|
||||
Query<T> alsoIf(BooleanSupplier predicate, Consumer<Query<T>> apply);
|
||||
|
||||
/**
|
||||
* Execute the query using the given transaction.
|
||||
*/
|
||||
@@ -685,6 +697,18 @@ public interface Query<T> extends CancelableQuery {
|
||||
*/
|
||||
Query<T> usingDatabase(Database database);
|
||||
|
||||
/**
|
||||
* Ensure that the master DataSource is used if there is a read only data source
|
||||
* being used (that is using a read replica database potentially with replication lag).
|
||||
* <p>
|
||||
* When the database is configured with a read-only DataSource via
|
||||
* say {@link io.ebean.config.DatabaseConfig#setReadOnlyDataSource(DataSource)} then
|
||||
* by default when a query is run without an active transaction, it uses the read-only data
|
||||
* source. We we use {@code usingMaster()} to instead ensure that the query is executed
|
||||
* against the master data source.
|
||||
*/
|
||||
Query<T> usingMaster();
|
||||
|
||||
/**
|
||||
* Execute the query returning the list of Id's.
|
||||
* <p>
|
||||
@@ -1372,13 +1396,9 @@ public interface Query<T> extends CancelableQuery {
|
||||
Query<T> orderBy(String orderByClause);
|
||||
|
||||
/**
|
||||
* Set the order by clause replacing the existing order by clause if there is
|
||||
* one.
|
||||
* <p>
|
||||
* This follows SQL syntax using commas between each property with the
|
||||
* optional asc and desc keywords representing ascending and descending order
|
||||
* respectively.
|
||||
* Deprecated migrate to orderBy().
|
||||
*/
|
||||
@Deprecated(since = "13.19", forRemoval = true)
|
||||
default Query<T> order(String orderByClause) {
|
||||
return orderBy(orderByClause);
|
||||
}
|
||||
@@ -1395,14 +1415,9 @@ public interface Query<T> extends CancelableQuery {
|
||||
OrderBy<T> orderBy();
|
||||
|
||||
/**
|
||||
* Return the OrderBy so that you can append an ascending or descending
|
||||
* property to the order by clause.
|
||||
* <p>
|
||||
* This will never return a null. If no order by clause exists then an 'empty'
|
||||
* OrderBy object is returned.
|
||||
* <p>
|
||||
* This is the same as <code>orderBy()</code>
|
||||
* Deprecated migrate to orderBy().
|
||||
*/
|
||||
@Deprecated(since = "13.19", forRemoval = true)
|
||||
default OrderBy<T> order() {
|
||||
return orderBy();
|
||||
}
|
||||
@@ -1413,8 +1428,9 @@ public interface Query<T> extends CancelableQuery {
|
||||
Query<T> setOrderBy(OrderBy<T> orderBy);
|
||||
|
||||
/**
|
||||
* Set an OrderBy object to replace any existing OrderBy clause.
|
||||
* Deprecated migrate to setOrderBy().
|
||||
*/
|
||||
@Deprecated(since = "13.19", forRemoval = true)
|
||||
default Query<T> setOrder(OrderBy<T> orderBy) {
|
||||
return setOrderBy(orderBy);
|
||||
}
|
||||
@@ -1579,14 +1595,6 @@ public interface Query<T> extends CancelableQuery {
|
||||
*/
|
||||
Query<T> setReadOnly(boolean readOnly);
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to use setBeanCacheMode(CacheMode.PUT) or other CacheMode.
|
||||
* <p>
|
||||
* When set to true all the beans from this query are loaded into the bean cache.
|
||||
*/
|
||||
@Deprecated
|
||||
Query<T> setLoadBeanCache(boolean loadBeanCache);
|
||||
|
||||
/**
|
||||
* Set a timeout on this query.
|
||||
* <p>
|
||||
|
||||
@@ -45,6 +45,18 @@ public interface SqlQuery extends Serializable, CancelableQuery {
|
||||
*/
|
||||
SqlQuery usingTransaction(Transaction transaction);
|
||||
|
||||
/**
|
||||
* Ensure that the master DataSource is used if there is a read only data source
|
||||
* being used (that is using a read replica database potentially with replication lag).
|
||||
* <p>
|
||||
* When the database is configured with a read-only DataSource via
|
||||
* say {@link io.ebean.config.DatabaseConfig#setReadOnlyDataSource(DataSource)} then
|
||||
* by default when a query is run without an active transaction, it uses the read-only data
|
||||
* source. We we use {@code usingMaster()} to instead ensure that the query is executed
|
||||
* against the master data source.
|
||||
*/
|
||||
SqlQuery usingMaster();
|
||||
|
||||
/**
|
||||
* Execute the query returning a list.
|
||||
*/
|
||||
|
||||
@@ -77,9 +77,9 @@ public final class StdOperators {
|
||||
StringBuilder expression = new StringBuilder(50);
|
||||
expression.append("concat(").append(property.toString());
|
||||
for (Object value : values) {
|
||||
expression.append(",").append(sqlConcatString(value));
|
||||
expression.append(',').append(sqlConcatString(value));
|
||||
}
|
||||
expression.append(")");
|
||||
expression.append(')');
|
||||
return Property.of(expression.toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public final class ToStringBuilder {
|
||||
id.putIfAbsent(bean, 0);
|
||||
}
|
||||
if (counter <= MAX) {
|
||||
sb.append(bean.getClass().getSimpleName()).append("@").append(counter).append("(");
|
||||
sb.append(bean.getClass().getSimpleName()).append('@').append(counter).append('(');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ public final class ToStringBuilder {
|
||||
*/
|
||||
public void end() {
|
||||
if (counter <= MAX) {
|
||||
sb.append(")");
|
||||
sb.append(')');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public final class ToStringBuilder {
|
||||
} else {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(name).append(":");
|
||||
sb.append(name).append(':');
|
||||
}
|
||||
|
||||
private void value(Object value) {
|
||||
@@ -110,7 +110,7 @@ public final class ToStringBuilder {
|
||||
} else {
|
||||
String content = String.valueOf(value);
|
||||
if (content.length() > TRIM_LENGTH) {
|
||||
content = content.substring(0, TRIM_LENGTH) + " <trimmed>";
|
||||
content = content.substring(0, TRIM_LENGTH) + " (trimmed)";
|
||||
}
|
||||
sb.append(content);
|
||||
if (sb.length() >= MAX_TOTAL_CONTENT) {
|
||||
@@ -125,20 +125,20 @@ public final class ToStringBuilder {
|
||||
sb.append("{}");
|
||||
} else {
|
||||
boolean firstElement = true;
|
||||
sb.append("{");
|
||||
sb.append('{');
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
if (firstElement) {
|
||||
firstElement = false;
|
||||
} else {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(entry.getKey()).append(":");
|
||||
sb.append(entry.getKey()).append(':');
|
||||
value(entry.getValue());
|
||||
if (counter > MAX) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
sb.append("}");
|
||||
sb.append('}');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ public final class ToStringBuilder {
|
||||
return;
|
||||
}
|
||||
boolean firstElement = true;
|
||||
sb.append("[");
|
||||
sb.append('[');
|
||||
for (Object o : c) {
|
||||
if (firstElement) {
|
||||
firstElement = false;
|
||||
@@ -163,7 +163,7 @@ public final class ToStringBuilder {
|
||||
return;
|
||||
}
|
||||
}
|
||||
sb.append("]");
|
||||
sb.append(']');
|
||||
}
|
||||
|
||||
private boolean push(Object bean) {
|
||||
@@ -178,7 +178,7 @@ public final class ToStringBuilder {
|
||||
Integer idx = id.putIfAbsent(bean, counter++);
|
||||
if (idx != null) {
|
||||
--counter;
|
||||
sb.append(bean.getClass().getSimpleName()).append("@").append(idx);
|
||||
sb.append(bean.getClass().getSimpleName()).append('@').append(idx);
|
||||
return false;
|
||||
}
|
||||
first = true;
|
||||
|
||||
@@ -69,7 +69,7 @@ public class TenantAwareKey {
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(key.toString());
|
||||
if (tenantId != null) {
|
||||
sb.append(":").append(tenantId);
|
||||
sb.append(':').append(tenantId);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
try {
|
||||
if (set == null) {
|
||||
if (!disableLazyLoad && modifyListening) {
|
||||
lazyLoadCollection(true);
|
||||
lazyLoadCollection(false);
|
||||
} else {
|
||||
set = new LinkedHashSet<>();
|
||||
}
|
||||
@@ -136,7 +136,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
if (disableLazyLoad) {
|
||||
set = new LinkedHashSet<>();
|
||||
} else {
|
||||
lazyLoadCollection(true);
|
||||
lazyLoadCollection(false);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
||||
@@ -228,7 +228,7 @@ public abstract class AbstractNamingConvention implements NamingConvention {
|
||||
public TableName getM2MJoinTableName(TableName lhsTable, TableName rhsTable) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append(unQuote(lhsTable.getName()));
|
||||
buffer.append("_");
|
||||
buffer.append('_');
|
||||
|
||||
String rhsTableName = unQuote(rhsTable.getName());
|
||||
if (rhsTableName.indexOf('_') < rhsPrefixLength) {
|
||||
@@ -271,10 +271,10 @@ public abstract class AbstractNamingConvention implements NamingConvention {
|
||||
public String getTableName(String catalog, String schema, String name) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (!isNull(catalog)) {
|
||||
sb.append(quoteIdentifiers(catalog)).append(".");
|
||||
sb.append(quoteIdentifiers(catalog)).append('.');
|
||||
}
|
||||
if (!isNull(schema)) {
|
||||
sb.append(quoteIdentifiers(schema)).append(".");
|
||||
sb.append(quoteIdentifiers(schema)).append('.');
|
||||
}
|
||||
return sb.append(quoteIdentifiers(name)).toString();
|
||||
}
|
||||
|
||||
@@ -526,11 +526,6 @@ public class DatabaseConfig {
|
||||
|
||||
private ProfilingConfig profilingConfig = new ProfilingConfig();
|
||||
|
||||
/**
|
||||
* Controls the default order by id setting of queries. See {@link Query#orderById(boolean)}
|
||||
*/
|
||||
private boolean defaultOrderById;
|
||||
|
||||
/**
|
||||
* The mappingLocations for searching xml mapping.
|
||||
*/
|
||||
@@ -595,22 +590,6 @@ public class DatabaseConfig {
|
||||
this.slowQueryListener = slowQueryListener;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deprecated - look to have explicit order by. Sets the default orderById setting for queries.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setDefaultOrderById(boolean defaultOrderById) {
|
||||
this.defaultOrderById = defaultOrderById;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default orderById setting for queries.
|
||||
*/
|
||||
public boolean isDefaultOrderById() {
|
||||
return defaultOrderById;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a service object into configuration such that it can be used by ebean or a plugin.
|
||||
* <p>
|
||||
@@ -2327,8 +2306,6 @@ public class DatabaseConfig {
|
||||
* <p>
|
||||
* If no classes are specified then the classes are found automatically via
|
||||
* searching the class path.
|
||||
* <p>
|
||||
* Alternatively the classes can be added via {@link #setClasses(List)}.
|
||||
*
|
||||
* @param cls the entity type (or other type) that should be registered by this database.
|
||||
*/
|
||||
@@ -2399,7 +2376,7 @@ public class DatabaseConfig {
|
||||
* Sorry if returning Set rather than List breaks code but it feels safer to
|
||||
* do that than a subtle change to return a shallow copy which you will not detect.
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated(forRemoval = true)
|
||||
public Set<Class<?>> getClasses() {
|
||||
return classes;
|
||||
}
|
||||
@@ -2942,7 +2919,6 @@ public class DatabaseConfig {
|
||||
jdbcFetchSizeFindEach = p.getInt("jdbcFetchSizeFindEach", jdbcFetchSizeFindEach);
|
||||
jdbcFetchSizeFindList = p.getInt("jdbcFetchSizeFindList", jdbcFetchSizeFindList);
|
||||
databasePlatformName = p.get("databasePlatformName", databasePlatformName);
|
||||
defaultOrderById = p.getBoolean("defaultOrderById", defaultOrderById);
|
||||
|
||||
uuidVersion = p.getEnum(UuidVersion.class, "uuidVersion", uuidVersion);
|
||||
uuidStateFile = p.get("uuidStateFile", uuidStateFile);
|
||||
@@ -3413,7 +3389,7 @@ public class DatabaseConfig {
|
||||
/**
|
||||
* Deprecated - migrate to isLoadModuleInfo().
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated(forRemoval = true)
|
||||
public boolean isAutoLoadModuleInfo() {
|
||||
return loadModuleInfo;
|
||||
}
|
||||
|
||||
@@ -135,16 +135,16 @@ public class DbConstraintNaming {
|
||||
*/
|
||||
protected String joinColumnNames(String[] columns) {
|
||||
if (columns.length == 1) {
|
||||
return normaliseColumn(columns[0]);
|
||||
return normaliseColumn(columns[0]).replace(" ", "_");
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append("_");
|
||||
sb.append('_');
|
||||
}
|
||||
sb.append(normaliseColumn(columns[i]));
|
||||
}
|
||||
return sb.toString();
|
||||
return sb.toString().replace(" ", "_");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,7 +27,6 @@ public class DbConstraintNormalise {
|
||||
* quoted identifier characters (",',[,] etc).
|
||||
*/
|
||||
public String normaliseTable(String tableName) {
|
||||
|
||||
tableName = trimQuotes(tableName);
|
||||
int lastPeriod = tableName.lastIndexOf('.');
|
||||
if (lastPeriod > -1) {
|
||||
@@ -59,7 +58,6 @@ public class DbConstraintNormalise {
|
||||
* Trim off the platform quoted identifier quotes like [ ' and ".
|
||||
*/
|
||||
public String trimQuotes(String identifier) {
|
||||
|
||||
if (identifier == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -117,12 +117,12 @@ public final class TableName {
|
||||
// Add schema
|
||||
if (schema != null) {
|
||||
if (buffer.length() > 0) {
|
||||
buffer.append(".");
|
||||
buffer.append('.');
|
||||
}
|
||||
buffer.append(schema);
|
||||
}
|
||||
if (buffer.length() > 0) {
|
||||
buffer.append(".");
|
||||
buffer.append('.');
|
||||
}
|
||||
return buffer.append(name).toString();
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ public class BasicSqlLimitOffset implements BasicSqlLimiter {
|
||||
sb.append(dbSql);
|
||||
|
||||
if (maxRows > 0) {
|
||||
sb.append(" ").append(LIMIT);
|
||||
sb.append(" ").append(maxRows);
|
||||
sb.append(' ').append(LIMIT);
|
||||
sb.append(' ').append(maxRows);
|
||||
}
|
||||
if (firstRow > 0) {
|
||||
sb.append(" ").append(OFFSET).append(" ");
|
||||
sb.append(' ').append(OFFSET).append(' ');
|
||||
sb.append(firstRow);
|
||||
}
|
||||
return sb.toString();
|
||||
|
||||
@@ -673,7 +673,7 @@ public class DatabasePlatform {
|
||||
|
||||
protected String withForUpdate(String sql, Query.LockWait lockWait, Query.LockType lockType) {
|
||||
// silently assume the database does not support the "for update" clause.
|
||||
log.log(INFO, "it seems your database does not support the 'for update' clause");
|
||||
log.log(INFO, "it seems your database does not support the ''for update'' clause");
|
||||
return sql;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,16 @@ public class DbPlatformType implements ExtraDbTypes {
|
||||
*/
|
||||
private final boolean canHaveLength;
|
||||
|
||||
/**
|
||||
* The maximum length supported by this platform type. If length is too big, fallback is used.
|
||||
*/
|
||||
private final int maxLength;
|
||||
|
||||
/**
|
||||
* Use this platform type if length exceedes
|
||||
*/
|
||||
private final DbPlatformType fallback;
|
||||
|
||||
/**
|
||||
* Parse a type definition into a DbPlatformType.
|
||||
* <p>
|
||||
@@ -53,6 +63,41 @@ public class DbPlatformType implements ExtraDbTypes {
|
||||
this(name, defaultLength, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct without length, but with a max length limit and a fallback type, that is used if maxLength is exceeded.
|
||||
* This can be used to use <ul>
|
||||
* <li>"longtext" for unspecified length</li>
|
||||
* <li>"text" for length up to 2^16-1</li>
|
||||
* <li>"mediumtext" for length up to 2^24-1</li>
|
||||
* <li>"longtext" else</li>
|
||||
* </ul>
|
||||
*/
|
||||
public DbPlatformType(String name, int maxLength, DbPlatformType fallback) {
|
||||
this.name = name;
|
||||
this.defaultLength = 0;
|
||||
this.defaultScale = 0;
|
||||
this.canHaveLength = false;
|
||||
this.maxLength = maxLength;
|
||||
this.fallback = fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with a given default length, a max length limit and a fallback type, that is used if maxLength is exceeded.
|
||||
* This can be used to use <ul>
|
||||
* <li>"varchar(255)" for unspecified length</li>
|
||||
* <li>"varchar(N)" for N <= maxLength</li>
|
||||
* <li>"varchar(max)" else</li>
|
||||
* </ul>
|
||||
*/
|
||||
public DbPlatformType(String name, int defaultPrecision, int maxLength, DbPlatformType fallback) {
|
||||
this.name = name;
|
||||
this.defaultLength = defaultPrecision;
|
||||
this.defaultScale = 0;
|
||||
this.canHaveLength = true;
|
||||
this.maxLength = maxLength;
|
||||
this.fallback = fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct for Decimal with precision and scale.
|
||||
*/
|
||||
@@ -61,6 +106,8 @@ public class DbPlatformType implements ExtraDbTypes {
|
||||
this.defaultLength = defaultPrecision;
|
||||
this.defaultScale = defaultScale;
|
||||
this.canHaveLength = true;
|
||||
this.maxLength = Integer.MAX_VALUE;
|
||||
this.fallback = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,6 +121,8 @@ public class DbPlatformType implements ExtraDbTypes {
|
||||
this.defaultLength = 0;
|
||||
this.defaultScale = 0;
|
||||
this.canHaveLength = canHaveLength;
|
||||
this.maxLength = Integer.MAX_VALUE;
|
||||
this.fallback = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,33 +173,33 @@ public class DbPlatformType implements ExtraDbTypes {
|
||||
*/
|
||||
public String renderType(int deployLength, int deployScale, boolean strict) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(name);
|
||||
if (canHaveLength || !strict) {
|
||||
renderLengthScale(deployLength, deployScale, sb);
|
||||
}
|
||||
int len = deployLength != 0 ? deployLength : defaultLength;
|
||||
if (len > maxLength) {
|
||||
return fallback.renderType(deployLength, deployScale, strict);
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(name);
|
||||
if ((canHaveLength || !strict) && len > 0) {
|
||||
renderLengthScale(len, deployScale, sb);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the length and scale part of the column definition.
|
||||
*/
|
||||
protected void renderLengthScale(int deployLength, int deployScale, StringBuilder sb) {
|
||||
protected void renderLengthScale(int len, int deployScale, StringBuilder sb) {
|
||||
// see if there is a precision/scale to add (or not)
|
||||
int len = deployLength != 0 ? deployLength : defaultLength;
|
||||
if (len == Integer.MAX_VALUE) {
|
||||
sb.append("(max)"); // TODO: this is sqlserver specific
|
||||
} else if (len > 0) {
|
||||
sb.append("(");
|
||||
sb.append(len);
|
||||
int scale = deployScale != 0 ? deployScale : defaultScale;
|
||||
if (scale > 0) {
|
||||
sb.append(",");
|
||||
sb.append(scale);
|
||||
}
|
||||
sb.append(")");
|
||||
sb.append('(');
|
||||
sb.append(len);
|
||||
int scale = deployScale != 0 ? deployScale : defaultScale;
|
||||
if (scale > 0) {
|
||||
sb.append(',');
|
||||
sb.append(scale);
|
||||
}
|
||||
sb.append(')');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,22 +16,6 @@ public interface MetaInfoManager {
|
||||
*/
|
||||
ServerMetrics collectMetrics();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to collectMetrics().asJson().
|
||||
*/
|
||||
@Deprecated
|
||||
default ServerMetricsAsJson collectMetricsAsJson() {
|
||||
return collectMetrics().asJson();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated migrate to collectMetrics().asData().
|
||||
*/
|
||||
@Deprecated
|
||||
default List<MetricData> collectMetricsAsData() {
|
||||
return collectMetrics().asData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Visit the metrics resetting and collecting/reporting as desired.
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,8 @@ package io.ebean.meta;
|
||||
|
||||
import io.ebean.ProfileLocation;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* Meta data for captured query plan.
|
||||
*/
|
||||
@@ -51,4 +53,14 @@ public interface MetaQueryPlan {
|
||||
* Return the total count of times bind capture has occurred.
|
||||
*/
|
||||
long captureCount();
|
||||
|
||||
/**
|
||||
* Return the time taken to capture this plan in microseconds.
|
||||
*/
|
||||
long captureMicros();
|
||||
|
||||
/**
|
||||
* Return the instant when the bind values were captured.
|
||||
*/
|
||||
Instant whenCaptured();
|
||||
}
|
||||
|
||||
@@ -118,28 +118,28 @@ final class MetricsAsJson implements ServerMetricsAsJson {
|
||||
|
||||
private void objStart() throws IOException {
|
||||
objKeyCounter = 0;
|
||||
writer.append("{");
|
||||
writer.append('{');
|
||||
}
|
||||
|
||||
private void objEnd() throws IOException {
|
||||
writer.append("}");
|
||||
writer.append('}');
|
||||
}
|
||||
|
||||
private void listStart() throws IOException {
|
||||
listCounter = 0;
|
||||
writer.append("[");
|
||||
writer.append('[');
|
||||
writer.append(newLine);
|
||||
}
|
||||
|
||||
private void listEnd() throws IOException {
|
||||
writer.append("]");
|
||||
writer.append(']');
|
||||
}
|
||||
|
||||
private void key(String key) throws IOException {
|
||||
if (objKeyCounter++ > 0) {
|
||||
writer.append(", ");
|
||||
}
|
||||
writer.append("\"").append(key).append("\":");
|
||||
writer.append('"').append(key).append("\":");
|
||||
}
|
||||
|
||||
private void val(long count) throws IOException {
|
||||
@@ -147,12 +147,12 @@ final class MetricsAsJson implements ServerMetricsAsJson {
|
||||
}
|
||||
|
||||
private void val(String val) throws IOException {
|
||||
writer.append("\"").append(val).append("\"");
|
||||
writer.append('"').append(val).append('"');
|
||||
}
|
||||
|
||||
private void metricStart(MetaMetric metric) throws IOException {
|
||||
if (listCounter++ > 0) {
|
||||
writer.append(",").append(newLine);
|
||||
writer.append(',').append(newLine);
|
||||
}
|
||||
objStart();
|
||||
key("name");
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.ebean.service;
|
||||
|
||||
import io.ebean.InTuples;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Internal extension to InTuples.
|
||||
*/
|
||||
public interface SpiInTuples extends InTuples {
|
||||
|
||||
/**
|
||||
* Return the properties of the tuples.
|
||||
*/
|
||||
String[] properties();
|
||||
|
||||
/**
|
||||
* Return all the tuple entries.
|
||||
*/
|
||||
List<Object[]> entries();
|
||||
|
||||
}
|
||||
@@ -205,7 +205,7 @@ public class PathProperties implements FetchPath {
|
||||
sb.append(it.next());
|
||||
hasNext = it.hasNext();
|
||||
if (hasNext) {
|
||||
sb.append(",");
|
||||
sb.append(',');
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
|
||||
@@ -25,14 +25,14 @@ public final class CamelCaseHelper {
|
||||
lastUpper = i;
|
||||
} else if (Character.isDigit(c)) {
|
||||
if (i > lastUpper + 1 && !digitsCompressed) {
|
||||
sb.append("_");
|
||||
sb.append('_');
|
||||
lastUpper = i;
|
||||
}
|
||||
sb.append(c);
|
||||
|
||||
} else if (Character.isUpperCase(c)) {
|
||||
if (i > lastUpper + 1) {
|
||||
sb.append("_");
|
||||
sb.append('_');
|
||||
}
|
||||
sb.append(Character.toLowerCase(c));
|
||||
lastUpper = i;
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package io.ebean;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class ListsTest {
|
||||
|
||||
@Test
|
||||
void partition_empty() {
|
||||
List<List<Integer>> partitions = Lists.partition(List.of(), 5);
|
||||
assertThat(partitions).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void partition_lt() {
|
||||
List<List<Integer>> partitions = Lists.partition(List.of(1, 2, 3, 4), 5);
|
||||
assertThat(partitions).hasSize(1);
|
||||
assertThat(partitions.get(0)).hasSize(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void partition_eq() {
|
||||
List<List<Integer>> partitions = Lists.partition(List.of(1, 2, 3, 4, 5), 5);
|
||||
assertThat(partitions).hasSize(1);
|
||||
assertThat(partitions.get(0)).hasSize(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void partition_gt() {
|
||||
List<List<Integer>> partitions = Lists.partition(List.of(1, 2, 3, 4, 5, 6), 5);
|
||||
assertThat(partitions).hasSize(2);
|
||||
assertThat(partitions.get(0)).hasSize(5);
|
||||
assertThat(partitions.get(1)).hasSize(1);
|
||||
assertThat(partitions.get(0)).containsExactly(1, 2, 3, 4, 5);
|
||||
assertThat(partitions.get(1)).containsExactly(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
void partition_gt1_letters() {
|
||||
var partitions = Lists.partition(List.of("a", "b", "c", "d"), 3);
|
||||
assertThat(partitions).hasSize(2);
|
||||
assertThat(partitions.get(0)).hasSize(3);
|
||||
assertThat(partitions.get(1)).hasSize(1);
|
||||
assertThat(partitions.get(0)).containsExactly("a", "b", "c");
|
||||
assertThat(partitions.get(1)).containsExactly("d");
|
||||
}
|
||||
|
||||
@Test
|
||||
void partition_gt1a_letters() {
|
||||
var partitions = Lists.partition(List.of("a", "b", "c", "d", "e"), 3);
|
||||
assertThat(partitions).hasSize(2);
|
||||
assertThat(partitions.get(0)).hasSize(3);
|
||||
assertThat(partitions.get(1)).hasSize(2);
|
||||
assertThat(partitions.get(0)).containsExactly("a", "b", "c");
|
||||
assertThat(partitions.get(1)).containsExactly("d", "e");
|
||||
}
|
||||
|
||||
@Test
|
||||
void partition_eq2_letters() {
|
||||
var partitions = Lists.partition(List.of("a", "b", "c", "d", "e", "f"), 3);
|
||||
assertThat(partitions).hasSize(2);
|
||||
assertThat(partitions.get(0)).hasSize(3);
|
||||
assertThat(partitions.get(1)).hasSize(3);
|
||||
assertThat(partitions.get(0)).containsExactly("a", "b", "c");
|
||||
assertThat(partitions.get(1)).containsExactly("d", "e", "f");
|
||||
}
|
||||
|
||||
@Test
|
||||
void partition_gt2_letters() {
|
||||
var partitions = Lists.partition(List.of("a", "b", "c", "d", "e", "f", "g"), 3);
|
||||
assertThat(partitions).hasSize(3);
|
||||
assertThat(partitions.get(0)).hasSize(3);
|
||||
assertThat(partitions.get(1)).hasSize(3);
|
||||
assertThat(partitions.get(2)).hasSize(1);
|
||||
assertThat(partitions.get(0)).containsExactly("a", "b", "c");
|
||||
assertThat(partitions.get(1)).containsExactly("d", "e", "f");
|
||||
assertThat(partitions.get(2)).containsExactly("g");
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
</parent>
|
||||
<!-- <parent>-->
|
||||
<!-- <groupId>org.avaje</groupId>-->
|
||||
<!-- <artifactId>java8-oss</artifactId>-->
|
||||
<!-- <version>2.2</version>-->
|
||||
<!-- </parent>-->
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
<name>ebean autotune</name>
|
||||
<description>ebean automatic query tuning module</description>
|
||||
<artifactId>ebean-autotune</artifactId>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- JAVAX-DEPENDENCY-START -->
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jaxb</groupId>
|
||||
<artifactId>jaxb-runtime</artifactId>
|
||||
<version>2.3.6</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- JAVAX-DEPENDENCY-END -->
|
||||
<!-- JAKARTA-DEPENDENCY-START ___
|
||||
<dependency>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-impl</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
____ JAKARTA-DEPENDENCY-END -->
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-datasource</artifactId>
|
||||
<version>${ebean-datasource.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>io.repaint.maven</groupId>
|
||||
<artifactId>tiles-maven-plugin</artifactId>
|
||||
<version>2.34</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<tiles>
|
||||
<tile>io.ebean.tile:enhancement:13.17.1</tile>
|
||||
</tiles>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,133 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.model;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Java class for anonymous complex type.
|
||||
* <p>
|
||||
* The following schema fragment specifies the expected content contained within this class.
|
||||
* <p>
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/autotune}origin" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/autotune}profileDiff" minOccurs="0"/>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/autotune}profileNew" minOccurs="0"/>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/autotune}profileEmpty" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"origin",
|
||||
"profileDiff",
|
||||
"profileNew",
|
||||
"profileEmpty"
|
||||
})
|
||||
@XmlRootElement(name = "autotune")
|
||||
public class Autotune {
|
||||
|
||||
protected List<Origin> origin;
|
||||
protected ProfileDiff profileDiff;
|
||||
protected ProfileNew profileNew;
|
||||
protected ProfileEmpty profileEmpty;
|
||||
|
||||
/**
|
||||
* Gets the value of the origin property.
|
||||
* <p>
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the origin property.
|
||||
* <p>
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getOrigin().add(newItem);
|
||||
* </pre>
|
||||
* <p>
|
||||
* <p>
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link Origin }
|
||||
*/
|
||||
public List<Origin> getOrigin() {
|
||||
if (origin == null) {
|
||||
origin = new ArrayList<>();
|
||||
}
|
||||
return this.origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the profileDiff property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link ProfileDiff }
|
||||
*/
|
||||
public ProfileDiff getProfileDiff() {
|
||||
return profileDiff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the profileDiff property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link ProfileDiff }
|
||||
*/
|
||||
public void setProfileDiff(ProfileDiff value) {
|
||||
this.profileDiff = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the profileNew property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link ProfileNew }
|
||||
*/
|
||||
public ProfileNew getProfileNew() {
|
||||
return profileNew;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the profileNew property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link ProfileNew }
|
||||
*/
|
||||
public void setProfileNew(ProfileNew value) {
|
||||
this.profileNew = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the profileEmpty property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link ProfileEmpty }
|
||||
*/
|
||||
public ProfileEmpty getProfileEmpty() {
|
||||
return profileEmpty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the profileEmpty property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link ProfileEmpty }
|
||||
*/
|
||||
public void setProfileEmpty(ProfileEmpty value) {
|
||||
this.profileEmpty = value;
|
||||
}
|
||||
|
||||
}
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.model;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRegistry;
|
||||
|
||||
|
||||
/**
|
||||
* This object contains factory methods for each
|
||||
* Java content interface and Java element interface
|
||||
* generated in the io.ebeaninternal.server.autotune.model package.
|
||||
* <p>An ObjectFactory allows you to programatically
|
||||
* construct new instances of the Java representation
|
||||
* for XML content. The Java representation of XML
|
||||
* content can consist of schema derived interfaces
|
||||
* and classes representing the binding of schema
|
||||
* type definitions, element declarations and model
|
||||
* groups. Factory methods for each of these are
|
||||
* provided in this class.
|
||||
*/
|
||||
@XmlRegistry
|
||||
public class ObjectFactory {
|
||||
|
||||
|
||||
/**
|
||||
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: io.ebeaninternal.server.autotune.model
|
||||
*/
|
||||
public ObjectFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link ProfileNew }
|
||||
*/
|
||||
public ProfileNew createProfileNew() {
|
||||
return new ProfileNew();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Origin }
|
||||
*/
|
||||
public Origin createOrigin() {
|
||||
return new Origin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link ProfileEmpty }
|
||||
*/
|
||||
public ProfileEmpty createProfileEmpty() {
|
||||
return new ProfileEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link Autotune }
|
||||
*/
|
||||
public Autotune createAutotune() {
|
||||
return new Autotune();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of {@link ProfileDiff }
|
||||
*/
|
||||
public ProfileDiff createProfileDiff() {
|
||||
return new ProfileDiff();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.model;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
* <p>
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
* <p>
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element name="callStack" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* <attribute name="key" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="beanType" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="detail" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* <attribute name="original" type="{http://www.w3.org/2001/XMLSchema}string" />
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"callStack"
|
||||
})
|
||||
@XmlRootElement(name = "origin")
|
||||
public class Origin {
|
||||
|
||||
protected String callStack;
|
||||
@XmlAttribute(name = "key", required = true)
|
||||
protected String key;
|
||||
@XmlAttribute(name = "beanType")
|
||||
protected String beanType;
|
||||
@XmlAttribute(name = "detail")
|
||||
protected String detail;
|
||||
@XmlAttribute(name = "original")
|
||||
protected String original;
|
||||
|
||||
/**
|
||||
* Gets the value of the callStack property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getCallStack() {
|
||||
return callStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the callStack property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setCallStack(String value) {
|
||||
this.callStack = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the key property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the key property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setKey(String value) {
|
||||
this.key = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the beanType property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getBeanType() {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the beanType property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setBeanType(String value) {
|
||||
this.beanType = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the detail property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getDetail() {
|
||||
return detail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the detail property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setDetail(String value) {
|
||||
this.detail = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the original property.
|
||||
*
|
||||
* @return possible object is
|
||||
* {@link String }
|
||||
*/
|
||||
public String getOriginal() {
|
||||
return original;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the original property.
|
||||
*
|
||||
* @param value allowed object is
|
||||
* {@link String }
|
||||
*/
|
||||
public void setOriginal(String value) {
|
||||
this.original = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.model;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
* <p>
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
* <p>
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/autotune}origin" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"origin"
|
||||
})
|
||||
@XmlRootElement(name = "profileDiff")
|
||||
public class ProfileDiff {
|
||||
|
||||
protected List<Origin> origin;
|
||||
|
||||
/**
|
||||
* Gets the value of the origin property.
|
||||
* <p>
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the origin property.
|
||||
* <p>
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getOrigin().add(newItem);
|
||||
* </pre>
|
||||
* <p>
|
||||
* <p>
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link Origin }
|
||||
*/
|
||||
public List<Origin> getOrigin() {
|
||||
if (origin == null) {
|
||||
origin = new ArrayList<>();
|
||||
}
|
||||
return this.origin;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.model;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
* <p>
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
* <p>
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/autotune}origin" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"origin"
|
||||
})
|
||||
@XmlRootElement(name = "profileEmpty")
|
||||
public class ProfileEmpty {
|
||||
|
||||
protected List<Origin> origin;
|
||||
|
||||
/**
|
||||
* Gets the value of the origin property.
|
||||
* <p>
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the origin property.
|
||||
* <p>
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getOrigin().add(newItem);
|
||||
* </pre>
|
||||
* <p>
|
||||
* <p>
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link Origin }
|
||||
*/
|
||||
public List<Origin> getOrigin() {
|
||||
if (origin == null) {
|
||||
origin = new ArrayList<>();
|
||||
}
|
||||
return this.origin;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.model;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
* <p>
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
* <p>
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element ref="{http://ebean-orm.github.io/xml/ns/autotune}origin" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"origin"
|
||||
})
|
||||
@XmlRootElement(name = "profileNew")
|
||||
public class ProfileNew {
|
||||
|
||||
protected List<Origin> origin;
|
||||
|
||||
/**
|
||||
* Gets the value of the origin property.
|
||||
* <p>
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the origin property.
|
||||
* <p>
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getOrigin().add(newItem);
|
||||
* </pre>
|
||||
* <p>
|
||||
* <p>
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link Origin }
|
||||
*/
|
||||
public List<Origin> getOrigin() {
|
||||
if (origin == null) {
|
||||
origin = new ArrayList<>();
|
||||
}
|
||||
return this.origin;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
@javax.xml.bind.annotation.XmlSchema(namespace = "http://ebean-orm.github.io/xml/ns/autotune", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
|
||||
package io.ebeaninternal.server.autotune.model;
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.ebeaninternal.server.autotune.model.Autotune;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Event where all tuned query information is collected.
|
||||
* <p>
|
||||
* This is for writing the "all" file on shutdown when using runtime tuning.
|
||||
* </p>
|
||||
*/
|
||||
public class AutoTuneAllCollection {
|
||||
|
||||
final Autotune document = new Autotune();
|
||||
|
||||
final BaseQueryTuner queryTuner;
|
||||
|
||||
/**
|
||||
* Construct to collect/report all tuned queries.
|
||||
*/
|
||||
public AutoTuneAllCollection(BaseQueryTuner queryTuner) {
|
||||
this.queryTuner = queryTuner;
|
||||
loadAllTuned();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of origin elements in the document.
|
||||
*/
|
||||
public int size() {
|
||||
return document.getOrigin().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Autotune document object.
|
||||
*/
|
||||
public Autotune getDocument() {
|
||||
return document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the document as an xml file.
|
||||
*/
|
||||
public void writeFile(String filePrefix, boolean withNow) {
|
||||
|
||||
AutoTuneXmlWriter writer = new AutoTuneXmlWriter();
|
||||
writer.write(document, filePrefix, withNow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all the existing query tuning into the document.
|
||||
*/
|
||||
private void loadAllTuned() {
|
||||
|
||||
Collection<TunedQueryInfo> all = queryTuner.getAll();
|
||||
for (TunedQueryInfo tuned : all) {
|
||||
document.getOrigin().add(tuned.getOrigin());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-115
@@ -1,115 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.ebean.bean.ObjectGraphOrigin;
|
||||
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Profiling information collected.
|
||||
*/
|
||||
public class AutoTuneCollection {
|
||||
|
||||
final List<Entry> entries = new ArrayList<>();
|
||||
|
||||
public Entry add(ObjectGraphOrigin origin, OrmQueryDetail detail, String sourceQuery) {
|
||||
Entry entry = new Entry(origin, detail, sourceQuery);
|
||||
entries.add(entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public List<Entry> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Profiling entry at a given origin point.
|
||||
*/
|
||||
public static class Entry {
|
||||
|
||||
/**
|
||||
* Profiling origin point.
|
||||
*/
|
||||
private final ObjectGraphOrigin origin;
|
||||
|
||||
/**
|
||||
* The tuned query detail.
|
||||
*/
|
||||
private final OrmQueryDetail detail;
|
||||
|
||||
/**
|
||||
* The original/existing query detail.
|
||||
*/
|
||||
private final String originalQuery;
|
||||
|
||||
/**
|
||||
* Summary execution statistics for queries related to this origin point.
|
||||
*/
|
||||
private final List<EntryQuery> queries = new ArrayList<>();
|
||||
|
||||
public Entry(ObjectGraphOrigin origin, OrmQueryDetail detail, String originalQuery) {
|
||||
this.origin = origin;
|
||||
this.detail = detail;
|
||||
this.originalQuery = originalQuery;
|
||||
}
|
||||
|
||||
public void addQuery(EntryQuery entryQuery) {
|
||||
queries.add(entryQuery);
|
||||
}
|
||||
|
||||
public ObjectGraphOrigin getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
public OrmQueryDetail getDetail() {
|
||||
return detail;
|
||||
}
|
||||
|
||||
public String getOriginalQuery() {
|
||||
return originalQuery;
|
||||
}
|
||||
|
||||
public List<EntryQuery> getQueries() {
|
||||
return queries;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary query execution statistics for the origin point.
|
||||
*/
|
||||
public static class EntryQuery {
|
||||
|
||||
final String path;
|
||||
final long exeCount;
|
||||
final long totalBeanLoaded;
|
||||
final long totalMicros;
|
||||
|
||||
public EntryQuery(String path, long exeCount, long totalBeanLoaded, long totalMicros) {
|
||||
this.path = path;
|
||||
this.exeCount = exeCount;
|
||||
this.totalBeanLoaded = totalBeanLoaded;
|
||||
this.totalMicros = totalMicros;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the relative path with empty string for the origin query.
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public long getExeCount() {
|
||||
return exeCount;
|
||||
}
|
||||
|
||||
public long getTotalBeanLoaded() {
|
||||
return totalBeanLoaded;
|
||||
}
|
||||
|
||||
public long getTotalMicros() {
|
||||
return totalMicros;
|
||||
}
|
||||
}
|
||||
}
|
||||
-161
@@ -1,161 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.ebean.bean.ObjectGraphOrigin;
|
||||
import io.ebeaninternal.server.autotune.model.Autotune;
|
||||
import io.ebeaninternal.server.autotune.model.Origin;
|
||||
import io.ebeaninternal.server.autotune.model.ProfileDiff;
|
||||
import io.ebeaninternal.server.autotune.model.ProfileNew;
|
||||
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
|
||||
|
||||
/**
|
||||
* Event where profiling information is collected and processed for differences
|
||||
* relative to the current query tuning.
|
||||
*/
|
||||
public class AutoTuneDiffCollection {
|
||||
|
||||
final Autotune document = new Autotune();
|
||||
|
||||
final AutoTuneCollection profiling;
|
||||
|
||||
final BaseQueryTuner queryTuner;
|
||||
|
||||
final boolean updateTuning;
|
||||
|
||||
int newCount;
|
||||
|
||||
int diffCount;
|
||||
|
||||
/**
|
||||
* Construct to collect/report the new/diff query tuning entries.
|
||||
*/
|
||||
public AutoTuneDiffCollection(AutoTuneCollection profiling, BaseQueryTuner queryTuner, boolean updateTuning) {
|
||||
this.profiling = profiling;
|
||||
this.queryTuner = queryTuner;
|
||||
this.updateTuning = updateTuning;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if there are no new or diff entries.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return newCount == 0 && diffCount == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the underlying Autotune document object.
|
||||
*/
|
||||
public Autotune getDocument() {
|
||||
return document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of diff entries.
|
||||
*/
|
||||
public int getDiffCount() {
|
||||
return diffCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of new entries.
|
||||
*/
|
||||
public int getNewCount() {
|
||||
return newCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the total new and diff entries.
|
||||
*/
|
||||
public int getChangeCount() {
|
||||
return newCount + diffCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the underlying document as an xml file.
|
||||
*/
|
||||
public void writeFile(String filePrefix) {
|
||||
|
||||
AutoTuneXmlWriter writer = new AutoTuneXmlWriter();
|
||||
writer.write(document, filePrefix, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process checking profiling entries against existing query tuning.
|
||||
*/
|
||||
public void process() {
|
||||
|
||||
for (AutoTuneCollection.Entry entry : profiling.getEntries()) {
|
||||
addToDocument(entry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the entry is new or diff and add as necessary.
|
||||
*/
|
||||
private void addToDocument(AutoTuneCollection.Entry entry) {
|
||||
|
||||
ObjectGraphOrigin point = entry.getOrigin();
|
||||
OrmQueryDetail profileDetail = entry.getDetail();
|
||||
|
||||
// compare with the existing query tuning entry
|
||||
OrmQueryDetail tuneDetail = queryTuner.get(point.key());
|
||||
if (tuneDetail == null) {
|
||||
addToDocumentNewEntry(entry, point);
|
||||
|
||||
} else if (!tuneDetail.isAutoTuneEqual(profileDetail)) {
|
||||
addToDocumentDiffEntry(entry, point, tuneDetail);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add as a diff entry.
|
||||
*/
|
||||
private void addToDocumentDiffEntry(AutoTuneCollection.Entry entry, ObjectGraphOrigin point, OrmQueryDetail tuneDetail) {
|
||||
|
||||
diffCount++;
|
||||
|
||||
Origin origin = createOrigin(entry, point, tuneDetail.asString());
|
||||
ProfileDiff diff = document.getProfileDiff();
|
||||
if (diff == null) {
|
||||
diff = new ProfileDiff();
|
||||
document.setProfileDiff(diff);
|
||||
}
|
||||
diff.getOrigin().add(origin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add as a "new" entry.
|
||||
*/
|
||||
private void addToDocumentNewEntry(AutoTuneCollection.Entry entry, ObjectGraphOrigin point) {
|
||||
|
||||
newCount++;
|
||||
|
||||
ProfileNew profileNew = document.getProfileNew();
|
||||
if (profileNew == null) {
|
||||
profileNew = new ProfileNew();
|
||||
document.setProfileNew(profileNew);
|
||||
}
|
||||
Origin origin = createOrigin(entry, point, entry.getOriginalQuery());
|
||||
profileNew.getOrigin().add(origin);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the XML Origin bean for the given entry and ObjectGraphOrigin.
|
||||
*/
|
||||
private Origin createOrigin(AutoTuneCollection.Entry entry, ObjectGraphOrigin point, String query) {
|
||||
|
||||
Origin origin = new Origin();
|
||||
origin.setKey(point.key());
|
||||
origin.setBeanType(point.beanType());
|
||||
origin.setDetail(entry.getDetail().asString());
|
||||
origin.setCallStack(point.callOrigin().description());
|
||||
origin.setOriginal(query);
|
||||
|
||||
if (updateTuning) {
|
||||
queryTuner.put(origin);
|
||||
}
|
||||
|
||||
return origin;
|
||||
}
|
||||
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.server.autotune.AutoTuneService;
|
||||
import io.ebeaninternal.server.autotune.AutoTuneServiceProvider;
|
||||
|
||||
public class AutoTuneServiceFactory implements AutoTuneServiceProvider {
|
||||
|
||||
@Override
|
||||
public AutoTuneService create(SpiEbeanServer server, DatabaseConfig config) {
|
||||
return new DefaultAutoTuneService(server, config);
|
||||
}
|
||||
|
||||
}
|
||||
-52
@@ -1,52 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
|
||||
import io.ebeaninternal.server.autotune.model.Autotune;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Reads a profiling xml document.
|
||||
*/
|
||||
public class AutoTuneXmlReader {
|
||||
|
||||
/**
|
||||
* Read and return a Profiling from an xml file.
|
||||
*/
|
||||
public static Autotune read(File file) {
|
||||
try {
|
||||
return readFile(file);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected static Autotune readFile(File file) throws IOException {
|
||||
if (!file.exists()) {
|
||||
return new Autotune();
|
||||
}
|
||||
try (FileInputStream is = new FileInputStream(file)) {
|
||||
return read(is);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and return a Profiling from an xml document.
|
||||
*/
|
||||
public static Autotune read(InputStream is) {
|
||||
try {
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance(Autotune.class);
|
||||
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
|
||||
return (Autotune) unmarshaller.unmarshal(is);
|
||||
} catch (JAXBException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
|
||||
import io.ebeaninternal.server.autotune.model.Autotune;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Simple writer for output of the AutoTune Profiling as an XML document.
|
||||
*/
|
||||
public class AutoTuneXmlWriter {
|
||||
|
||||
/**
|
||||
* Return 'now' as a string to second precision.
|
||||
*/
|
||||
public static String now() {
|
||||
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd-HHmmss");
|
||||
return df.format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the document as xml file with the given prefix.
|
||||
*/
|
||||
public void write(Autotune document, String fileName, boolean withNow) {
|
||||
|
||||
SortAutoTuneDocument.sort(document);
|
||||
|
||||
if (withNow) {
|
||||
fileName += "-" + now() + ".xml";
|
||||
}
|
||||
|
||||
// write the file with serverName and now suffix as we can output the profiling many times
|
||||
write(document, new File(fileName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write Profiling to a file as xml.
|
||||
*/
|
||||
public void write(Autotune profiling, File file) {
|
||||
|
||||
try {
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance(Autotune.class);
|
||||
Marshaller marshaller = jaxbContext.createMarshaller();
|
||||
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
|
||||
marshaller.marshal(profiling, file);
|
||||
|
||||
} catch (JAXBException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-204
@@ -1,204 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.ebean.bean.CallOrigin;
|
||||
import io.ebean.bean.ObjectGraphNode;
|
||||
import io.ebean.config.AutoTuneConfig;
|
||||
import io.ebean.config.AutoTuneMode;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.autotune.ProfilingListener;
|
||||
import io.ebeaninternal.server.autotune.model.Origin;
|
||||
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class BaseQueryTuner {
|
||||
|
||||
private final boolean queryTuning;
|
||||
|
||||
private final boolean profiling;
|
||||
|
||||
private final AutoTuneMode mode;
|
||||
|
||||
/**
|
||||
* Map of the tuned query details per profile query point.
|
||||
*/
|
||||
private final Map<String, TunedQueryInfo> tunedQueryInfoMap = new ConcurrentHashMap<>();
|
||||
|
||||
private final SpiEbeanServer server;
|
||||
|
||||
private final ProfilingListener profilingListener;
|
||||
|
||||
/**
|
||||
* Flag set true when there is no profiling or query tuning.
|
||||
*/
|
||||
private final boolean skipAll;
|
||||
|
||||
BaseQueryTuner(AutoTuneConfig config, SpiEbeanServer server, ProfilingListener profilingListener) {
|
||||
this.server = server;
|
||||
this.profilingListener = profilingListener;
|
||||
this.mode = config.getMode();
|
||||
this.queryTuning = config.isQueryTuning();
|
||||
this.profiling = config.isProfiling();
|
||||
this.skipAll = !queryTuning && !profiling;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the current tuned query entries.
|
||||
*/
|
||||
public Collection<TunedQueryInfo> getAll() {
|
||||
return tunedQueryInfoMap.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a query tuning entry.
|
||||
*/
|
||||
public void put(Origin origin) {
|
||||
|
||||
tunedQueryInfoMap.put(origin.getKey(), new TunedQueryInfo(origin));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the tuned query information.
|
||||
*/
|
||||
public void load(String key, TunedQueryInfo queryInfo) {
|
||||
tunedQueryInfoMap.put(key, queryInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the detail currently used for tuning.
|
||||
* This returns null if there is currently no matching tuning.
|
||||
*/
|
||||
public OrmQueryDetail get(String key) {
|
||||
TunedQueryInfo info = tunedQueryInfoMap.get(key);
|
||||
return (info == null) ? null : info.getTunedDetail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto tune the query and enable profiling.
|
||||
*/
|
||||
boolean tuneQuery(SpiQuery<?> query) {
|
||||
|
||||
if (skipAll || !tunableQuery(query)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (query.getProfilingListener() != null) {
|
||||
// profiling secondary query
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!useTuning(query)) {
|
||||
if (profiling) {
|
||||
profiling(query, server.createCallOrigin());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (query.getParentNode() != null) {
|
||||
// This is a +lazy/+query query with profiling on.
|
||||
// We continue to collect the profiling information.
|
||||
query.setProfilingListener(profilingListener);
|
||||
return true;
|
||||
}
|
||||
|
||||
// create a query point to identify the query
|
||||
CallOrigin callOrigin = server.createCallOrigin();
|
||||
ObjectGraphNode origin = query.setOrigin(callOrigin);
|
||||
|
||||
if (profiling) {
|
||||
if (profilingListener.isProfileRequest(origin, query)) {
|
||||
// collect more profiling based on profiling rate etc
|
||||
query.setProfilingListener(profilingListener);
|
||||
}
|
||||
}
|
||||
|
||||
if (queryTuning) {
|
||||
// get current "tuned fetch" for this query point
|
||||
TunedQueryInfo tuneInfo = tunedQueryInfoMap.get(origin.origin().key());
|
||||
return tuneInfo != null && tuneInfo.tuneQuery(query);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return false for row count, find ids, subQuery, delete and Versions queries.
|
||||
* <p>
|
||||
* These queries are not applicable for autoTune in that they don't have a select/fetch (fetch group).
|
||||
* </p>
|
||||
* <p>
|
||||
* We also exclude queries that are explicitly set to load the L2 bean cache as we want full beans
|
||||
* in that case.
|
||||
* </p>
|
||||
*/
|
||||
private boolean tunableQuery(SpiQuery<?> query) {
|
||||
SpiQuery.Type type = query.getType();
|
||||
switch (type) {
|
||||
case COUNT:
|
||||
case ATTRIBUTE:
|
||||
case ATTRIBUTE_SET:
|
||||
case ID_LIST:
|
||||
case UPDATE:
|
||||
case DELETE:
|
||||
case SQ_EXISTS:
|
||||
case SQ_EX:
|
||||
return false;
|
||||
default:
|
||||
// not using autoTune when explicitly loading the l2 bean cache
|
||||
// or when using Versions query
|
||||
return !query.isForceHitDatabase() && SpiQuery.TemporalMode.VERSIONS != query.getTemporalMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void profiling(SpiQuery<?> query, CallOrigin call) {
|
||||
|
||||
// create a query point to identify the query
|
||||
ObjectGraphNode origin = query.setOrigin(call);
|
||||
if (profilingListener.isProfileRequest(origin, query)) {
|
||||
// collect more profiling based on profiling rate etc
|
||||
query.setProfilingListener(profilingListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if we should try to tune this query.
|
||||
*/
|
||||
private boolean useTuning(SpiQuery<?> query) {
|
||||
|
||||
Boolean autoTune = query.isAutoTune();
|
||||
if (autoTune != null) {
|
||||
// explicitly set...
|
||||
return autoTune;
|
||||
|
||||
} else {
|
||||
// determine using implicit mode...
|
||||
switch (mode) {
|
||||
case DEFAULT_ON:
|
||||
return true;
|
||||
|
||||
case DEFAULT_OFF:
|
||||
return false;
|
||||
|
||||
case DEFAULT_ONIFEMPTY:
|
||||
return query.isDetailEmpty();
|
||||
|
||||
default:
|
||||
throw new PersistenceException("Invalid AutoTuneMode " + mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the keys as a set.
|
||||
*/
|
||||
public Set<String> keySet() {
|
||||
return tunedQueryInfoMap.keySet();
|
||||
}
|
||||
}
|
||||
-295
@@ -1,295 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.avaje.applog.AppLog;
|
||||
import io.ebean.config.AutoTuneConfig;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.autotune.AutoTuneService;
|
||||
import io.ebeaninternal.server.autotune.model.Autotune;
|
||||
import io.ebeaninternal.server.autotune.model.Origin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
|
||||
/**
|
||||
* Implementation of the AutoTuneService which is comprised of profiling and query tuning.
|
||||
*/
|
||||
public class DefaultAutoTuneService implements AutoTuneService {
|
||||
|
||||
private static final System.Logger logger = AppLog.getLogger(DefaultAutoTuneService.class);
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
private final SpiEbeanServer server;
|
||||
|
||||
private final long defaultGarbageCollectionWait;
|
||||
|
||||
private final boolean skipGarbageCollectionOnShutdown;
|
||||
|
||||
private final boolean skipProfileReportingOnShutdown;
|
||||
|
||||
private final BaseQueryTuner queryTuner;
|
||||
|
||||
private final ProfileManager profileManager;
|
||||
|
||||
private final boolean profiling;
|
||||
|
||||
private final boolean queryTuning;
|
||||
|
||||
private final String tuningFile;
|
||||
|
||||
private final String profilingFile;
|
||||
|
||||
private final String serverName;
|
||||
|
||||
private final int profilingUpdateFrequency;
|
||||
|
||||
private long runtimeChangeCount;
|
||||
|
||||
public DefaultAutoTuneService(SpiEbeanServer server, DatabaseConfig databaseConfig) {
|
||||
AutoTuneConfig config = databaseConfig.getAutoTuneConfig();
|
||||
this.server = server;
|
||||
this.queryTuning = config.isQueryTuning();
|
||||
this.profiling = config.isProfiling();
|
||||
this.tuningFile = config.getQueryTuningFile();
|
||||
this.profilingFile = config.getProfilingFile();
|
||||
this.profilingUpdateFrequency = config.getProfilingUpdateFrequency();
|
||||
this.serverName = server.name();
|
||||
this.profileManager = new ProfileManager(config, server);
|
||||
this.queryTuner = new BaseQueryTuner(config, server, profileManager);
|
||||
this.skipGarbageCollectionOnShutdown = config.isSkipGarbageCollectionOnShutdown();
|
||||
this.skipProfileReportingOnShutdown = config.isSkipProfileReportingOnShutdown();
|
||||
this.defaultGarbageCollectionWait = config.getGarbageCollectionWait();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the query tuning information from it's data store.
|
||||
*/
|
||||
@Override
|
||||
public void startup() {
|
||||
|
||||
if (queryTuning) {
|
||||
loadTuningFile();
|
||||
if (isRuntimeTuningUpdates()) {
|
||||
// periodically gather and update query tuning
|
||||
server.backgroundExecutor().scheduleWithFixedDelay(new ProfilingUpdate(), profilingUpdateFrequency, profilingUpdateFrequency, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if the tuning should update periodically at runtime.
|
||||
*/
|
||||
private boolean isRuntimeTuningUpdates() {
|
||||
return profilingUpdateFrequency > 0;
|
||||
}
|
||||
|
||||
private class ProfilingUpdate implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
runtimeTuningUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load tuning information from an existing tuning file.
|
||||
*/
|
||||
private void loadTuningFile() {
|
||||
File file = new File(tuningFile);
|
||||
if (file.exists()) {
|
||||
loadAutoTuneProfiling(AutoTuneXmlReader.read(file));
|
||||
} else {
|
||||
// look for autotune as a resource
|
||||
try (InputStream stream = getClass().getResourceAsStream("/" + tuningFile)) {
|
||||
if (stream != null) {
|
||||
loadAutoTuneProfiling(AutoTuneXmlReader.read(stream));
|
||||
} else {
|
||||
logger.log(WARNING, "AutoTune file {0} not found - no initial automatic query tuning", tuningFile);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Error on auto close of " + tuningFile, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadAutoTuneProfiling(Autotune profiling) {
|
||||
logger.log(INFO, "AutoTune loading {0} tuning entries", profiling.getOrigin().size());
|
||||
for (Origin origin : profiling.getOrigin()) {
|
||||
queryTuner.put(origin);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect profiling, check for new/diff to existing tuning and apply changes.
|
||||
*/
|
||||
private void runtimeTuningUpdate() {
|
||||
lock.lock();
|
||||
try {
|
||||
try {
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
AutoTuneCollection profiling = profileManager.profilingCollection(false);
|
||||
|
||||
AutoTuneDiffCollection event = new AutoTuneDiffCollection(profiling, queryTuner, true);
|
||||
event.process();
|
||||
if (event.isEmpty()) {
|
||||
long exeMillis = System.currentTimeMillis() - start;
|
||||
logger.log(DEBUG, "No query tuning updates for server:{0} executionMillis:{1}", serverName, exeMillis);
|
||||
|
||||
} else {
|
||||
// report the query tuning changes that have been made
|
||||
runtimeChangeCount += event.getChangeCount();
|
||||
event.writeFile(profilingFile + "-" + serverName + "-update");
|
||||
long exeMillis = System.currentTimeMillis() - start;
|
||||
logger.log(INFO, "query tuning updates - new:{0} diff:{1} for server:{2} executionMillis:{3}", event.getNewCount(), event.getDiffCount(), serverName, exeMillis);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.log(ERROR, "Error collecting or applying automatic query tuning", e);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void saveProfilingOnShutdown(boolean reset) {
|
||||
lock.lock();
|
||||
try {
|
||||
if (isRuntimeTuningUpdates()) {
|
||||
runtimeTuningUpdate();
|
||||
outputAllTuning();
|
||||
|
||||
} else {
|
||||
|
||||
AutoTuneCollection profiling = profileManager.profilingCollection(reset);
|
||||
|
||||
AutoTuneDiffCollection event = new AutoTuneDiffCollection(profiling, queryTuner, false);
|
||||
event.process();
|
||||
if (event.isEmpty()) {
|
||||
logger.log(INFO, "No new or diff entries for profiling server:{0}", serverName);
|
||||
|
||||
} else {
|
||||
event.writeFile(profilingFile + "-" + serverName);
|
||||
logger.log(INFO, "writing new:{0} diff:{1} profiling entries for server:{2}", event.getNewCount(), event.getDiffCount(), serverName);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output all the query tuning (the "all" file).
|
||||
* <p>
|
||||
* This is the originally loaded tuning plus any tuning changes picked up and applied at runtime.
|
||||
* </p>
|
||||
* <p>
|
||||
* This "all" file can be used as the next "ebean-autotune.xml" file.
|
||||
* </p>
|
||||
*/
|
||||
private void outputAllTuning() {
|
||||
|
||||
if (runtimeChangeCount == 0) {
|
||||
logger.log(INFO, "no runtime query tuning changes for server:{0}", serverName);
|
||||
|
||||
} else {
|
||||
AutoTuneAllCollection event = new AutoTuneAllCollection(queryTuner);
|
||||
int size = event.size();
|
||||
File existingTuning = new File(tuningFile);
|
||||
if (existingTuning.exists()) {
|
||||
// rename the existing autotune.xml file (appending 'now')
|
||||
if (!existingTuning.renameTo(new File(tuningFile + "." + AutoTuneXmlWriter.now()))) {
|
||||
logger.log(WARNING, "Failed to rename autotune file [{0}]", tuningFile);
|
||||
}
|
||||
}
|
||||
|
||||
event.writeFile(tuningFile, false);
|
||||
logger.log(INFO, "query tuning detected [{0}] changes, writing all [{1}] tuning entries for server:{2}", runtimeChangeCount, size, serverName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the listener.
|
||||
* <p>
|
||||
* We should try to collect the usage statistics by calling a System.gc().
|
||||
* This is necessary for use with short lived applications where garbage
|
||||
* collection may not otherwise occur at all.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public void shutdown() {
|
||||
if (profiling) {
|
||||
if (!skipGarbageCollectionOnShutdown && !skipProfileReportingOnShutdown) {
|
||||
// trigger GC to update profiling information on recently executed queries
|
||||
collectProfiling(-1);
|
||||
}
|
||||
if (!skipProfileReportingOnShutdown) {
|
||||
saveProfilingOnShutdown(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the profiling.
|
||||
* <p>
|
||||
* When profiling updates are applied to tuning at runtime this reports all tuning and profiling combined.
|
||||
* When profiling is not applied at runtime then this reports the diff report with new and diff entries relative
|
||||
* to the existing tuning.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public void reportProfiling() {
|
||||
saveProfilingOnShutdown(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask for a System.gc() so that we gather node usage information.
|
||||
* <p>
|
||||
* Really only want to do this sparingly but useful just prior to shutdown
|
||||
* for short run application where garbage collection may otherwise not
|
||||
* occur at all.
|
||||
* </p>
|
||||
* <p>
|
||||
* waitMillis will do a thread sleep to give the garbage collection a little
|
||||
* time to do its thing assuming we are shutting down the VM.
|
||||
* </p>
|
||||
* <p>
|
||||
* If waitMillis is -1 then the defaultGarbageCollectionWait is used which
|
||||
* defaults to 100 milliseconds.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public void collectProfiling() {
|
||||
collectProfiling(-1);
|
||||
}
|
||||
|
||||
public void collectProfiling(long waitMillis) {
|
||||
System.gc();
|
||||
try {
|
||||
if (waitMillis < 0) {
|
||||
waitMillis = defaultGarbageCollectionWait;
|
||||
}
|
||||
Thread.sleep(waitMillis);
|
||||
} catch (InterruptedException e) {
|
||||
// restore the interrupted status
|
||||
Thread.currentThread().interrupt();
|
||||
logger.log(WARNING, "Error while sleeping after System.gc() request.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto tune the query and enable profiling.
|
||||
*/
|
||||
@Override
|
||||
public boolean tuneQuery(SpiQuery<?> query) {
|
||||
return queryTuner.tuneQuery(query);
|
||||
}
|
||||
|
||||
}
|
||||
-122
@@ -1,122 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.ebean.bean.NodeUsageCollector;
|
||||
import io.ebean.bean.ObjectGraphNode;
|
||||
import io.ebean.bean.ObjectGraphOrigin;
|
||||
import io.ebean.config.AutoTuneConfig;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.autotune.ProfilingListener;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* Manages the collection of object graph usage profiling.
|
||||
*/
|
||||
public class ProfileManager implements ProfilingListener {
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
private final boolean queryTuningAddVersion;
|
||||
|
||||
/**
|
||||
* Converted from a 0-100 int to a double. Effectively a percentage rate at
|
||||
* which to collect profiling information.
|
||||
*/
|
||||
private final double profilingRate;
|
||||
|
||||
private final int profilingBase;
|
||||
|
||||
/**
|
||||
* Map of the usage and query statistics gathered.
|
||||
*/
|
||||
private final Map<String, ProfileOrigin> profileMap = new ConcurrentHashMap<>();
|
||||
|
||||
private final SpiEbeanServer server;
|
||||
|
||||
public ProfileManager(AutoTuneConfig config, SpiEbeanServer server) {
|
||||
this.server = server;
|
||||
this.profilingRate = config.getProfilingRate();
|
||||
this.profilingBase = config.getProfilingBase();
|
||||
this.queryTuningAddVersion = config.isQueryTuningAddVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProfileRequest(ObjectGraphNode origin, SpiQuery<?> query) {
|
||||
ProfileOrigin profileOrigin = profileMap.get(origin.origin().key());
|
||||
if (profileOrigin == null) {
|
||||
profileMap.put(origin.origin().key(), createProfileOrigin(origin, query));
|
||||
return true;
|
||||
} else {
|
||||
return profileOrigin.isProfile();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the profile origin noting the query detail currently being used.
|
||||
* <p>
|
||||
* For new profiling entries it is useful to compare the profiling against the current
|
||||
* query detail that is specified in the code (as the query might already be manually optimised).
|
||||
*/
|
||||
private ProfileOrigin createProfileOrigin(ObjectGraphNode origin, SpiQuery<?> query) {
|
||||
ProfileOrigin profileOrigin = new ProfileOrigin(origin.origin(), queryTuningAddVersion, profilingBase, profilingRate);
|
||||
// set the current query detail (fetch group) so that we can compare against profiling for new entries
|
||||
profileOrigin.setOriginalQuery(query.getDetail().asString());
|
||||
return profileOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather query execution statistics. This could either be the originating
|
||||
* query in which case the parentNode will be null, or a lazy loading query
|
||||
* resulting from traversal of the object graph.
|
||||
*/
|
||||
@Override
|
||||
public void collectQueryInfo(ObjectGraphNode node, long beans, long micros) {
|
||||
if (node != null) {
|
||||
ObjectGraphOrigin origin = node.origin();
|
||||
if (origin != null) {
|
||||
ProfileOrigin stats = getProfileOrigin(origin);
|
||||
stats.collectQueryInfo(node, beans, micros);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect usage statistics from a node in the object graph.
|
||||
* <p>
|
||||
* This is sent to use from a EntityBeanIntercept when the finalise method
|
||||
* is called on the bean.
|
||||
*/
|
||||
@Override
|
||||
public void collectNodeUsage(NodeUsageCollector.State usageCollector) {
|
||||
ProfileOrigin profileOrigin = getProfileOrigin(usageCollector.node().origin());
|
||||
profileOrigin.collectUsageInfo(usageCollector);
|
||||
}
|
||||
|
||||
private ProfileOrigin getProfileOrigin(ObjectGraphOrigin originQueryPoint) {
|
||||
lock.lock();
|
||||
try {
|
||||
return profileMap.computeIfAbsent(originQueryPoint.key(), k -> new ProfileOrigin(originQueryPoint, queryTuningAddVersion, profilingBase, profilingRate));
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect all the profiling information.
|
||||
*/
|
||||
public AutoTuneCollection profilingCollection(boolean reset) {
|
||||
AutoTuneCollection req = new AutoTuneCollection();
|
||||
for (ProfileOrigin origin : profileMap.values()) {
|
||||
BeanDescriptor<?> desc = server.descriptorById(origin.getOrigin().beanType());
|
||||
if (desc != null) {
|
||||
origin.profilingCollection(desc, req, reset);
|
||||
}
|
||||
}
|
||||
return req;
|
||||
}
|
||||
|
||||
}
|
||||
-176
@@ -1,176 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.ebean.bean.NodeUsageCollector;
|
||||
import io.ebean.bean.ObjectGraphNode;
|
||||
import io.ebean.bean.ObjectGraphOrigin;
|
||||
import io.ebean.text.PathProperties;
|
||||
import io.ebean.text.PathProperties.Props;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class ProfileOrigin {
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
private static final long RESET_COUNT = -1000000000L;
|
||||
|
||||
private final ObjectGraphOrigin origin;
|
||||
|
||||
private final boolean queryTuningAddVersion;
|
||||
|
||||
private final int profilingBase;
|
||||
|
||||
private final double profilingRate;
|
||||
|
||||
private final Map<String, ProfileOriginQuery> queryStatsMap = new ConcurrentHashMap<>();
|
||||
|
||||
private final Map<String, ProfileOriginNodeUsage> nodeUsageMap = new ConcurrentHashMap<>();
|
||||
|
||||
private final AtomicLong requestCount = new AtomicLong();
|
||||
|
||||
private final AtomicLong profileCount = new AtomicLong();
|
||||
|
||||
private String originalQuery;
|
||||
|
||||
public ProfileOrigin(ObjectGraphOrigin origin, boolean queryTuningAddVersion, int profilingBase, double profilingRate) {
|
||||
this.origin = origin;
|
||||
this.queryTuningAddVersion = queryTuningAddVersion;
|
||||
this.profilingBase = profilingBase;
|
||||
this.profilingRate = profilingRate;
|
||||
}
|
||||
|
||||
public String getOriginalQuery() {
|
||||
return originalQuery;
|
||||
}
|
||||
|
||||
public void setOriginalQuery(String originalQuery) {
|
||||
this.originalQuery = originalQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this query should be profiled based on a percentage rate.
|
||||
*/
|
||||
public boolean isProfile() {
|
||||
|
||||
long count = requestCount.incrementAndGet();
|
||||
if (count < profilingBase) {
|
||||
return true;
|
||||
}
|
||||
long hits = profileCount.get();
|
||||
if (profilingRate > (double) hits / count) {
|
||||
profileCount.incrementAndGet();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect profiling information with the option to reset the underlying profiling detail.
|
||||
*/
|
||||
public void profilingCollection(BeanDescriptor<?> rootDesc, AutoTuneCollection req, boolean reset) {
|
||||
lock.lock();
|
||||
try {
|
||||
if (nodeUsageMap.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
OrmQueryDetail detail = buildDetail(rootDesc);
|
||||
AutoTuneCollection.Entry entry = req.add(origin, detail, originalQuery);
|
||||
|
||||
Collection<ProfileOriginQuery> values = queryStatsMap.values();
|
||||
for (ProfileOriginQuery queryEntry : values) {
|
||||
entry.addQuery(queryEntry.createEntryQuery(reset));
|
||||
}
|
||||
if (reset) {
|
||||
nodeUsageMap.clear();
|
||||
if (requestCount.get() > RESET_COUNT) {
|
||||
requestCount.set(profilingBase);
|
||||
profileCount.set(0);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
OrmQueryDetail buildDetail(BeanDescriptor<?> rootDesc) {
|
||||
|
||||
PathProperties pathProps = new PathProperties();
|
||||
for (ProfileOriginNodeUsage statsNode : nodeUsageMap.values()) {
|
||||
statsNode.buildTunedFetch(pathProps, rootDesc, queryTuningAddVersion);
|
||||
}
|
||||
|
||||
OrmQueryDetail detail = new OrmQueryDetail();
|
||||
|
||||
for (Props props : pathProps.getPathProps()) {
|
||||
if (!props.isEmpty()) {
|
||||
detail.fetch(props.getPath(), props.getPropertiesAsString(), null);
|
||||
}
|
||||
}
|
||||
|
||||
detail.sortFetchPaths(rootDesc);
|
||||
return detail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the origin.
|
||||
*/
|
||||
public ObjectGraphOrigin getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect query execution summary statistics.
|
||||
* <p>
|
||||
* This can give us a quick overview into bad lazy loading areas etc.
|
||||
* </p>
|
||||
*/
|
||||
public void collectQueryInfo(ObjectGraphNode node, long beansLoaded, long micros) {
|
||||
|
||||
String key = node.path();
|
||||
if (key == null) {
|
||||
key = "";
|
||||
}
|
||||
|
||||
ProfileOriginQuery stats = queryStatsMap.get(key);
|
||||
if (stats == null) {
|
||||
// a race condition but we don't care
|
||||
stats = new ProfileOriginQuery(key);
|
||||
queryStatsMap.put(key, stats);
|
||||
}
|
||||
stats.add(beansLoaded, micros);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the usage information for from a instance for this node.
|
||||
*/
|
||||
public void collectUsageInfo(NodeUsageCollector.State profile) {
|
||||
if (!profile.isEmpty()) {
|
||||
getNodeStats(profile.node().path()).collectUsageInfo(profile);
|
||||
}
|
||||
}
|
||||
|
||||
private ProfileOriginNodeUsage getNodeStats(String path) {
|
||||
lock.lock();
|
||||
try {
|
||||
// handle null paths as using ConcurrentHashMap
|
||||
path = (path == null) ? "" : path;
|
||||
ProfileOriginNodeUsage nodeStats = nodeUsageMap.get(path);
|
||||
if (nodeStats == null) {
|
||||
nodeStats = new ProfileOriginNodeUsage(path);
|
||||
nodeUsageMap.put(path, nodeStats);
|
||||
}
|
||||
return nodeStats;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-128
@@ -1,128 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.avaje.applog.AppLog;
|
||||
import io.ebean.bean.NodeUsageCollector;
|
||||
import io.ebean.text.PathProperties;
|
||||
import io.ebean.util.SplitName;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssoc;
|
||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static java.lang.System.Logger.Level.WARNING;
|
||||
|
||||
/**
|
||||
* Collects usages statistics for a given node in the object graph.
|
||||
*/
|
||||
public class ProfileOriginNodeUsage {
|
||||
|
||||
private static final System.Logger logger = AppLog.getLogger(ProfileOriginNodeUsage.class);
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
private final String path;
|
||||
|
||||
private int profileCount;
|
||||
|
||||
private int profileUsedCount;
|
||||
|
||||
private boolean modified;
|
||||
|
||||
private final Set<String> aggregateUsed = new LinkedHashSet<>();
|
||||
|
||||
public ProfileOriginNodeUsage(String path) {
|
||||
// handle null paths as using ConcurrentHashMap
|
||||
this.path = "".equals(path) ? null : path;
|
||||
}
|
||||
|
||||
protected void buildTunedFetch(PathProperties pathProps, BeanDescriptor<?> rootDesc, boolean addVersionProperty) {
|
||||
lock.lock();
|
||||
try {
|
||||
BeanDescriptor<?> desc = rootDesc;
|
||||
if (path != null) {
|
||||
ElPropertyValue elGetValue = rootDesc.elGetValue(path);
|
||||
if (elGetValue == null) {
|
||||
logger.log(WARNING, "AutoTune: Can't find join for path[" + path + "] for " + rootDesc.name());
|
||||
return;
|
||||
} else {
|
||||
BeanProperty beanProperty = elGetValue.beanProperty();
|
||||
if (beanProperty instanceof BeanPropertyAssoc<?>) {
|
||||
desc = ((BeanPropertyAssoc<?>) beanProperty).targetDescriptor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BeanProperty toOneIdProperty = null;
|
||||
boolean addedToPath = false;
|
||||
|
||||
for (String propName : aggregateUsed) {
|
||||
BeanProperty beanProp = desc.findPropertyFromPath(propName);
|
||||
if (beanProp == null) {
|
||||
logger.log(WARNING, "AutoTune: Can't find property[" + propName + "] for " + desc.name());
|
||||
|
||||
} else {
|
||||
if (beanProp.isId()) {
|
||||
// remember and maybe add ToOne property to parent path
|
||||
toOneIdProperty = beanProp;
|
||||
} else if (beanProp instanceof BeanPropertyAssoc<?>) {
|
||||
// intentionally skip
|
||||
} else {
|
||||
//noinspection StatementWithEmptyBody
|
||||
if (beanProp.isLob() && !beanProp.isFetchEager()) {
|
||||
// AutoTune will not include Lob's marked FetchLazy
|
||||
// (which is the default for Lob's so typical).
|
||||
} else {
|
||||
addedToPath = true;
|
||||
pathProps.addToPath(path, beanProp.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((modified || addVersionProperty) && desc != null) {
|
||||
BeanProperty versionProp = desc.versionProperty();
|
||||
if (versionProp != null) {
|
||||
addedToPath = true;
|
||||
pathProps.addToPath(path, versionProp.name());
|
||||
}
|
||||
}
|
||||
|
||||
if (toOneIdProperty != null && !addedToPath) {
|
||||
// add ToOne property to parent path
|
||||
ElPropertyValue assocOne = rootDesc.elGetValue(path);
|
||||
pathProps.addToPath(SplitName.parent(path), assocOne.name());
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect usage from a node.
|
||||
*/
|
||||
protected void collectUsageInfo(NodeUsageCollector.State profile) {
|
||||
lock.lock();
|
||||
try {
|
||||
Set<String> used = profile.used();
|
||||
profileCount++;
|
||||
if (!used.isEmpty()) {
|
||||
profileUsedCount++;
|
||||
aggregateUsed.addAll(used);
|
||||
}
|
||||
if (profile.isModified()) {
|
||||
modified = true;
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "path[" + path + "] profileCount[" + profileCount + "] used[" + profileUsedCount + "] props" + aggregateUsed;
|
||||
}
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
|
||||
/**
|
||||
* Used to accumulate query execution statistics for paths relative to the origin query.
|
||||
*/
|
||||
public class ProfileOriginQuery implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1133958958072778811L;
|
||||
|
||||
private final String path;
|
||||
|
||||
private final LongAdder exeCount = new LongAdder();
|
||||
|
||||
private final LongAdder totalBeanLoaded = new LongAdder();
|
||||
|
||||
private final LongAdder totalMicros = new LongAdder();
|
||||
|
||||
public ProfileOriginQuery(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public void add(long beansLoaded, long micros) {
|
||||
exeCount.increment();
|
||||
totalBeanLoaded.add(beansLoaded);
|
||||
totalMicros.add(micros);
|
||||
}
|
||||
|
||||
public AutoTuneCollection.EntryQuery createEntryQuery(boolean reset) {
|
||||
|
||||
if (reset) {
|
||||
return new AutoTuneCollection.EntryQuery(path, exeCount.sumThenReset(), totalBeanLoaded.sumThenReset(), totalMicros.sumThenReset());
|
||||
|
||||
} else {
|
||||
return new AutoTuneCollection.EntryQuery(path, exeCount.sum(), totalBeanLoaded.sum(), totalMicros.sum());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-70
@@ -1,70 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.ebeaninternal.server.autotune.model.Autotune;
|
||||
import io.ebeaninternal.server.autotune.model.Origin;
|
||||
import io.ebeaninternal.server.autotune.model.ProfileDiff;
|
||||
import io.ebeaninternal.server.autotune.model.ProfileEmpty;
|
||||
import io.ebeaninternal.server.autotune.model.ProfileNew;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Sorts Autotune document by
|
||||
*/
|
||||
public class SortAutoTuneDocument {
|
||||
|
||||
|
||||
/**
|
||||
* Set the diff and new entries by bean type followed by key.
|
||||
*/
|
||||
public static void sort(Autotune document) {
|
||||
|
||||
ProfileDiff profileDiff = document.getProfileDiff();
|
||||
if (profileDiff != null) {
|
||||
profileDiff.getOrigin().sort(NAME_KEY_SORT);
|
||||
}
|
||||
ProfileNew profileNew = document.getProfileNew();
|
||||
if (profileNew != null) {
|
||||
profileNew.getOrigin().sort(NAME_KEY_SORT);
|
||||
}
|
||||
ProfileEmpty profileEmpty = document.getProfileEmpty();
|
||||
if (profileEmpty != null) {
|
||||
profileEmpty.getOrigin().sort(KEY_SORT);
|
||||
}
|
||||
List<Origin> origins = document.getOrigin();
|
||||
if (!origins.isEmpty()) {
|
||||
origins.sort(NAME_KEY_SORT);
|
||||
}
|
||||
}
|
||||
|
||||
private static final OriginNameKeySort NAME_KEY_SORT = new OriginNameKeySort();
|
||||
|
||||
private static final OriginKeySort KEY_SORT = new OriginKeySort();
|
||||
|
||||
/**
|
||||
* Comparator sort by bean type then key.
|
||||
*/
|
||||
private static class OriginNameKeySort implements Comparator<Origin> {
|
||||
|
||||
@Override
|
||||
public int compare(Origin o1, Origin o2) {
|
||||
int comp = o1.getBeanType().compareTo(o2.getBeanType());
|
||||
if (comp == 0) {
|
||||
comp = o1.getKey().compareTo(o2.getKey());
|
||||
}
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparator sort by bean type then key.
|
||||
*/
|
||||
private static class OriginKeySort implements Comparator<Origin> {
|
||||
|
||||
@Override
|
||||
public int compare(Origin o1, Origin o2) {
|
||||
return o1.getKey().compareTo(o2.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.autotune.model.Origin;
|
||||
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
|
||||
import io.ebeaninternal.server.querydefn.OrmQueryDetailParser;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Holds tuned query information. Is immutable so this represents the tuning at
|
||||
* a given point in time.
|
||||
*/
|
||||
public class TunedQueryInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 8661702592481810396L;
|
||||
|
||||
private final Origin origin;
|
||||
|
||||
private final OrmQueryDetail tunedDetail;
|
||||
|
||||
public TunedQueryInfo(Origin origin) {
|
||||
this.origin = origin;
|
||||
this.tunedDetail = new OrmQueryDetailParser(origin.getDetail()).parse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the origin entry (includes call stack and bean type).
|
||||
*/
|
||||
public Origin getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the tuned detail (for comparison with profiling information).
|
||||
*/
|
||||
public OrmQueryDetail getTunedDetail() {
|
||||
return tunedDetail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tune the query by replacing its OrmQueryDetail with a tuned one.
|
||||
*
|
||||
* @return true if the query was tuned, otherwise false.
|
||||
*/
|
||||
public boolean tuneQuery(SpiQuery<?> query) {
|
||||
if (tunedDetail == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean tuned;
|
||||
if (query.isDetailEmpty()) {
|
||||
tuned = true;
|
||||
// tune by 'replacement'
|
||||
query.setDetail(tunedDetail.copy());
|
||||
} else {
|
||||
// tune by 'addition'
|
||||
tuned = query.tuneFetchProperties(tunedDetail);
|
||||
}
|
||||
if (tuned) {
|
||||
query.setAutoTuned(true);
|
||||
}
|
||||
return tuned;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return tunedDetail.asString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import io.ebeaninternal.server.autotune.AutoTuneServiceProvider;
|
||||
import io.ebeaninternal.server.autotune.service.AutoTuneServiceFactory;
|
||||
|
||||
/**
|
||||
* Provider of AutoTuneServiceProvider
|
||||
*/
|
||||
module io.ebean.autotune {
|
||||
|
||||
provides AutoTuneServiceProvider with AutoTuneServiceFactory;
|
||||
|
||||
requires io.ebean.api;
|
||||
requires io.ebean.core;
|
||||
requires java.xml;
|
||||
requires java.xml.bind;
|
||||
}
|
||||
-1
@@ -1 +0,0 @@
|
||||
io.ebeaninternal.server.autotune.service.AutoTuneServiceFactory
|
||||
@@ -1,55 +0,0 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://ebean-orm.github.io/xml/ns/autotune"
|
||||
targetNamespace="http://ebean-orm.github.io/xml/ns/autotune" elementFormDefault="qualified">
|
||||
|
||||
|
||||
<!-- Root level type : profiling -->
|
||||
|
||||
<xsd:element name="autotune">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="origin" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element ref="profileDiff" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element ref="profileNew" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element ref="profileEmpty" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="origin">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="callStack" type="xsd:string" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="key" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="beanType" type="xsd:string"/>
|
||||
<xsd:attribute name="detail" type="xsd:string"/>
|
||||
<xsd:attribute name="original" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="profileDiff">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="origin" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="profileNew">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="origin" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="profileEmpty">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="origin" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
</xsd:schema>
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.ebeaninternal.server.autotune.model.Autotune;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class AutoTuneXmlReaderTest {
|
||||
|
||||
@Test
|
||||
public void read_file() {
|
||||
|
||||
File testFile = new File("src/test/resources/autotune/test-autotune.xml");
|
||||
|
||||
Autotune tuneInfo = AutoTuneXmlReader.read(testFile);
|
||||
assertThat(tuneInfo.getOrigin()).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void read_inputStream() {
|
||||
|
||||
InputStream is = getClass().getResourceAsStream("/autotune/test-autotune.xml");
|
||||
|
||||
Autotune tuneInfo = AutoTuneXmlReader.read(is);
|
||||
assertThat(tuneInfo.getOrigin()).isNotEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
-149
@@ -1,149 +0,0 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.ebean.bean.NodeUsageCollector;
|
||||
import io.ebean.bean.NodeUsageListener;
|
||||
import io.ebean.bean.ObjectGraphNode;
|
||||
import io.ebean.bean.ObjectGraphOrigin;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.tests.autofetch.BaseTestCase;
|
||||
import org.tests.model.basic.Order;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ProfileOriginTest extends BaseTestCase {
|
||||
|
||||
static class Noop implements NodeUsageListener {
|
||||
@Override
|
||||
public void collectNodeUsage(NodeUsageCollector.State state) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
private final NodeUsageListener listener = new Noop();
|
||||
|
||||
private final BeanDescriptor<Order> desc = getBeanDescriptor(Order.class);
|
||||
|
||||
@Test
|
||||
public void buildDetail() {
|
||||
|
||||
NodeUsageCollector c = node("customer");
|
||||
c.addUsed("id");
|
||||
c.addUsed("name");
|
||||
|
||||
ProfileOrigin po = new ProfileOrigin(null, false, 1, 1);
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
OrmQueryDetail detail = po.buildDetail(desc);
|
||||
|
||||
assertThat(detail.asString().trim()).isEqualTo("fetch customer (name)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildDetail_selectFetch() {
|
||||
|
||||
NodeUsageCollector c = node("customer");
|
||||
c.addUsed("id");
|
||||
c.addUsed("name");
|
||||
|
||||
ProfileOrigin po = new ProfileOrigin(null, false, 1, 1);
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
c = node(null);
|
||||
c.addUsed("orderDate");
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
OrmQueryDetail detail = po.buildDetail(desc);
|
||||
|
||||
assertThat(detail.asString()).isEqualTo("select (orderDate) fetch customer (name)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildDetail_expect_mergeFetchToSelect() {
|
||||
|
||||
NodeUsageCollector c = node("customer");
|
||||
c.addUsed("id");
|
||||
|
||||
ProfileOrigin po = new ProfileOrigin(null, false, 1, 1);
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
c = node(null);
|
||||
c.addUsed("orderDate");
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
OrmQueryDetail detail = po.buildDetail(desc);
|
||||
|
||||
assertThat(detail.asString().trim()).isEqualTo("select (orderDate,customer)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildDetail_expect_mergeFetchToParentFetch() {
|
||||
|
||||
ProfileOrigin po = new ProfileOrigin(null, false, 1, 1);
|
||||
|
||||
NodeUsageCollector c = node(null);
|
||||
c.addUsed("orderDate");
|
||||
c.addUsed("customer");
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
c = node("customer");
|
||||
c.addUsed("billingAddress");
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
c = node("customer.billingAddress");
|
||||
c.addUsed("id");
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
OrmQueryDetail detail = po.buildDetail(desc);
|
||||
|
||||
assertThat(detail.asString()).isEqualTo("select (orderDate) fetch customer (billingAddress)");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void buildDetail_expect_mergeMulit() {
|
||||
|
||||
ProfileOrigin po = new ProfileOrigin(null, false, 1, 1);
|
||||
|
||||
//fetch details (id,orderQty,shipQty,unitPrice)
|
||||
|
||||
NodeUsageCollector c = node(null);
|
||||
c.addUsed("customer");
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
c = node("customer");
|
||||
c.addUsed("id");
|
||||
c.addUsed("name");
|
||||
c.addUsed("note");
|
||||
c.addUsed("billingAddress");
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
//fetch details.product (id,name)
|
||||
c = node("customer.billingAddress");
|
||||
c.addUsed("id");
|
||||
c.addUsed("line1");
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
OrmQueryDetail detail = po.buildDetail(desc);
|
||||
assertThat(detail.asString()).isEqualTo("fetch customer (name,note) fetch customer.billingAddress (line1)");
|
||||
}
|
||||
|
||||
private NodeUsageCollector node(String path) {
|
||||
ObjectGraphNode node = new ObjectGraphNode((ObjectGraphOrigin)null, path);
|
||||
return new NodeUsageCollector(node, listener);
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void testQueries() {
|
||||
//
|
||||
// ResetBasicData.reset();
|
||||
//
|
||||
// //DB.createQuery(Order.class, "select (orderDate) fetch customer (billingAddress)").findList();
|
||||
//
|
||||
// // we prefer this first query other the second one
|
||||
// DB.createQuery(Order.class, "select (orderDate,customer)").findList();
|
||||
// DB.createQuery(Order.class, "select (orderDate) fetch customer (id)").findList();
|
||||
//
|
||||
// }
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package org.tests.autofetch;
|
||||
|
||||
import io.ebean.DB;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
|
||||
public class BaseTestCase {
|
||||
|
||||
protected SpiEbeanServer spiEbeanServer() {
|
||||
return (SpiEbeanServer) DB.getDefault();
|
||||
}
|
||||
|
||||
protected <T> BeanDescriptor<T> getBeanDescriptor(Class<T> cls) {
|
||||
return spiEbeanServer().descriptor(cls);
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package org.tests.autofetch;
|
||||
|
||||
//import io.ebean.Ebean;
|
||||
//import org.tests.model.basic.EBasicClob;
|
||||
|
||||
//import java.util.List;
|
||||
|
||||
public class MainAutoFetchExcludeLazyLobs {
|
||||
|
||||
// public static void main(String[] args) {
|
||||
//
|
||||
// EBasicClob a = new EBasicClob();
|
||||
// a.setName("name 1");
|
||||
// a.setTitle("a title");
|
||||
// a.setDescription("not that meaningful");
|
||||
//
|
||||
// Ebean.save(a);
|
||||
//
|
||||
// List<EBasicClob> list = Ebean.find(EBasicClob.class)
|
||||
// .setAutoTune(true)
|
||||
// .findList();
|
||||
//
|
||||
// for (EBasicClob bean : list) {
|
||||
// bean.getName();
|
||||
// // although we read the description
|
||||
// // autofetch will not include it later
|
||||
// bean.getDescription();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package org.tests.autofetch;
|
||||
|
||||
import io.ebean.DB;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.tests.model.basic.Order;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MainAutoQueryTune1 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
MainAutoQueryTune1 me = new MainAutoQueryTune1();
|
||||
me.tuneJoin();
|
||||
}
|
||||
|
||||
@Test
|
||||
void tuneJoin() {
|
||||
TestData.load();
|
||||
|
||||
List<Order> list = DB.find(Order.class)
|
||||
.setAutoTune(true)
|
||||
//.fetch("customer")
|
||||
.where()
|
||||
.eq("status", Order.Status.NEW)
|
||||
.eq("customer.name", "Rob")
|
||||
.order().asc("id")
|
||||
.findList();
|
||||
|
||||
for (Order order : list) {
|
||||
order.getId();
|
||||
order.getOrderDate();
|
||||
order.getCustomer().getName();
|
||||
order.getCustomer().getNote();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package org.tests.autofetch;
|
||||
|
||||
import io.ebean.DB;
|
||||
import org.tests.model.basic.Address;
|
||||
import org.tests.model.basic.Customer;
|
||||
import org.tests.model.basic.Order;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
public class TestData {
|
||||
|
||||
static void load() {
|
||||
if (DB.find(Order.class).findCount() > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var customer = new Customer("Rob");
|
||||
customer.setBillingAddress(new Address("l0", "city0"));
|
||||
DB.save(customer);
|
||||
|
||||
var order = new Order(customer);
|
||||
order.setOrderDate(LocalDate.now());
|
||||
DB.save(order);
|
||||
}
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
package org.tests.autofetch;
|
||||
|
||||
//import io.ebean.BaseTestCase;
|
||||
//import io.ebean.Ebean;
|
||||
//import io.ebean.EbeanServer;
|
||||
//import io.ebean.Query;
|
||||
//import io.ebean.bean.EntityBean;
|
||||
//import io.ebean.bean.EntityBeanIntercept;
|
||||
//import io.ebean.cache.ServerCacheManager;
|
||||
//import io.ebeaninternal.api.SpiQuery;
|
||||
//import io.ebeaninternal.server.autotune.model.Origin;
|
||||
//import io.ebeaninternal.server.autotune.service.TunedQueryInfo;
|
||||
//import io.ebeaninternal.server.querydefn.OrmQueryDetail;
|
||||
//import org.ebeantest.LoggedSqlCollector;
|
||||
//import org.junit.Assert;
|
||||
//import org.junit.Test;
|
||||
//import org.tests.model.basic.Order;
|
||||
//import org.tests.model.basic.ResetBasicData;
|
||||
//
|
||||
//import java.util.List;
|
||||
//import java.util.Set;
|
||||
|
||||
public class TunedQueryInfoTest extends BaseTestCase {
|
||||
|
||||
// private void init() {
|
||||
//
|
||||
// ResetBasicData.reset();
|
||||
//
|
||||
// ServerCacheManager serverCacheManager = Ebean.getServer(null).getServerCacheManager();
|
||||
// serverCacheManager.clearAll();
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void withSelectEmpty() {
|
||||
//
|
||||
// init();
|
||||
//
|
||||
// OrmQueryDetail tunedDetail = new OrmQueryDetail();
|
||||
// tunedDetail.select("");
|
||||
//
|
||||
// TunedQueryInfo tunedInfo = createTunedQueryInfo(tunedDetail);
|
||||
//
|
||||
// Query<Order> query = server.find(Order.class).setId(1);
|
||||
//
|
||||
// tunedInfo.tuneQuery((SpiQuery<?>) query);
|
||||
//
|
||||
// Order order = query.findOne();
|
||||
// EntityBean eb = (EntityBean) order;
|
||||
// EntityBeanIntercept ebi = eb._ebean_getIntercept();
|
||||
//
|
||||
// Assert.assertTrue(ebi.isFullyLoadedBean());
|
||||
//
|
||||
// Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
|
||||
// Assert.assertNull(loadedPropertyNames);
|
||||
//
|
||||
// // invoke lazy loading
|
||||
// order.getCustomer();
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void withSelectSomethingThatDoesNotExist() {
|
||||
//
|
||||
// init();
|
||||
//
|
||||
// OrmQueryDetail tunedDetail = new OrmQueryDetail();
|
||||
// tunedDetail.select("somethingThatDoesNotExist");
|
||||
//
|
||||
// TunedQueryInfo tunedInfo = createTunedQueryInfo(tunedDetail);
|
||||
//
|
||||
// Query<Order> query = server.find(Order.class).setId(1);
|
||||
//
|
||||
// tunedInfo.tuneQuery((SpiQuery<?>) query);
|
||||
//
|
||||
// LoggedSqlCollector.start();
|
||||
//
|
||||
// Order order = query.findOne();
|
||||
// EntityBean eb = (EntityBean) order;
|
||||
// EntityBeanIntercept ebi = eb._ebean_getIntercept();
|
||||
//
|
||||
// Assert.assertFalse(ebi.isFullyLoadedBean());
|
||||
//
|
||||
// // id and any ToMany relationships
|
||||
// Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
|
||||
// Assert.assertNotNull(loadedPropertyNames);
|
||||
//
|
||||
// // invoke lazy loading
|
||||
// order.getCustomer();
|
||||
//
|
||||
// List<String> loggedSql = LoggedSqlCollector.stop();
|
||||
// Assert.assertEquals(2, loggedSql.size());
|
||||
//
|
||||
// Assert.assertTrue(trimSql(loggedSql.get(0), 1).contains("select t0.id, t0.id from o_order t0 where t0.id = ?"));
|
||||
// Assert.assertTrue(trimSql(loggedSql.get(1), 1).contains("select t0.id, t0.status,"));
|
||||
// }
|
||||
//
|
||||
// private TunedQueryInfo createTunedQueryInfo(OrmQueryDetail tunedDetail) {
|
||||
// Origin origin = new Origin();
|
||||
// origin.setDetail(tunedDetail.asString());
|
||||
// return new TunedQueryInfo(origin);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void withSelectSomeIncludeLazyLoaded() {
|
||||
//
|
||||
// init();
|
||||
//
|
||||
// OrmQueryDetail tunedDetail = new OrmQueryDetail();
|
||||
// tunedDetail.select("status, customer");
|
||||
//
|
||||
// TunedQueryInfo tunedInfo = createTunedQueryInfo(tunedDetail);
|
||||
//
|
||||
// Query<Order> query = server.find(Order.class).setId(1);
|
||||
//
|
||||
// tunedInfo.tuneQuery((SpiQuery<?>) query);
|
||||
//
|
||||
// LoggedSqlCollector.start();
|
||||
//
|
||||
// Order order = query.findOne();
|
||||
// EntityBean eb = (EntityBean) order;
|
||||
// EntityBeanIntercept ebi = eb._ebean_getIntercept();
|
||||
//
|
||||
// Assert.assertFalse(ebi.isFullyLoadedBean());
|
||||
//
|
||||
// Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
|
||||
// Assert.assertNotNull(loadedPropertyNames);
|
||||
//
|
||||
// Assert.assertTrue(loadedPropertyNames.contains("status"));
|
||||
// Assert.assertTrue(loadedPropertyNames.contains("customer"));
|
||||
//
|
||||
// // no lazy loading expected here
|
||||
// order.getCustomer();
|
||||
//
|
||||
// List<String> loggedSql = LoggedSqlCollector.stop();
|
||||
// Assert.assertEquals(1, loggedSql.size());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void withSelectSome() {
|
||||
//
|
||||
// init();
|
||||
//
|
||||
// OrmQueryDetail tunedDetail = new OrmQueryDetail();
|
||||
// tunedDetail.select("status");
|
||||
//
|
||||
// TunedQueryInfo tunedInfo = createTunedQueryInfo(tunedDetail);
|
||||
//
|
||||
// Query<Order> query = server.find(Order.class).setId(1);
|
||||
//
|
||||
// tunedInfo.tuneQuery((SpiQuery<?>) query);
|
||||
//
|
||||
// LoggedSqlCollector.start();
|
||||
//
|
||||
// Order order = query.findOne();
|
||||
// EntityBean eb = (EntityBean) order;
|
||||
// EntityBeanIntercept ebi = eb._ebean_getIntercept();
|
||||
//
|
||||
// Assert.assertFalse(ebi.isFullyLoadedBean());
|
||||
//
|
||||
// Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
|
||||
// Assert.assertNotNull(loadedPropertyNames);
|
||||
//
|
||||
// Assert.assertTrue(loadedPropertyNames.contains("status"));
|
||||
// Assert.assertFalse(loadedPropertyNames.contains("customer"));
|
||||
//
|
||||
// // no lazy loading expected here
|
||||
// order.getCustomer();
|
||||
//
|
||||
// List<String> loggedSql = LoggedSqlCollector.stop();
|
||||
// Assert.assertEquals(2, loggedSql.size());
|
||||
// }
|
||||
|
||||
}
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
package org.tests.autofetch;
|
||||
|
||||
//import io.ebean.BaseTestCase;
|
||||
//import io.ebean.Ebean;
|
||||
//import io.ebean.EbeanServer;
|
||||
//import io.ebean.Query;
|
||||
//import io.ebean.bean.EntityBean;
|
||||
//import io.ebean.bean.EntityBeanIntercept;
|
||||
//import org.ebeantest.LoggedSqlCollector;
|
||||
//import org.junit.Assert;
|
||||
//import org.junit.Test;
|
||||
//import org.tests.model.basic.Address;
|
||||
//import org.tests.model.basic.Customer;
|
||||
//import org.tests.model.basic.ResetBasicData;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class TunedQueryWithNullFetchedBeanTest extends BaseTestCase {
|
||||
|
||||
// EbeanServer server = Ebean.getServer(null);
|
||||
//
|
||||
// @Test
|
||||
// public void withFetchOfNullBeanJoin() {
|
||||
//
|
||||
// ResetBasicData.reset();
|
||||
//
|
||||
// Customer newCustomer = new Customer();
|
||||
// newCustomer.setName("TestFetchBillingAddress");
|
||||
// server.save(newCustomer);
|
||||
//
|
||||
// Query<Customer> query = server.find(Customer.class)
|
||||
// .setId(newCustomer.getId())
|
||||
// .fetch("billingAddress", "id");
|
||||
//
|
||||
// LoggedSqlCollector.start();
|
||||
//
|
||||
// Customer customer = query.findOne();
|
||||
// EntityBean eb = (EntityBean) customer;
|
||||
// EntityBeanIntercept ebi = eb._ebean_getIntercept();
|
||||
//
|
||||
// Assert.assertTrue(ebi.isFullyLoadedBean());
|
||||
//
|
||||
// // find the internal property index for "billingAddress"
|
||||
// String[] propNames = eb._ebean_getPropertyNames();
|
||||
// int pos = 0;
|
||||
// for (int i = 0; i < propNames.length; i++) {
|
||||
// if (propNames[i].equals("billingAddress")) {
|
||||
// pos = i;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // The billing address is loaded (but value null)
|
||||
// Assert.assertTrue(ebi.isLoadedProperty(pos));
|
||||
//
|
||||
// Set<String> loadedPropertyNames = ebi.getLoadedPropertyNames();
|
||||
// Assert.assertNull(loadedPropertyNames);
|
||||
//
|
||||
// // no lazy loading expected here, value is null
|
||||
// Address billingAddress = customer.getBillingAddress();
|
||||
// Assert.assertNull(billingAddress);
|
||||
//
|
||||
// // assert only one query executed
|
||||
// List<String> loggedSql = LoggedSqlCollector.stop();
|
||||
// Assert.assertEquals(1, loggedSql.size());
|
||||
//
|
||||
// Ebean.delete(newCustomer);
|
||||
// }
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package org.tests.model.basic;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "o_address")
|
||||
public class Address extends BaseModel {
|
||||
|
||||
String line1;
|
||||
String line2;
|
||||
String city;
|
||||
|
||||
public Address(String line1, String city) {
|
||||
this.line1 = line1;
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getLine1() {
|
||||
return line1;
|
||||
}
|
||||
|
||||
public void setLine1(String line1) {
|
||||
this.line1 = line1;
|
||||
}
|
||||
|
||||
public String getLine2() {
|
||||
return line2;
|
||||
}
|
||||
|
||||
public void setLine2(String line2) {
|
||||
this.line2 = line2;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package org.tests.model.basic;
|
||||
|
||||
import io.ebean.Model;
|
||||
import io.ebean.annotation.WhenCreated;
|
||||
import io.ebean.annotation.WhenModified;
|
||||
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.Version;
|
||||
import java.time.Instant;
|
||||
|
||||
@MappedSuperclass
|
||||
public class BaseModel extends Model {
|
||||
|
||||
@Id
|
||||
long id;
|
||||
|
||||
@WhenCreated
|
||||
Instant whenCreated;
|
||||
|
||||
@WhenModified
|
||||
Instant whenModified;
|
||||
|
||||
@Version
|
||||
long version;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Instant getWhenCreated() {
|
||||
return whenCreated;
|
||||
}
|
||||
|
||||
public void setWhenCreated(Instant whenCreated) {
|
||||
this.whenCreated = whenCreated;
|
||||
}
|
||||
|
||||
public Instant getWhenModified() {
|
||||
return whenModified;
|
||||
}
|
||||
|
||||
public void setWhenModified(Instant whenModified) {
|
||||
this.whenModified = whenModified;
|
||||
}
|
||||
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(long version) {
|
||||
this.version = version;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package org.tests.model.basic;
|
||||
|
||||
import io.ebean.annotation.NotNull;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "o_customer")
|
||||
public class Customer extends BaseModel {
|
||||
|
||||
@NotNull String name;
|
||||
|
||||
String note;
|
||||
|
||||
@ManyToOne(cascade = CascadeType.PERSIST)
|
||||
Address billingAddress;
|
||||
|
||||
public Customer(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getNote() {
|
||||
return note;
|
||||
}
|
||||
|
||||
public void setNote(String note) {
|
||||
this.note = note;
|
||||
}
|
||||
|
||||
public Address getBillingAddress() {
|
||||
return billingAddress;
|
||||
}
|
||||
|
||||
public void setBillingAddress(Address billingAddress) {
|
||||
this.billingAddress = billingAddress;
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package org.tests.model.basic;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Entity
|
||||
@Table(name = "o_order")
|
||||
public class Order extends BaseModel {
|
||||
|
||||
public enum Status {
|
||||
NEW,
|
||||
APPROVED,
|
||||
SHIPPED,
|
||||
COMPLETE
|
||||
}
|
||||
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
Status status = Status.NEW;
|
||||
|
||||
LocalDate orderDate;
|
||||
|
||||
@ManyToOne(cascade = CascadeType.PERSIST)
|
||||
final Customer customer;
|
||||
|
||||
public Order(Customer customer) {
|
||||
this.customer = customer;
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public LocalDate getOrderDate() {
|
||||
return orderDate;
|
||||
}
|
||||
|
||||
public void setOrderDate(LocalDate orderDate) {
|
||||
this.orderDate = orderDate;
|
||||
}
|
||||
|
||||
public Customer getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
ebean.ddl.generate=true
|
||||
ebean.ddl.run=true
|
||||
datasource.default=h2
|
||||
|
||||
datasource.h2.username=sa
|
||||
datasource.h2.password=
|
||||
datasource.h2.url=jdbc:h2:mem:h2AutoTune
|
||||
|
||||
datasource.pg.username=sa
|
||||
datasource.pg.password=
|
||||
datasource.pg.url=jdbc:h2:mem:h2AutoTune
|
||||
|
||||
ebean.autoTune.profiling=true
|
||||
ebean.maxCallStack=10
|
||||
|
||||
ebean.autoTune.queryTuning=true
|
||||
ebean.autoTune.queryTuningFile=autotune/my-autotune.xml
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<autotune xmlns="http://ebean-orm.github.io/xml/ns/autotune">
|
||||
<origin key="BmouL7.Bn_jgL.BNY1QD" beanType="org.tests.model.basic.Order" detail="select (orderDate) fetch customer (name,note)" original="">
|
||||
<callStack>org.tests.autofetch.MainAutoQueryTune1.tuneJoin(MainAutoQueryTune1.java:27)
|
||||
org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
|
||||
org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
|
||||
org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
|
||||
org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
|
||||
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
|
||||
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
|
||||
org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
|
||||
org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
|
||||
org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)</callStack>
|
||||
</origin>
|
||||
</autotune>
|
||||
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<autotune xmlns="http://ebean-orm.github.io/xml/ns/autotune">
|
||||
<origin key="DWeHD4.B0dP9Z.DKG8lq" beanType="org.tests.model.basic.Order" detail="select (status,shipDate) " original="select (status, orderDate, shipDate) ">
|
||||
<callStack>org.tests.query.autotune.TestAutoTuneProfiling.findById(TestAutoTuneProfiling.java:62)
|
||||
org.tests.query.autotune.TestAutoTuneProfiling.useOrderDate(TestAutoTuneProfiling.java:66)
|
||||
org.tests.query.autotune.TestAutoTuneProfiling.execute(TestAutoTuneProfiling.java:52)
|
||||
org.tests.query.autotune.TestAutoTuneProfiling.test(TestAutoTuneProfiling.java:25)
|
||||
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
</callStack>
|
||||
</origin>
|
||||
<origin key="DWeHD4.BZfmOY.Yd8Hf" beanType="org.tests.model.basic.Order" detail=" fetch customer (id) fetch details (orderQty,shipQty,unitPrice) fetch details.product (id,name) " original="select (id) fetch details ">
|
||||
<callStack>org.tests.query.autotune.TestAutoTuneProfiling.useLotUntuned(TestAutoTuneProfiling.java:95)
|
||||
org.tests.query.autotune.TestAutoTuneProfiling.execute(TestAutoTuneProfiling.java:55)
|
||||
org.tests.query.autotune.TestAutoTuneProfiling.test(TestAutoTuneProfiling.java:25)
|
||||
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
|
||||
</callStack>
|
||||
</origin>
|
||||
<origin key="DWeHD4.l6b4M.BYWlSr" beanType="org.tests.model.basic.Order" detail=" fetch customer (name) " original="">
|
||||
<callStack>org.tests.model.basic.Order._ebean_get_customer(Order.java:6)
|
||||
org.tests.model.basic.Order.getCustomer(Order.java:228)
|
||||
org.tests.query.autotune.TestAutoTuneProfiling.useOrderDateCustomerName(TestAutoTuneProfiling.java:74)
|
||||
org.tests.query.autotune.TestAutoTuneProfiling.execute(TestAutoTuneProfiling.java:53)
|
||||
org.tests.query.autotune.TestAutoTuneProfiling.test(TestAutoTuneProfiling.java:25)
|
||||
</callStack>
|
||||
</origin>
|
||||
<origin key="DVf2Cn.StLsZ.BCru36" beanType="org.tests.model.basic.OrderDetail" detail=" fetch product (name) " original="">
|
||||
<callStack>org.tests.model.basic.OrderDetail._ebean_get_product(OrderDetail.java:6)
|
||||
org.tests.model.basic.OrderDetail.getProduct(OrderDetail.java:150)
|
||||
org.tests.query.autotune.TestAutoTuneProfiling.useLotUntuned(TestAutoTuneProfiling.java:96)
|
||||
org.tests.query.autotune.TestAutoTuneProfiling.execute(TestAutoTuneProfiling.java:55)
|
||||
org.tests.query.autotune.TestAutoTuneProfiling.test(TestAutoTuneProfiling.java:32)
|
||||
</callStack>
|
||||
</origin>
|
||||
</autotune>
|
||||
@@ -1,22 +0,0 @@
|
||||
<configuration scan="true" scanPeriod="10 seconds">
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>TRACE</level>
|
||||
</filter>
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
|
||||
<logger name="io.ebeaninternal" level="DEBUG"/>
|
||||
<logger name="io.ebean.docker" level="TRACE"/>
|
||||
<!-- <logger name="io.ebean.DDL" level="DEBUG"/>-->
|
||||
<logger name="io.ebean.SQL" level="TRACE"/>
|
||||
<!-- <logger name="io.ebean.TXN" level="TRACE"/>-->
|
||||
<logger name="io.ebean.SUM" level="TRACE"/>
|
||||
|
||||
</configuration>
|
||||
+30
-30
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean bom</name>
|
||||
@@ -89,112 +89,112 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-joda-time</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.18.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-jsonnode</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.18.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-mapper</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.18.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-xml</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.18.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-autotune</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.18.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>querybean-generator</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>kotlin-querybean-generator</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgis</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-redis</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-spring-txn</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- platforms -->
|
||||
@@ -202,67 +202,67 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-clickhouse</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-db2</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-h2</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-hana</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-mariadb</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-mysql</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-nuodb</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-oracle</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgres</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-sqlite</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-sqlserver</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
@@ -16,7 +16,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
+23
-9
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core</artifactId>
|
||||
@@ -22,7 +22,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -46,13 +46,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-api</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.18.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -81,12 +81,28 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- JAVAX-DEPENDENCY-START -->
|
||||
<dependency>
|
||||
<groupId>javax.transaction</groupId>
|
||||
<artifactId>javax.transaction-api</artifactId>
|
||||
<version>1.3</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- JAVAX-DEPENDENCY-END -->
|
||||
<!-- JAKARTA-DEPENDENCY-START ___
|
||||
<dependency>
|
||||
<groupId>jakarta.transaction</groupId>
|
||||
<artifactId>jakarta.transaction-api</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.enterprise</groupId>
|
||||
<artifactId>jakarta.enterprise.cdi-api</artifactId>
|
||||
<version>4.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
____ JAKARTA-DEPENDENCY-END -->
|
||||
|
||||
<!-- validation annotations Size etc -->
|
||||
<dependency>
|
||||
@@ -143,21 +159,21 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>13.17.3</version>
|
||||
<version>13.22.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -201,7 +217,6 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M4</version>
|
||||
<configuration>
|
||||
<useSystemClassLoader>false</useSystemClassLoader>
|
||||
<trimStackTrace>false</trimStackTrace>
|
||||
@@ -229,7 +244,6 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<configuration>
|
||||
<doctitle>Ebean 12</doctitle>
|
||||
<overview>src/main/java/io/ebean/overview.html</overview>
|
||||
|
||||
@@ -40,14 +40,14 @@ public final class BeanCacheResult<T> {
|
||||
/**
|
||||
* Return the natural key or id value.
|
||||
*/
|
||||
public Object getKey() {
|
||||
public Object key() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bean.
|
||||
*/
|
||||
public T getBean() {
|
||||
public T bean() {
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
package io.ebeaninternal.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper of the list of Id's.
|
||||
*/
|
||||
public class BeanIdList {
|
||||
|
||||
private final List<Object> idList;
|
||||
|
||||
private boolean hasMore;
|
||||
|
||||
public BeanIdList(List<Object> idList) {
|
||||
this.idList = idList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an Id to the list.
|
||||
*/
|
||||
public void add(Object id) {
|
||||
idList.add(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of Id's.
|
||||
*/
|
||||
public List<Object> getIdList() {
|
||||
return idList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if max rows was hit and there is more rows to fetch.
|
||||
*/
|
||||
public boolean isHasMore() {
|
||||
return hasMore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true when max rows is hit and there are more rows to fetch.
|
||||
*/
|
||||
public void setHasMore(boolean hasMore) {
|
||||
this.hasMore = hasMore;
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user