mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
154
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 | ||
|
|
63a23904ac | ||
|
|
1807fc201e |
@@ -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.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-clickhouse</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-db2</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-hana</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mariadb</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mysql</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-nuodb</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-oracle</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlite</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<name>ebean (all platforms)</name>
|
||||
@@ -16,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -40,7 +41,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-mapper</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -59,13 +60,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-all</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>composites</artifactId>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean api</name>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package io.ebean;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
/**
|
||||
* Thrown when a foreign key constraint is enforced or a field is too large.
|
||||
* Thrown when a foreign key constraint is enforced.
|
||||
*/
|
||||
public class DataIntegrityException extends PersistenceException {
|
||||
private static final long serialVersionUID = -6740171949170180970L;
|
||||
@@ -14,11 +14,4 @@ public class DataIntegrityException extends PersistenceException {
|
||||
public DataIntegrityException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create with message only.
|
||||
*/
|
||||
public DataIntegrityException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -56,7 +56,7 @@ public interface ExpressionList<T> {
|
||||
/**
|
||||
* Deprecated migrate to {@link #orderBy(String)}
|
||||
*/
|
||||
@Deprecated(since = "13.19")
|
||||
@Deprecated(since = "13.19", forRemoval = true)
|
||||
default ExpressionList<T> order(String orderByClause) {
|
||||
return orderBy(orderByClause);
|
||||
}
|
||||
@@ -74,7 +74,7 @@ public interface ExpressionList<T> {
|
||||
/**
|
||||
* Deprecated migrate to orderBy().
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated(forRemoval = true)
|
||||
default OrderBy<T> order() {
|
||||
return orderBy();
|
||||
}
|
||||
@@ -508,6 +508,8 @@ public interface ExpressionList<T> {
|
||||
ExpressionList<T> filterMany(String manyProperty);
|
||||
|
||||
/**
|
||||
* Deprecated for removal - migrate to filterManyRaw()
|
||||
* <p>
|
||||
* Add filter expressions to the many property.
|
||||
*
|
||||
* <pre>{@code
|
||||
@@ -524,8 +526,29 @@ public interface ExpressionList<T> {
|
||||
* @param expressions Filter expressions with and, or and ? or ?1 type bind parameters
|
||||
* @param params Bind parameters used in the expressions
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
ExpressionList<T> filterMany(String manyProperty, String expressions, Object... params);
|
||||
|
||||
/**
|
||||
* Add filter expressions for the many path. The expressions can include SQL functions if
|
||||
* desired and the property names are translated to column names.
|
||||
* <p>
|
||||
* The expressions can contain placeholders for bind values using <code>?</code> or <code>?1</code> style.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* new QCustomer()
|
||||
* .name.startsWith("Postgres")
|
||||
* .contacts.filterManyRaw("status = ? and firstName like ?", Contact.Status.NEW, "Rob%")
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param rawExpressions The raw expressions which can include ? and ?1 style bind parameter placeholders
|
||||
* @param params The parameter values to bind
|
||||
*/
|
||||
ExpressionList<T> filterManyRaw(String manyProperty, String rawExpressions, Object... params);
|
||||
|
||||
/**
|
||||
* Specify specific properties to fetch on the main/root bean (aka partial
|
||||
* object).
|
||||
@@ -1131,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.
|
||||
*
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -1374,7 +1398,7 @@ public interface Query<T> extends CancelableQuery {
|
||||
/**
|
||||
* Deprecated migrate to orderBy().
|
||||
*/
|
||||
@Deprecated(since = "13.19")
|
||||
@Deprecated(since = "13.19", forRemoval = true)
|
||||
default Query<T> order(String orderByClause) {
|
||||
return orderBy(orderByClause);
|
||||
}
|
||||
@@ -1393,7 +1417,7 @@ public interface Query<T> extends CancelableQuery {
|
||||
/**
|
||||
* Deprecated migrate to orderBy().
|
||||
*/
|
||||
@Deprecated(since = "13.19")
|
||||
@Deprecated(since = "13.19", forRemoval = true)
|
||||
default OrderBy<T> order() {
|
||||
return orderBy();
|
||||
}
|
||||
@@ -1406,7 +1430,7 @@ public interface Query<T> extends CancelableQuery {
|
||||
/**
|
||||
* Deprecated migrate to setOrderBy().
|
||||
*/
|
||||
@Deprecated(since = "13.19")
|
||||
@Deprecated(since = "13.19", forRemoval = true)
|
||||
default Query<T> setOrder(OrderBy<T> orderBy) {
|
||||
return setOrderBy(orderBy);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -540,7 +540,6 @@ public class DatabaseConfig {
|
||||
|
||||
private String dumpMetricsOptions;
|
||||
|
||||
private LengthCheck lengthCheck = LengthCheck.OFF;
|
||||
private Function<String, String> metricNaming = MetricNamingMatch.INSTANCE;
|
||||
|
||||
/**
|
||||
@@ -2377,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;
|
||||
}
|
||||
@@ -2920,7 +2919,6 @@ public class DatabaseConfig {
|
||||
jdbcFetchSizeFindEach = p.getInt("jdbcFetchSizeFindEach", jdbcFetchSizeFindEach);
|
||||
jdbcFetchSizeFindList = p.getInt("jdbcFetchSizeFindList", jdbcFetchSizeFindList);
|
||||
databasePlatformName = p.get("databasePlatformName", databasePlatformName);
|
||||
lengthCheck = p.getEnum(LengthCheck.class, "lengthCheck", lengthCheck);
|
||||
|
||||
uuidVersion = p.getEnum(UuidVersion.class, "uuidVersion", uuidVersion);
|
||||
uuidStateFile = p.get("uuidStateFile", uuidStateFile);
|
||||
@@ -3391,7 +3389,7 @@ public class DatabaseConfig {
|
||||
/**
|
||||
* Deprecated - migrate to isLoadModuleInfo().
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated(forRemoval = true)
|
||||
public boolean isAutoLoadModuleInfo() {
|
||||
return loadModuleInfo;
|
||||
}
|
||||
@@ -3421,20 +3419,6 @@ public class DatabaseConfig {
|
||||
this.metricNaming = metricNaming;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length check mode.
|
||||
*/
|
||||
public LengthCheck getLengthCheck() {
|
||||
return lengthCheck;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the length check mode.
|
||||
*/
|
||||
public void setLengthCheck(LengthCheck lengthCheck) {
|
||||
this.lengthCheck = lengthCheck;
|
||||
}
|
||||
|
||||
public enum UuidVersion {
|
||||
VERSION4,
|
||||
VERSION1,
|
||||
|
||||
@@ -135,12 +135,12 @@ 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]));
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package io.ebean.config;
|
||||
|
||||
/**
|
||||
* Defines the length-check mode.
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*/
|
||||
public enum LengthCheck {
|
||||
/**
|
||||
* By default, length checking is off. This means, strings/jsons and files are passed to the DB and the DB might or might not check the length.
|
||||
* The DB has to check the data length. Note this is not possible for certain datatypes (e.g. clob without size)
|
||||
*/
|
||||
OFF,
|
||||
/**
|
||||
* When enabling length check, ebean validates strings/json strings and files before saving them to DB.
|
||||
*/
|
||||
ON,
|
||||
/**
|
||||
* Same as "ON", but take the UTF8-bytelength for validation. This may be useful, if you have an UTF8 based charset (default for DB2)
|
||||
*/
|
||||
UTF8
|
||||
}
|
||||
@@ -117,12 +117,12 @@ public final class TableName {
|
||||
// Add schema
|
||||
if (schema != null) {
|
||||
if (buffer.length() > 0) {
|
||||
buffer.append(".");
|
||||
buffer.append('.');
|
||||
}
|
||||
buffer.append(schema);
|
||||
}
|
||||
if (buffer.length() > 0) {
|
||||
buffer.append(".");
|
||||
buffer.append('.');
|
||||
}
|
||||
return buffer.append(name).toString();
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ public class BasicSqlLimitOffset implements BasicSqlLimiter {
|
||||
sb.append(dbSql);
|
||||
|
||||
if (maxRows > 0) {
|
||||
sb.append(" ").append(LIMIT);
|
||||
sb.append(" ").append(maxRows);
|
||||
sb.append(' ').append(LIMIT);
|
||||
sb.append(' ').append(maxRows);
|
||||
}
|
||||
if (firstRow > 0) {
|
||||
sb.append(" ").append(OFFSET).append(" ");
|
||||
sb.append(' ').append(OFFSET).append(' ');
|
||||
sb.append(firstRow);
|
||||
}
|
||||
return sb.toString();
|
||||
|
||||
@@ -118,28 +118,28 @@ final class MetricsAsJson implements ServerMetricsAsJson {
|
||||
|
||||
private void objStart() throws IOException {
|
||||
objKeyCounter = 0;
|
||||
writer.append("{");
|
||||
writer.append('{');
|
||||
}
|
||||
|
||||
private void objEnd() throws IOException {
|
||||
writer.append("}");
|
||||
writer.append('}');
|
||||
}
|
||||
|
||||
private void listStart() throws IOException {
|
||||
listCounter = 0;
|
||||
writer.append("[");
|
||||
writer.append('[');
|
||||
writer.append(newLine);
|
||||
}
|
||||
|
||||
private void listEnd() throws IOException {
|
||||
writer.append("]");
|
||||
writer.append(']');
|
||||
}
|
||||
|
||||
private void key(String key) throws IOException {
|
||||
if (objKeyCounter++ > 0) {
|
||||
writer.append(", ");
|
||||
}
|
||||
writer.append("\"").append(key).append("\":");
|
||||
writer.append('"').append(key).append("\":");
|
||||
}
|
||||
|
||||
private void val(long count) throws IOException {
|
||||
@@ -147,12 +147,12 @@ final class MetricsAsJson implements ServerMetricsAsJson {
|
||||
}
|
||||
|
||||
private void val(String val) throws IOException {
|
||||
writer.append("\"").append(val).append("\"");
|
||||
writer.append('"').append(val).append('"');
|
||||
}
|
||||
|
||||
private void metricStart(MetaMetric metric) throws IOException {
|
||||
if (listCounter++ > 0) {
|
||||
writer.append(",").append(newLine);
|
||||
writer.append(',').append(newLine);
|
||||
}
|
||||
objStart();
|
||||
key("name");
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
+25
-25
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean bom</name>
|
||||
@@ -89,25 +89,25 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -125,13 +125,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-mapper</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -155,46 +155,46 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>querybean-generator</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>kotlin-querybean-generator</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgis</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-redis</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-spring-txn</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- platforms -->
|
||||
@@ -202,67 +202,67 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-clickhouse</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-db2</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-h2</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-hana</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-mariadb</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-mysql</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-nuodb</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-oracle</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgres</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-sqlite</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-sqlserver</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -174,9 +174,4 @@ public interface DataBinder {
|
||||
*/
|
||||
String popJson();
|
||||
|
||||
/**
|
||||
* Returns the last bound object (e.g. for BindValidation). Note for InputStreams you'll get an InputStreamInfo.
|
||||
*/
|
||||
Object popLastObject();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package io.ebean.core.type;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Helper to transports length info of DataBind.setBinaryStream(stream, length) to BindValidation
|
||||
*
|
||||
* @author Roland Praml, FOCONIS AG
|
||||
*/
|
||||
public final class InputStreamInfo {
|
||||
|
||||
private final InputStream stream;
|
||||
private final long length;
|
||||
|
||||
public InputStreamInfo(InputStream stream, long length) {
|
||||
this.stream = stream;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public InputStream stream() {
|
||||
return stream;
|
||||
}
|
||||
|
||||
public long length() {
|
||||
return length;
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.20.1-SNAPSHOT</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.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -46,7 +46,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -159,21 +159,21 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>13.20.1-SNAPSHOT</version>
|
||||
<version>13.22.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -73,13 +73,13 @@ public final class BindParams implements Serializable {
|
||||
for (Param param : positionedParameters) {
|
||||
tempBindCount = param.queryBindCount();
|
||||
bc += tempBindCount;
|
||||
builder.append("p").append(bc).append(" ?:").append(tempBindCount).append(",");
|
||||
builder.append('p').append(bc).append(" ?:").append(tempBindCount).append(',');
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Param> entry : namedParameters.entrySet()) {
|
||||
tempBindCount = entry.getValue().queryBindCount();
|
||||
bc += tempBindCount;
|
||||
builder.append("n").append(bc).append(" k:").append(entry.getKey()).append(" ?:").append(tempBindCount).append(",");
|
||||
builder.append('n').append(bc).append(" k:").append(entry.getKey()).append(" ?:").append(tempBindCount).append(',');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +111,12 @@ public final class LoadManyRequest extends LoadRequest {
|
||||
loadContext.configureQuery(query);
|
||||
if (onlyIds) {
|
||||
// lazy loading invoked via clear() and removeAll()
|
||||
query.select(many.targetIdProperty());
|
||||
String mapKey = many.mapKey();
|
||||
if (mapKey != null) {
|
||||
query.select(mapKey);
|
||||
} else {
|
||||
query.select(many.targetIdProperty());
|
||||
}
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
@@ -61,9 +61,4 @@ public interface SpiDtoQuery<T> extends DtoQuery<T>, SpiSqlBinding {
|
||||
*/
|
||||
SpiQuery<?> ormQuery();
|
||||
|
||||
/**
|
||||
* Return the explicit transaction used to execute the query.
|
||||
*/
|
||||
Transaction transaction();
|
||||
|
||||
}
|
||||
|
||||
@@ -66,6 +66,11 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
|
||||
*/
|
||||
CallOrigin createCallOrigin();
|
||||
|
||||
/**
|
||||
* Override in order to return SpiQuery
|
||||
*/
|
||||
<T> SpiQuery<T> createQuery(Class<T> beanType);
|
||||
|
||||
/**
|
||||
* Return the PersistenceContextScope to use defined at query or server level.
|
||||
*/
|
||||
@@ -135,8 +140,9 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
|
||||
* Create a ServerTransaction for query purposes.
|
||||
*
|
||||
* @param tenantId For multi-tenant lazy loading provide the tenantId to use.
|
||||
* @param useMaster Set to true when the query should use the master data source.
|
||||
*/
|
||||
SpiTransaction createReadOnlyTransaction(Object tenantId);
|
||||
SpiTransaction createReadOnlyTransaction(Object tenantId, boolean useMaster);
|
||||
|
||||
/**
|
||||
* An event from another server in the cluster used to notify local
|
||||
@@ -147,7 +153,7 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
|
||||
/**
|
||||
* Compile a query.
|
||||
*/
|
||||
<T> CQuery<T> compileQuery(Type type, Query<T> query, Transaction transaction);
|
||||
<T> CQuery<T> compileQuery(Type type, SpiQuery<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the findId's query but without copying the query.
|
||||
@@ -156,12 +162,12 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
|
||||
* the query has finished (if executing in a background thread).
|
||||
* </p>
|
||||
*/
|
||||
<A, T> List<A> findIdsWithCopy(Query<T> query, Transaction transaction);
|
||||
<A, T> List<A> findIdsWithCopy(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Execute the findCount query but without copying the query.
|
||||
*/
|
||||
<T> int findCountWithCopy(Query<T> query, Transaction transaction);
|
||||
<T> int findCountWithCopy(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Load a batch of Associated One Beans.
|
||||
@@ -289,7 +295,7 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
|
||||
/**
|
||||
* Execute the underlying ORM query returning as a JDBC ResultSet to map to DTO beans.
|
||||
*/
|
||||
SpiResultSet findResultSet(SpiQuery<?> ormQuery, SpiTransaction transaction);
|
||||
SpiResultSet findResultSet(SpiQuery<?> ormQuery);
|
||||
|
||||
/**
|
||||
* Visit all the metrics (typically reporting them).
|
||||
@@ -321,136 +327,57 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
|
||||
*/
|
||||
SpiQueryBindCapture createQueryBindCapture(SpiQueryPlan queryPlan);
|
||||
|
||||
<T> boolean exists(SpiQuery<T> ormQuery);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> boolean exists(Query<T> ormQuery, Transaction transaction);
|
||||
<T> int findCount(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> int findCount(Query<T> query, Transaction transaction);
|
||||
<A, T> List<A> findIds(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<A, T> List<A> findIds(Query<T> query, Transaction transaction);
|
||||
<T> QueryIterator<T> findIterate(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction);
|
||||
<T> Stream<T> findStream(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> Stream<T> findStream(Query<T> query, Transaction transaction);
|
||||
<T> void findEach(SpiQuery<T> query, Consumer<T> consumer);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> void findEach(Query<T> query, Consumer<T> consumer, Transaction transaction);
|
||||
<T> void findEach(SpiQuery<T> query, int batch, Consumer<List<T>> consumer);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> void findEach(Query<T> query, int batch, Consumer<List<T>> consumer, Transaction t);
|
||||
<T> void findEachWhile(SpiQuery<T> query, Predicate<T> consumer);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> void findEachWhile(Query<T> query, Predicate<T> consumer, Transaction transaction);
|
||||
<T> List<Version<T>> findVersions(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> List<Version<T>> findVersions(Query<T> query, Transaction transaction);
|
||||
<T> List<T> findList(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> List<T> findList(Query<T> query, Transaction transaction);
|
||||
<T> FutureRowCount<T> findFutureCount(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> FutureRowCount<T> findFutureCount(Query<T> query, Transaction transaction);
|
||||
<T> FutureIds<T> findFutureIds(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> FutureIds<T> findFutureIds(Query<T> query, Transaction transaction);
|
||||
<T> FutureList<T> findFutureList(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> FutureList<T> findFutureList(Query<T> query, Transaction transaction);
|
||||
<T> PagedList<T> findPagedList(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> PagedList<T> findPagedList(Query<T> query, Transaction transaction);
|
||||
<T> Set<T> findSet(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> Set<T> findSet(Query<T> query, Transaction transaction);
|
||||
<K, T> Map<K, T> findMap(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<K, T> Map<K, T> findMap(Query<T> query, Transaction transaction);
|
||||
<A, T> List<A> findSingleAttributeList(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<A, T> List<A> findSingleAttributeList(Query<T> query, Transaction transaction);
|
||||
<A, T> Set<A> findSingleAttributeSet(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<A, T> Set<A> findSingleAttributeSet(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Nullable
|
||||
<T> T findOne(Query<T> query, Transaction transaction);
|
||||
<T> T findOne(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> Optional<T> findOneOrEmpty(Query<T> query, Transaction transaction);
|
||||
<T> Optional<T> findOneOrEmpty(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> int delete(Query<T> query, Transaction transaction);
|
||||
<T> int delete(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
<T> int update(Query<T> query, Transaction transaction);
|
||||
<T> int update(SpiQuery<T> query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
List<SqlRow> findList(SqlQuery query, Transaction transaction);
|
||||
List<SqlRow> findList(SpiSqlQuery query);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
void findEach(SqlQuery query, Consumer<SqlRow> consumer, Transaction transaction);
|
||||
void findEach(SpiSqlQuery query, Consumer<SqlRow> consumer);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
void findEachWhile(SqlQuery query, Predicate<SqlRow> consumer, Transaction transaction);
|
||||
void findEachWhile(SpiSqlQuery query, Predicate<SqlRow> consumer);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link SqlQuery#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Nullable
|
||||
SqlRow findOne(SqlQuery query, Transaction transaction);
|
||||
SqlRow findOne(SpiSqlQuery query);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,11 @@ public interface SpiExpressionRequest {
|
||||
*/
|
||||
SpiExpressionRequest append(String expression);
|
||||
|
||||
/**
|
||||
* Append to the expression sql without any parsing.
|
||||
*/
|
||||
SpiExpressionRequest append(char c);
|
||||
|
||||
/**
|
||||
* Append to the expression sql with logical property parsing to db columns with logical path prefix.
|
||||
* <p>
|
||||
|
||||
@@ -235,6 +235,16 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
*/
|
||||
String planLabel();
|
||||
|
||||
/**
|
||||
* Return the transaction explicitly assigned or null.
|
||||
*/
|
||||
SpiTransaction transaction();
|
||||
|
||||
/**
|
||||
* Return true if this query should not use the read only data source.
|
||||
*/
|
||||
boolean isUseMaster();
|
||||
|
||||
/**
|
||||
* Return true if this is a "find by id" query. This includes a check for a single "equal to" expression for the Id.
|
||||
*/
|
||||
@@ -867,17 +877,6 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
*/
|
||||
boolean isDisableReadAudit();
|
||||
|
||||
/**
|
||||
* Return true if this is a query executing in the background.
|
||||
*/
|
||||
boolean isFutureFetch();
|
||||
|
||||
/**
|
||||
* Set to true to indicate the query is executing in a background thread
|
||||
* asynchronously.
|
||||
*/
|
||||
void setFutureFetch(boolean futureFetch);
|
||||
|
||||
/**
|
||||
* Set the readEvent for future queries (as prepared in foreground thread).
|
||||
*/
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
package io.ebeaninternal.api;
|
||||
|
||||
import io.avaje.lang.Nullable;
|
||||
|
||||
/**
|
||||
* SQL query binding (for SqlQuery and DtoQuery).
|
||||
*/
|
||||
public interface SpiSqlBinding extends SpiCancelableQuery {
|
||||
|
||||
/**
|
||||
* Return the transaction explicitly associated to the query.
|
||||
*/
|
||||
@Nullable
|
||||
SpiTransaction transaction();
|
||||
|
||||
/**
|
||||
* Return true if this query should not use the read only data source.
|
||||
*/
|
||||
boolean isUseMaster();
|
||||
|
||||
/**
|
||||
* Return the named or positioned parameters.
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
package io.ebeaninternal.api;
|
||||
|
||||
import io.avaje.lang.Nullable;
|
||||
import io.ebean.SqlQuery;
|
||||
import io.ebean.Transaction;
|
||||
|
||||
/**
|
||||
* SQL query - Internal extension to SqlQuery.
|
||||
*/
|
||||
public interface SpiSqlQuery extends SqlQuery, SpiSqlBinding {
|
||||
|
||||
/**
|
||||
* Return the transaction explicitly associated to the query.
|
||||
*/
|
||||
@Nullable
|
||||
Transaction transaction();
|
||||
}
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
package io.ebeaninternal.server.bind;
|
||||
|
||||
import io.ebean.core.type.DataBinder;
|
||||
import io.ebean.core.type.InputStreamInfo;
|
||||
import io.ebeaninternal.api.CoreLog;
|
||||
import io.ebeaninternal.server.core.timezone.DataTimeZone;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.io.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
@@ -27,8 +23,6 @@ public class DataBind implements DataBinder {
|
||||
protected int pos;
|
||||
private String json;
|
||||
|
||||
private Object lastObject = null;
|
||||
|
||||
public DataBind(DataTimeZone dataTimeZone, PreparedStatement pstmt, Connection connection) {
|
||||
this.dataTimeZone = dataTimeZone;
|
||||
this.pstmt = pstmt;
|
||||
@@ -71,19 +65,16 @@ public class DataBind implements DataBinder {
|
||||
@Override
|
||||
public void setObject(Object value) throws SQLException {
|
||||
pstmt.setObject(++pos, value);
|
||||
lastObject = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setObject(Object value, int sqlType) throws SQLException {
|
||||
pstmt.setObject(++pos, value, sqlType);
|
||||
lastObject = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNull(int jdbcType) throws SQLException {
|
||||
pstmt.setNull(++pos, jdbcType);
|
||||
lastObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,7 +96,7 @@ public class DataBind implements DataBinder {
|
||||
}
|
||||
}
|
||||
|
||||
public void closeInputStreams() {
|
||||
private void closeInputStreams() {
|
||||
if (inputStreams != null) {
|
||||
for (InputStream inputStream : inputStreams) {
|
||||
try {
|
||||
@@ -126,43 +117,36 @@ public class DataBind implements DataBinder {
|
||||
@Override
|
||||
public void setString(String value) throws SQLException {
|
||||
pstmt.setString(++pos, value);
|
||||
lastObject = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setInt(int value) throws SQLException {
|
||||
pstmt.setInt(++pos, value);
|
||||
lastObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setLong(long value) throws SQLException {
|
||||
pstmt.setLong(++pos, value);
|
||||
lastObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setShort(short value) throws SQLException {
|
||||
pstmt.setShort(++pos, value);
|
||||
lastObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setFloat(float value) throws SQLException {
|
||||
pstmt.setFloat(++pos, value);
|
||||
lastObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setDouble(double value) throws SQLException {
|
||||
pstmt.setDouble(++pos, value);
|
||||
lastObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setBigDecimal(BigDecimal value) throws SQLException {
|
||||
pstmt.setBigDecimal(++pos, value);
|
||||
lastObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -173,7 +157,6 @@ public class DataBind implements DataBinder {
|
||||
} else {
|
||||
pstmt.setDate(++pos, value);
|
||||
}
|
||||
lastObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -184,7 +167,6 @@ public class DataBind implements DataBinder {
|
||||
} else {
|
||||
pstmt.setTimestamp(++pos, value);
|
||||
}
|
||||
lastObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -195,31 +177,26 @@ public class DataBind implements DataBinder {
|
||||
} else {
|
||||
pstmt.setTime(++pos, value);
|
||||
}
|
||||
lastObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBoolean(boolean value) throws SQLException {
|
||||
pstmt.setBoolean(++pos, value);
|
||||
lastObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBytes(byte[] value) throws SQLException {
|
||||
pstmt.setBytes(++pos, value);
|
||||
lastObject = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setByte(byte value) throws SQLException {
|
||||
pstmt.setByte(++pos, value);
|
||||
lastObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChar(char value) throws SQLException {
|
||||
pstmt.setString(++pos, String.valueOf(value));
|
||||
lastObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -234,31 +211,21 @@ public class DataBind implements DataBinder {
|
||||
}
|
||||
inputStreams.add(inputStream);
|
||||
pstmt.setBinaryStream(++pos, inputStream, length);
|
||||
lastObject = new InputStreamInfo(inputStream, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlob(byte[] bytes) throws SQLException {
|
||||
pstmt.setBinaryStream(++pos, new ByteArrayInputStream(bytes), bytes.length);
|
||||
lastObject = bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClob(String content) throws SQLException {
|
||||
pstmt.setCharacterStream(++pos, new StringReader(content), content.length());
|
||||
lastObject = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArray(String arrayType, Object[] elements) throws SQLException {
|
||||
pstmt.setArray(++pos, connection.createArrayOf(arrayType, elements));
|
||||
lastObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object popLastObject() {
|
||||
Object ret = lastObject;
|
||||
lastObject = null;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,10 +33,10 @@ public abstract class AbstractSqlQueryRequest implements CancelableQuery {
|
||||
/**
|
||||
* Create the BeanFindRequest.
|
||||
*/
|
||||
AbstractSqlQueryRequest(SpiEbeanServer server, SpiSqlBinding query, Transaction t) {
|
||||
AbstractSqlQueryRequest(SpiEbeanServer server, SpiSqlBinding query) {
|
||||
this.server = server;
|
||||
this.query = query;
|
||||
this.transaction = (SpiTransaction) t;
|
||||
this.transaction = query.transaction();
|
||||
this.query.setCancelableQuery(this);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public abstract class AbstractSqlQueryRequest implements CancelableQuery {
|
||||
transaction = server.currentServerTransaction();
|
||||
if (transaction == null || !transaction.isActive()) {
|
||||
// create a local readOnly transaction
|
||||
transaction = server.createReadOnlyTransaction(null);
|
||||
transaction = server.createReadOnlyTransaction(null, query.isUseMaster());
|
||||
createdTransaction = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public abstract class BeanRequest {
|
||||
*/
|
||||
public void commitTransIfRequired() {
|
||||
if (createdTransaction) {
|
||||
server.commitTransaction();
|
||||
transaction.commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ final class DefaultBeanLoader {
|
||||
query.setLoadDescription("+lazy", null);
|
||||
}
|
||||
|
||||
query.select(parentDesc.idBinder().getIdProperty());
|
||||
query.select(parentDesc.idBinder().idSelect());
|
||||
if (onlyIds) {
|
||||
query.fetch(many.name(), many.targetIdProperty());
|
||||
} else {
|
||||
@@ -106,7 +106,7 @@ final class DefaultBeanLoader {
|
||||
query.setReadOnly(true);
|
||||
}
|
||||
|
||||
server.findOne(query, null);
|
||||
server.findOne(query);
|
||||
if (beanCollection != null) {
|
||||
if (beanCollection.checkEmptyLazyLoad()) {
|
||||
if (log.isLoggable(DEBUG)) {
|
||||
@@ -127,6 +127,7 @@ final class DefaultBeanLoader {
|
||||
throw new RuntimeException("Nothing in batch?");
|
||||
}
|
||||
final SpiQuery<?> query = server.createQuery(loadRequest.beanType());
|
||||
query.usingTransaction(loadRequest.transaction());
|
||||
loadRequest.configureQuery(query);
|
||||
loadRequest.postLoad(executeQuery(loadRequest, query));
|
||||
}
|
||||
@@ -137,14 +138,15 @@ final class DefaultBeanLoader {
|
||||
private List<?> executeQuery(LoadRequest loadRequest, SpiQuery<?> query) {
|
||||
if (onIterateUseExtraTxn && loadRequest.isParentFindIterate()) {
|
||||
// MySql - we need a different transaction to execute the secondary query
|
||||
SpiTransaction extraTxn = server.createReadOnlyTransaction(query.tenantId());
|
||||
SpiTransaction extraTxn = server.createReadOnlyTransaction(query.tenantId(), query.isUseMaster());
|
||||
try {
|
||||
return server.findList(query, extraTxn);
|
||||
query.usingTransaction(extraTxn);
|
||||
return server.findList(query);
|
||||
} finally {
|
||||
extraTxn.end();
|
||||
}
|
||||
} else {
|
||||
return server.findList(query, loadRequest.transaction());
|
||||
return server.findList(query);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -440,8 +440,9 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
* Compile a query. Only valid for ORM queries.
|
||||
*/
|
||||
@Override
|
||||
public <T> CQuery<T> compileQuery(Type type, Query<T> query, Transaction transaction) {
|
||||
SpiOrmQueryRequest<T> qr = createQueryRequest(type, query, transaction);
|
||||
public <T> CQuery<T> compileQuery(Type type, SpiQuery<T> query, Transaction transaction) {
|
||||
query.usingTransaction(transaction);
|
||||
SpiOrmQueryRequest<T> qr = createQueryRequest(type, query);
|
||||
OrmQueryRequest<T> orm = (OrmQueryRequest<T>) qr;
|
||||
return cqueryEngine.buildQuery(orm);
|
||||
}
|
||||
@@ -903,8 +904,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpiResultSet findResultSet(SpiQuery<?> ormQuery, SpiTransaction transaction) {
|
||||
SpiOrmQueryRequest<?> request = createQueryRequest(ormQuery.type(), ormQuery, transaction);
|
||||
public SpiResultSet findResultSet(SpiQuery<?> ormQuery) {
|
||||
SpiOrmQueryRequest<?> request = createQueryRequest(ormQuery.type(), ormQuery);
|
||||
request.initTransIfRequired();
|
||||
return request.findResultSet();
|
||||
}
|
||||
@@ -935,24 +936,26 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
@Override
|
||||
public <T> T find(Class<T> beanType, Object id, @Nullable Transaction transaction) {
|
||||
Objects.requireNonNull(id);
|
||||
Query<T> query = createQuery(beanType).setId(id);
|
||||
return findId(query, transaction);
|
||||
SpiQuery<T> query = createQuery(beanType);
|
||||
query.usingTransaction(transaction);
|
||||
query.setId(id);
|
||||
return findId(query);
|
||||
}
|
||||
|
||||
<T> SpiOrmQueryRequest<T> createQueryRequest(Type type, Query<T> query, @Nullable Transaction transaction) {
|
||||
SpiOrmQueryRequest<T> request = buildQueryRequest(type, query, transaction);
|
||||
<T> SpiOrmQueryRequest<T> createQueryRequest(Type type, SpiQuery<T> query) {
|
||||
SpiOrmQueryRequest<T> request = buildQueryRequest(type, query);
|
||||
request.prepareQuery();
|
||||
return request;
|
||||
}
|
||||
|
||||
<T> SpiOrmQueryRequest<T> buildQueryRequest(Type type, Query<T> query, @Nullable Transaction transaction) {
|
||||
SpiQuery<T> spiQuery = (SpiQuery<T>) query;
|
||||
spiQuery.setType(type);
|
||||
spiQuery.checkNamedParameters();
|
||||
return buildQueryRequest(spiQuery, transaction);
|
||||
<T> SpiOrmQueryRequest<T> buildQueryRequest(Type type, SpiQuery<T> query) {
|
||||
query.setType(type);
|
||||
query.checkNamedParameters();
|
||||
return buildQueryRequest(query);
|
||||
}
|
||||
|
||||
private <T> SpiOrmQueryRequest<T> buildQueryRequest(SpiQuery<T> query, @Nullable Transaction transaction) {
|
||||
private <T> SpiOrmQueryRequest<T> buildQueryRequest(SpiQuery<T> query) {
|
||||
SpiTransaction transaction = query.transaction();
|
||||
if (transaction == null) {
|
||||
transaction = currentServerTransaction();
|
||||
}
|
||||
@@ -973,7 +976,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
if (query.parentNode() == null) {
|
||||
query.setOrigin(createCallOrigin());
|
||||
}
|
||||
return new OrmQueryRequest<>(this, queryEngine, query, (SpiTransaction) transaction);
|
||||
return new OrmQueryRequest<>(this, queryEngine, query, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -981,8 +984,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T findIdCheckPersistenceContextAndCache(@Nullable Transaction transaction, SpiQuery<T> query, Object id) {
|
||||
SpiTransaction t = (SpiTransaction) transaction;
|
||||
private <T> T findIdCheckPersistenceContextAndCache(SpiQuery<T> query, Object id) {
|
||||
SpiTransaction t = query.transaction();
|
||||
if (t == null) {
|
||||
t = currentServerTransaction();
|
||||
}
|
||||
@@ -1028,18 +1031,17 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T findId(Query<T> query, @Nullable Transaction transaction) {
|
||||
SpiQuery<T> spiQuery = (SpiQuery<T>) query;
|
||||
spiQuery.setType(Type.BEAN);
|
||||
if (SpiQuery.Mode.NORMAL == spiQuery.mode() && !spiQuery.isForceHitDatabase()) {
|
||||
private <T> T findId(SpiQuery<T> query) {
|
||||
query.setType(Type.BEAN);
|
||||
if (SpiQuery.Mode.NORMAL == query.mode() && !query.isForceHitDatabase()) {
|
||||
// See if we can skip doing the fetch completely by getting the bean from the
|
||||
// persistence context or the bean cache
|
||||
T bean = findIdCheckPersistenceContextAndCache(transaction, spiQuery, spiQuery.getId());
|
||||
T bean = findIdCheckPersistenceContextAndCache(query, query.getId());
|
||||
if (bean != null) {
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
SpiOrmQueryRequest<T> request = buildQueryRequest(spiQuery, transaction);
|
||||
SpiOrmQueryRequest<T> request = buildQueryRequest(query);
|
||||
request.prepareQuery();
|
||||
if (request.isUseDocStore()) {
|
||||
return docStore().find(request);
|
||||
@@ -1053,23 +1055,19 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> findOneOrEmpty(Query<T> query, Transaction transaction) {
|
||||
return Optional.ofNullable(findOne(query, transaction));
|
||||
public <T> Optional<T> findOneOrEmpty(SpiQuery<T> query) {
|
||||
return Optional.ofNullable(findOne(query));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T findOne(Query<T> query, @Nullable Transaction transaction) {
|
||||
SpiQuery<T> spiQuery = (SpiQuery<T>) query;
|
||||
if (spiQuery.isFindById()) {
|
||||
public <T> T findOne(SpiQuery<T> query) {
|
||||
if (query.isFindById()) {
|
||||
// actually a find by Id query
|
||||
return findId(query, transaction);
|
||||
}
|
||||
if (transaction == null) {
|
||||
transaction = currentServerTransaction();
|
||||
return findId(query);
|
||||
}
|
||||
// a query that is expected to return either 0 or 1 beans
|
||||
List<T> list = findList(query, transaction, true);
|
||||
List<T> list = findList(query, true);
|
||||
return extractUnique(list);
|
||||
}
|
||||
|
||||
@@ -1086,10 +1084,10 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public <T> Set<T> findSet(Query<T> query, Transaction transaction) {
|
||||
SpiOrmQueryRequest request = buildQueryRequest(Type.SET, query, transaction);
|
||||
public <T> Set<T> findSet(SpiQuery<T> query) {
|
||||
SpiOrmQueryRequest request = buildQueryRequest(Type.SET, query);
|
||||
request.resetBeanCacheAutoMode(false);
|
||||
if ((transaction == null || !transaction.isSkipCache()) && request.getFromBeanCache()) {
|
||||
if (request.isGetAllFromBeanCache()) {
|
||||
// hit bean cache and got all results from cache
|
||||
return request.beanCacheHitsAsSet();
|
||||
}
|
||||
@@ -1108,10 +1106,10 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public <K, T> Map<K, T> findMap(Query<T> query, @Nullable Transaction transaction) {
|
||||
SpiOrmQueryRequest request = buildQueryRequest(Type.MAP, query, transaction);
|
||||
public <K, T> Map<K, T> findMap(SpiQuery<T> query) {
|
||||
SpiOrmQueryRequest request = buildQueryRequest(Type.MAP, query);
|
||||
request.resetBeanCacheAutoMode(false);
|
||||
if ((transaction == null || !transaction.isSkipCache()) && request.getFromBeanCache()) {
|
||||
if (request.isGetAllFromBeanCache()) {
|
||||
// hit bean cache and got all results from cache
|
||||
return request.beanCacheHitsAsMap();
|
||||
}
|
||||
@@ -1130,8 +1128,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <A, T> List<A> findSingleAttributeList(Query<T> query, Transaction transaction) {
|
||||
SpiOrmQueryRequest<T> request = buildQueryRequest(Type.ATTRIBUTE, query, transaction);
|
||||
public <A, T> List<A> findSingleAttributeList(SpiQuery<T> query) {
|
||||
SpiOrmQueryRequest<T> request = buildQueryRequest(Type.ATTRIBUTE, query);
|
||||
request.query().setSingleAttribute();
|
||||
request.prepareQuery();
|
||||
Object result = request.getFromQueryCache();
|
||||
@@ -1148,8 +1146,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <A, T> Set<A> findSingleAttributeSet(Query<T> query, Transaction transaction) {
|
||||
SpiOrmQueryRequest<T> request = buildQueryRequest(Type.ATTRIBUTE_SET, query, transaction);
|
||||
public <A, T> Set<A> findSingleAttributeSet(SpiQuery<T> query) {
|
||||
SpiOrmQueryRequest<T> request = buildQueryRequest(Type.ATTRIBUTE_SET, query);
|
||||
request.query().setSingleAttribute();
|
||||
request.prepareQuery();
|
||||
Object result = request.getFromQueryCache();
|
||||
@@ -1165,17 +1163,16 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> int findCount(Query<T> query, @Nullable Transaction transaction) {
|
||||
SpiQuery<T> spiQuery = ((SpiQuery<T>) query);
|
||||
if (!spiQuery.isDistinct()) {
|
||||
spiQuery = spiQuery.copy();
|
||||
public <T> int findCount(SpiQuery<T> query) {
|
||||
if (!query.isDistinct()) {
|
||||
query = query.copy();
|
||||
}
|
||||
return findCountWithCopy(spiQuery, transaction);
|
||||
return findCountWithCopy(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> int findCountWithCopy(Query<T> query, @Nullable Transaction transaction) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.COUNT, query, transaction);
|
||||
public <T> int findCountWithCopy(SpiQuery<T> query) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.COUNT, query);
|
||||
Integer result = request.getFromQueryCache();
|
||||
if (result != null) {
|
||||
return result;
|
||||
@@ -1190,13 +1187,17 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
|
||||
@Override
|
||||
public boolean exists(Class<?> beanType, Object beanId, Transaction transaction) {
|
||||
return !findIdsWithCopy(find(beanType).setId(beanId), transaction).isEmpty();
|
||||
final DefaultOrmQuery<?> query = createQuery(beanType);
|
||||
query.usingTransaction(transaction);
|
||||
query.setId(beanId);
|
||||
return !findIdsWithCopy(query).isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean exists(Query<T> ormQuery, Transaction transaction) {
|
||||
Query<T> ormQueryCopy = ormQuery.copy().setMaxRows(1);
|
||||
SpiOrmQueryRequest<?> request = createQueryRequest(Type.EXISTS, ormQueryCopy, transaction);
|
||||
public <T> boolean exists(SpiQuery<T> ormQuery) {
|
||||
SpiQuery<T> ormQueryCopy = ormQuery.copy();
|
||||
ormQueryCopy.setMaxRows(1);
|
||||
SpiOrmQueryRequest<?> request = createQueryRequest(Type.EXISTS, ormQueryCopy);
|
||||
List<Object> ids = request.getFromQueryCache();
|
||||
if (ids != null) {
|
||||
return !ids.isEmpty();
|
||||
@@ -1210,14 +1211,14 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A, T> List<A> findIds(Query<T> query, Transaction transaction) {
|
||||
return findIdsWithCopy(((SpiQuery<T>) query).copy(), transaction);
|
||||
public <A, T> List<A> findIds(SpiQuery<T> query) {
|
||||
return findIdsWithCopy(query.copy());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <A, T> List<A> findIdsWithCopy(Query<T> query, Transaction transaction) {
|
||||
SpiOrmQueryRequest<?> request = createQueryRequest(Type.ID_LIST, query, transaction);
|
||||
public <A, T> List<A> findIdsWithCopy(SpiQuery<T> query) {
|
||||
SpiOrmQueryRequest<?> request = createQueryRequest(Type.ID_LIST, query);
|
||||
Object result = request.getFromQueryCache();
|
||||
if (result != null) {
|
||||
if (Boolean.FALSE.equals(request.query().isReadOnly())) {
|
||||
@@ -1235,8 +1236,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> int delete(Query<T> query, Transaction transaction) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.DELETE, query, transaction);
|
||||
public <T> int delete(SpiQuery<T> query) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.DELETE, query);
|
||||
try {
|
||||
request.initTransIfRequired();
|
||||
request.markNotQueryOnly();
|
||||
@@ -1258,8 +1259,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> int update(Query<T> query, Transaction transaction) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.UPDATE, query, transaction);
|
||||
public <T> int update(SpiQuery<T> query) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.UPDATE, query);
|
||||
try {
|
||||
request.initTransIfRequired();
|
||||
request.markNotQueryOnly();
|
||||
@@ -1270,29 +1271,44 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> FutureRowCount<T> findFutureCount(Query<T> query, Transaction transaction) {
|
||||
SpiQuery<T> copy = ((SpiQuery<T>) query).copy();
|
||||
copy.setFutureFetch(true);
|
||||
Transaction newTxn = createTransaction();
|
||||
QueryFutureRowCount<T> queryFuture = new QueryFutureRowCount<>(new CallableQueryCount<>(this, copy, newTxn));
|
||||
public <T> FutureRowCount<T> findFutureCount(SpiQuery<T> query) {
|
||||
SpiQuery<T> copy = query.copy();
|
||||
boolean createdTransaction = false;
|
||||
SpiTransaction transaction = query.transaction();
|
||||
if (transaction == null) {
|
||||
transaction = currentServerTransaction();
|
||||
if (transaction == null) {
|
||||
transaction = (SpiTransaction) createTransaction();
|
||||
createdTransaction = true;
|
||||
}
|
||||
copy.usingTransaction(transaction);
|
||||
}
|
||||
var queryFuture = new QueryFutureRowCount<>(new CallableQueryCount<>(this, copy, createdTransaction));
|
||||
backgroundExecutor.execute(queryFuture.futureTask());
|
||||
return queryFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> FutureIds<T> findFutureIds(Query<T> query, Transaction transaction) {
|
||||
SpiQuery<T> copy = ((SpiQuery<T>) query).copy();
|
||||
copy.setFutureFetch(true);
|
||||
Transaction newTxn = createTransaction();
|
||||
QueryFutureIds<T> queryFuture = new QueryFutureIds<>(new CallableQueryIds<>(this, copy, newTxn));
|
||||
public <T> FutureIds<T> findFutureIds(SpiQuery<T> query) {
|
||||
SpiQuery<T> copy = query.copy();
|
||||
boolean createdTransaction = false;
|
||||
SpiTransaction transaction = query.transaction();
|
||||
if (transaction == null) {
|
||||
transaction = currentServerTransaction();
|
||||
if (transaction == null) {
|
||||
transaction = (SpiTransaction) createTransaction();
|
||||
createdTransaction = true;
|
||||
}
|
||||
copy.usingTransaction(transaction);
|
||||
}
|
||||
QueryFutureIds<T> queryFuture = new QueryFutureIds<>(new CallableQueryIds<>(this, copy, createdTransaction));
|
||||
backgroundExecutor.execute(queryFuture.futureTask());
|
||||
return queryFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> FutureList<T> findFutureList(Query<T> query, Transaction transaction) {
|
||||
SpiQuery<T> spiQuery = (SpiQuery<T>) query.copy();
|
||||
spiQuery.setFutureFetch(true);
|
||||
public <T> FutureList<T> findFutureList(SpiQuery<T> query) {
|
||||
SpiQuery<T> spiQuery = query.copy();
|
||||
// FutureList query always run in it's own persistence content
|
||||
spiQuery.setPersistenceContext(new DefaultPersistenceContext());
|
||||
if (!spiQuery.isDisableReadAudit()) {
|
||||
@@ -1300,28 +1316,36 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
desc.readAuditFutureList(spiQuery);
|
||||
}
|
||||
// Create a new transaction solely to execute the findList() at some future time
|
||||
Transaction newTxn = createTransaction();
|
||||
QueryFutureList<T> queryFuture = new QueryFutureList<>(new CallableQueryList<>(this, spiQuery, newTxn));
|
||||
boolean createdTransaction = false;
|
||||
SpiTransaction transaction = query.transaction();
|
||||
if (transaction == null) {
|
||||
transaction = currentServerTransaction();
|
||||
if (transaction == null) {
|
||||
transaction = (SpiTransaction) createTransaction();
|
||||
createdTransaction = true;
|
||||
}
|
||||
spiQuery.usingTransaction(transaction);
|
||||
}
|
||||
QueryFutureList<T> queryFuture = new QueryFutureList<>(new CallableQueryList<>(this, spiQuery, createdTransaction));
|
||||
backgroundExecutor.execute(queryFuture.futureTask());
|
||||
return queryFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> PagedList<T> findPagedList(Query<T> query, Transaction transaction) {
|
||||
SpiQuery<T> spiQuery = (SpiQuery<T>) query;
|
||||
int maxRows = spiQuery.getMaxRows();
|
||||
public <T> PagedList<T> findPagedList(SpiQuery<T> query) {
|
||||
int maxRows = query.getMaxRows();
|
||||
if (maxRows == 0) {
|
||||
throw new PersistenceException("maxRows must be specified for findPagedList() query");
|
||||
}
|
||||
if (spiQuery.isUseDocStore()) {
|
||||
return docStore().findPagedList(createQueryRequest(Type.LIST, query, transaction));
|
||||
if (query.isUseDocStore()) {
|
||||
return docStore().findPagedList(createQueryRequest(Type.LIST, query));
|
||||
}
|
||||
return new LimitOffsetPagedList<>(this, spiQuery);
|
||||
return new LimitOffsetPagedList<>(this, query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query, transaction);
|
||||
public <T> QueryIterator<T> findIterate(SpiQuery<T> query) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query);
|
||||
try {
|
||||
request.initTransIfRequired();
|
||||
return request.findIterate();
|
||||
@@ -1332,8 +1356,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Stream<T> findStream(Query<T> query, Transaction transaction) {
|
||||
return toStream(findIterate(query, transaction));
|
||||
public <T> Stream<T> findStream(SpiQuery<T> query) {
|
||||
return toStream(findIterate(query));
|
||||
}
|
||||
|
||||
private <T> Stream<T> toStream(QueryIterator<T> queryIterator) {
|
||||
@@ -1341,8 +1365,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void findEach(Query<T> query, Consumer<T> consumer, Transaction transaction) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query, transaction);
|
||||
public <T> void findEach(SpiQuery<T> query, Consumer<T> consumer) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query);
|
||||
if (request.isUseDocStore()) {
|
||||
docStore().findEach(request, consumer);
|
||||
return;
|
||||
@@ -1353,8 +1377,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void findEach(Query<T> query, int batch, Consumer<List<T>> consumer, Transaction transaction) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query, transaction);
|
||||
public <T> void findEach(SpiQuery<T> query, int batch, Consumer<List<T>> consumer) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query);
|
||||
// if (request.isUseDocStore()) {
|
||||
// docStore().findEach(request, consumer);
|
||||
// return;
|
||||
@@ -1365,8 +1389,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void findEachWhile(Query<T> query, Predicate<T> consumer, Transaction transaction) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query, transaction);
|
||||
public <T> void findEachWhile(SpiQuery<T> query, Predicate<T> consumer) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ITERATE, query);
|
||||
if (request.isUseDocStore()) {
|
||||
docStore().findEachWhile(request, consumer);
|
||||
return;
|
||||
@@ -1377,8 +1401,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<Version<T>> findVersions(Query<T> query, @Nullable Transaction transaction) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.LIST, query, transaction);
|
||||
public <T> List<Version<T>> findVersions(SpiQuery<T> query) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.LIST, query);
|
||||
try {
|
||||
request.initTransIfRequired();
|
||||
return request.findVersions();
|
||||
@@ -1388,15 +1412,15 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> findList(Query<T> query, Transaction transaction) {
|
||||
return findList(query, transaction, false);
|
||||
public <T> List<T> findList(SpiQuery<T> query) {
|
||||
return findList(query, false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> List<T> findList(Query<T> query, @Nullable Transaction transaction, boolean findOne) {
|
||||
SpiOrmQueryRequest<T> request = buildQueryRequest(Type.LIST, query, transaction);
|
||||
private <T> List<T> findList(SpiQuery<T> query, boolean findOne) {
|
||||
SpiOrmQueryRequest<T> request = buildQueryRequest(Type.LIST, query);
|
||||
request.resetBeanCacheAutoMode(findOne);
|
||||
if ((transaction == null || !transaction.isSkipCache()) && request.getFromBeanCache()) {
|
||||
if (request.isGetAllFromBeanCache()) {
|
||||
// hit bean cache and got all results from cache
|
||||
return request.beanCacheHits();
|
||||
}
|
||||
@@ -1418,16 +1442,16 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public SqlRow findOne(SqlQuery query, Transaction transaction) {
|
||||
public SqlRow findOne(SpiSqlQuery query) {
|
||||
// no findId() method for SqlQuery...
|
||||
// a query that is expected to return either 0 or 1 rows
|
||||
List<SqlRow> list = findList(query, transaction);
|
||||
List<SqlRow> list = findList(query);
|
||||
return extractUnique(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findEach(SqlQuery query, Consumer<SqlRow> consumer, Transaction transaction) {
|
||||
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query, transaction);
|
||||
public void findEach(SpiSqlQuery query, Consumer<SqlRow> consumer) {
|
||||
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query);
|
||||
try {
|
||||
request.initTransIfRequired();
|
||||
request.findEach(consumer);
|
||||
@@ -1437,8 +1461,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findEachWhile(SqlQuery query, Predicate<SqlRow> consumer, Transaction transaction) {
|
||||
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query, transaction);
|
||||
public void findEachWhile(SpiSqlQuery query, Predicate<SqlRow> consumer) {
|
||||
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query);
|
||||
try {
|
||||
request.initTransIfRequired();
|
||||
request.findEachWhile(consumer);
|
||||
@@ -1448,8 +1472,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SqlRow> findList(SqlQuery query, Transaction transaction) {
|
||||
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query, transaction);
|
||||
public List<SqlRow> findList(SpiSqlQuery query) {
|
||||
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query);
|
||||
try {
|
||||
request.initTransIfRequired();
|
||||
return request.findList();
|
||||
@@ -1459,7 +1483,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
private <P> P executeSqlQuery(Function<RelationalQueryRequest, P> fun, SpiSqlQuery query) {
|
||||
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query, query.transaction());
|
||||
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query);
|
||||
try {
|
||||
request.initTransIfRequired();
|
||||
return fun.apply(request);
|
||||
@@ -2123,8 +2147,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpiTransaction createReadOnlyTransaction(Object tenantId) {
|
||||
return transactionManager.createReadOnlyTransaction(tenantId);
|
||||
public SpiTransaction createReadOnlyTransaction(Object tenantId, boolean useMaster) {
|
||||
return transactionManager.createReadOnlyTransaction(tenantId, useMaster);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2179,9 +2203,10 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
Object id = idProperty.getValue(entityBean);
|
||||
if (entityBean._ebean_getIntercept().isNew() && id != null) {
|
||||
// Primary Key is changeable only on new models - so skip check if we are not new
|
||||
Query<?> query = new DefaultOrmQuery<>(beanDesc, this, expressionFactory);
|
||||
SpiQuery<?> query = new DefaultOrmQuery<>(beanDesc, this, expressionFactory);
|
||||
query.usingTransaction(transaction);
|
||||
query.setId(id);
|
||||
if (findCount(query, transaction) > 0) {
|
||||
if (findCount(query) > 0) {
|
||||
return Collections.singleton(idProperty);
|
||||
}
|
||||
}
|
||||
@@ -2200,7 +2225,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
@Nullable
|
||||
private Set<Property> checkUniqueness(EntityBean entityBean, BeanDescriptor<?> beanDesc, BeanProperty[] props, @Nullable Transaction transaction) {
|
||||
BeanProperty idProperty = beanDesc.idProperty();
|
||||
Query<?> query = new DefaultOrmQuery<>(beanDesc, this, expressionFactory);
|
||||
SpiQuery<?> query = new DefaultOrmQuery<>(beanDesc, this, expressionFactory);
|
||||
query.usingTransaction(transaction);
|
||||
ExpressionList<?> exprList = query.where();
|
||||
if (!entityBean._ebean_getIntercept().isNew()) {
|
||||
// if model is not new, exclude ourself.
|
||||
@@ -2213,7 +2239,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
exprList.eq(prop.name(), value);
|
||||
}
|
||||
if (findCount(query, transaction) > 0) {
|
||||
if (findCount(query) > 0) {
|
||||
Set<Property> ret = new LinkedHashSet<>();
|
||||
Collections.addAll(ret, props);
|
||||
return ret;
|
||||
|
||||
@@ -281,9 +281,9 @@ public final class DefaultSqlUpdate implements Serializable, SpiSqlUpdate {
|
||||
int offset = 0;
|
||||
for (Object val : values) {
|
||||
if (offset > 0) {
|
||||
sqlExpand.append(",");
|
||||
sqlExpand.append(',');
|
||||
}
|
||||
sqlExpand.append("?");
|
||||
sqlExpand.append('?');
|
||||
bindParams.setParameter(position + offset++, val);
|
||||
}
|
||||
bindExpansion += (offset - 1);
|
||||
|
||||
@@ -33,7 +33,7 @@ public final class DtoQueryRequest<T> extends AbstractSqlQueryRequest {
|
||||
private DataReader dataReader;
|
||||
|
||||
DtoQueryRequest(SpiEbeanServer server, DtoQueryEngine engine, SpiDtoQuery<T> query) {
|
||||
super(server, query, query.transaction());
|
||||
super(server, query);
|
||||
this.queryEngine = engine;
|
||||
this.query = query;
|
||||
query.obtainLocation();
|
||||
@@ -52,7 +52,8 @@ public final class DtoQueryRequest<T> extends AbstractSqlQueryRequest {
|
||||
|
||||
query.setCancelableQuery(ormQuery);
|
||||
// execute the underlying ORM query returning the ResultSet
|
||||
SpiResultSet result = server.findResultSet(ormQuery, transaction);
|
||||
ormQuery.usingTransaction(transaction);
|
||||
SpiResultSet result = server.findResultSet(ormQuery);
|
||||
this.pstmt = result.statement();
|
||||
this.sql = ormQuery.getGeneratedSql();
|
||||
setResultSet(result.resultSet(), ormQuery.queryPlanKey());
|
||||
|
||||
@@ -121,7 +121,7 @@ final class DumpMetrics {
|
||||
}
|
||||
|
||||
private void appendQueryName(MetaQueryMetric metric, StringBuilder sb) {
|
||||
sb.append("query:").append(padName(metric.name())).append(" ");
|
||||
sb.append("query:").append(padName(metric.name())).append(' ');
|
||||
}
|
||||
|
||||
private void appendProfileAndSql(MetaQueryMetric metric, StringBuilder sb) {
|
||||
@@ -136,7 +136,7 @@ final class DumpMetrics {
|
||||
|
||||
private void log(MetaTimedMetric metric) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(padNameTimed(metric.name())).append(" ");
|
||||
sb.append(padNameTimed(metric.name())).append(' ');
|
||||
appendCounters(metric, sb);
|
||||
out(sb.toString());
|
||||
}
|
||||
|
||||
+4
-2
@@ -56,7 +56,10 @@ final class MultiTenantDbCatalogSupplier implements DataSourceSupplier {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection readOnlyConnection(Object tenantId) throws SQLException {
|
||||
public Connection readOnlyConnection(Object tenantId, boolean useMaster) throws SQLException {
|
||||
if (readOnly == null || useMaster) {
|
||||
return catalogDataSource.getConnectionForTenant(tenantId);
|
||||
}
|
||||
return readOnly.getConnectionForTenant(tenantId);
|
||||
}
|
||||
|
||||
@@ -103,7 +106,6 @@ final class MultiTenantDbCatalogSupplier implements DataSourceSupplier {
|
||||
*/
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
|
||||
Connection connection = dataSource.getConnection();
|
||||
connection.setCatalog(tenantCatalog());
|
||||
return connection;
|
||||
|
||||
+6
-3
@@ -56,8 +56,12 @@ final class MultiTenantDbSchemaSupplier implements DataSourceSupplier {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection readOnlyConnection(Object tenantId) throws SQLException {
|
||||
return readOnly.getConnectionForTenant(tenantId);
|
||||
public Connection readOnlyConnection(Object tenantId, boolean useMaster) throws SQLException {
|
||||
if (readOnly == null || useMaster) {
|
||||
return schemaDataSource.getConnectionForTenant(tenantId);
|
||||
} else {
|
||||
return readOnly.getConnectionForTenant(tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,7 +110,6 @@ final class MultiTenantDbSchemaSupplier implements DataSourceSupplier {
|
||||
*/
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
|
||||
Connection connection = dataSource.getConnection();
|
||||
connection.setSchema(tenantSchema());
|
||||
return connection;
|
||||
|
||||
@@ -43,8 +43,8 @@ final class MultiTenantDbSupplier implements DataSourceSupplier {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection readOnlyConnection(Object tenantId) throws SQLException {
|
||||
throw new SQLException("Not currently supported");
|
||||
public Connection readOnlyConnection(Object tenantId, boolean useMaster) throws SQLException {
|
||||
return dataSourceProvider.dataSource(tenantId).getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ final class ObtainedTransactionImplicit extends ObtainedTransaction {
|
||||
|
||||
@Override
|
||||
public void commitIfCreated() {
|
||||
server.commitTransaction();
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -60,6 +60,11 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
return queryEngine.translate(this, bindLog, sql, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGetAllFromBeanCache() {
|
||||
return (transaction == null || !transaction.isSkipCache()) && getFromBeanCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeleteByStatement() {
|
||||
if (!transaction.isPersistCascade() || beanDescriptor.isDeleteByStatement()) {
|
||||
@@ -220,7 +225,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
} else {
|
||||
// create an implicit transaction to execute this query
|
||||
// potentially using read-only DataSource with autoCommit
|
||||
transaction = server.createReadOnlyTransaction(query.tenantId());
|
||||
transaction = server.createReadOnlyTransaction(query.tenantId(), query.isUseMaster());
|
||||
}
|
||||
createdTransaction = true;
|
||||
}
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ public final class PersistDeferredRelationship {
|
||||
return; // could not bind: TODO: should we log/throw an error?
|
||||
}
|
||||
// bind the where clause for the bean
|
||||
Object[] idValues = beanDescriptor.idBinder().getIdValues(bean);
|
||||
Object[] idValues = beanDescriptor.idBinder().values(bean);
|
||||
for (int j = 0; j < idValues.length; j++) {
|
||||
sqlUpdate.setParameter(pos + j, idValues[j]);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.ebeaninternal.server.core;
|
||||
|
||||
import io.ebean.*;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiSqlBinding;
|
||||
import io.ebeaninternal.api.SpiSqlQuery;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
@@ -22,8 +22,8 @@ public final class RelationalQueryRequest extends AbstractSqlQueryRequest {
|
||||
private int estimateCapacity;
|
||||
private int rows;
|
||||
|
||||
RelationalQueryRequest(SpiEbeanServer server, RelationalQueryEngine engine, SqlQuery q, Transaction t) {
|
||||
super(server, (SpiSqlBinding) q, t);
|
||||
RelationalQueryRequest(SpiEbeanServer server, RelationalQueryEngine engine, SpiSqlQuery q) {
|
||||
super(server, q);
|
||||
this.queryEngine = engine;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,8 +41,12 @@ final class SimpleDataSourceProvider implements DataSourceSupplier {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection readOnlyConnection(Object tenantId) throws SQLException {
|
||||
return readOnlyDataSource.getConnection();
|
||||
public Connection readOnlyConnection(Object tenantId, boolean useMaster) throws SQLException {
|
||||
if (readOnlyDataSource == null || useMaster) {
|
||||
return dataSource.getConnection();
|
||||
} else {
|
||||
return readOnlyDataSource.getConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -188,4 +188,8 @@ public interface SpiOrmQueryRequest<T> extends BeanQueryRequest<T>, DocQueryRequ
|
||||
*/
|
||||
boolean isDeleteByStatement();
|
||||
|
||||
/**
|
||||
* Return true if hitting bean cache and returning all beans from cache.
|
||||
*/
|
||||
boolean isGetAllFromBeanCache();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.Query;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.BeanCollectionAdd;
|
||||
import io.ebean.bean.BeanCollectionLoader;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
import io.ebeaninternal.server.query.CQueryCollectionAdd;
|
||||
|
||||
@@ -63,11 +63,6 @@ public interface BeanCollectionHelp<T> extends CQueryCollectionAdd<T> {
|
||||
*/
|
||||
BeanCollection<T> createReference(EntityBean parentBean);
|
||||
|
||||
/**
|
||||
* Refresh the List Set or Map.
|
||||
*/
|
||||
void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean);
|
||||
|
||||
/**
|
||||
* Apply the new refreshed BeanCollection to the appropriate property of the parent bean.
|
||||
*/
|
||||
|
||||
@@ -212,7 +212,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
private final EntityBean prototypeEntityBean;
|
||||
|
||||
private final IdBinder idBinder;
|
||||
private final String idSelect;
|
||||
private String idBinderInLHSSql;
|
||||
private String idBinderIdSql;
|
||||
private String deleteByIdSql;
|
||||
@@ -355,23 +354,11 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
propertiesIndex[i] = propMap.get(ebi.property(i));
|
||||
}
|
||||
}
|
||||
idSelect = initIdSelect();
|
||||
}
|
||||
|
||||
String initIdSelect() {
|
||||
if (idProperty != null && !idProperty.name().equals("_idClass")) {
|
||||
return idProperty.name();
|
||||
} else if (entityType == EntityType.EMBEDDED) {
|
||||
return null;
|
||||
} else {
|
||||
StringJoiner sj = new StringJoiner(",");
|
||||
for (BeanProperty prop : propertiesNonMany) {
|
||||
if (prop.isImportedPrimaryKey()) {
|
||||
sj.add(prop.name());
|
||||
}
|
||||
}
|
||||
return sj.toString().intern();
|
||||
}
|
||||
public String idSelect() {
|
||||
if (idBinder == null) throw new UnsupportedOperationException();
|
||||
return idBinder.idSelect();
|
||||
}
|
||||
|
||||
public boolean isJacksonCorePresent() {
|
||||
@@ -543,10 +530,10 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
unidirectional.initialise(initContext);
|
||||
}
|
||||
idBinder.initialise();
|
||||
idBinderInLHSSql = idBinder.getBindIdInSql(baseTableAlias);
|
||||
idBinderIdSql = idBinder.getBindIdSql(baseTableAlias);
|
||||
String idBinderInLHSSqlNoAlias = idBinder.getBindIdInSql(null);
|
||||
String idEqualsSql = idBinder.getBindIdSql(null);
|
||||
idBinderInLHSSql = idBinder.bindInSql(baseTableAlias);
|
||||
idBinderIdSql = idBinder.bindEqSql(baseTableAlias);
|
||||
String idBinderInLHSSqlNoAlias = idBinder.bindInSql(null);
|
||||
String idEqualsSql = idBinder.bindEqSql(null);
|
||||
deleteByIdSql = "delete from " + baseTable + " where " + idEqualsSql;
|
||||
whereIdInSql = " where " + idBinderInLHSSqlNoAlias + " ";
|
||||
deleteByIdInSql = "delete from " + baseTable + whereIdInSql;
|
||||
@@ -868,10 +855,10 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
private SqlUpdate deleteByIdList(List<Object> idList, DeleteMode mode) {
|
||||
String baseSql = mode.isHard() ? deleteByIdInSql : softDeleteByIdInSql;
|
||||
StringBuilder sb = new StringBuilder(baseSql);
|
||||
String inClause = idBinder.getIdInValueExprDelete(idList.size());
|
||||
String inClause = idBinder.idInValueExprDelete(idList.size());
|
||||
sb.append(inClause);
|
||||
DefaultSqlUpdate delete = new DefaultSqlUpdate(sb.toString());
|
||||
idBinder.addIdInBindValues(delete, idList);
|
||||
idBinder.addBindValues(delete, idList);
|
||||
return delete;
|
||||
}
|
||||
|
||||
@@ -882,7 +869,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
private SqlUpdate deleteById(Object id, DeleteMode mode) {
|
||||
String baseSql = mode.isHard() ? deleteByIdSql : softDeleteByIdSql;
|
||||
DefaultSqlUpdate sqlDelete = new DefaultSqlUpdate(baseSql);
|
||||
Object[] bindValues = idBinder.getBindValues(id);
|
||||
Object[] bindValues = idBinder.bindValues(id);
|
||||
for (Object bindValue : bindValues) {
|
||||
sqlDelete.setParameter(bindValue);
|
||||
}
|
||||
@@ -1537,7 +1524,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
* Return a Sql update statement to set the importedId value (deferred execution).
|
||||
*/
|
||||
public String updateImportedIdSql(ImportedId prop) {
|
||||
return "update " + baseTable + " set " + prop.importedIdClause() + " where " + idBinder.getBindIdSql(null);
|
||||
return "update " + baseTable + " set " + prop.importedIdClause() + " where " + idBinder.bindEqSql(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1631,7 +1618,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
* Return a raw expression for 'where parent id in ...' clause.
|
||||
*/
|
||||
String parentIdInExpr(int parentIdSize, String rawWhere) {
|
||||
String inClause = idBinder.getIdInValueExpr(false, parentIdSize);
|
||||
String inClause = idBinder.idInValueExpr(false, parentIdSize);
|
||||
return idBinder.isIdInExpandedForm() ? inClause : rawWhere + inClause;
|
||||
}
|
||||
|
||||
@@ -1684,7 +1671,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
if (alias == null) {
|
||||
return idBinderIdSql;
|
||||
} else {
|
||||
return idBinder.getBindIdSql(alias);
|
||||
return idBinder.bindEqSql(alias);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1710,7 +1697,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
* This 'flattens' any EmbeddedId or multiple Id property cases.
|
||||
*/
|
||||
public Object[] bindIdValues(Object idValue) {
|
||||
return idBinder.getBindValues(idValue);
|
||||
return idBinder.bindValues(idValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2118,7 +2105,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
* The usage is to provide simple id types for JSON processing (for embeddedId's).
|
||||
*/
|
||||
public Object idForJson(Object bean) {
|
||||
return idBinder.getIdForJson((EntityBean) bean);
|
||||
return idBinder.convertForJson((EntityBean) bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2127,7 +2114,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
* The usage is to provide simple id types for JSON processing (for embeddedId's).
|
||||
*/
|
||||
Object convertIdFromJson(Object idValue) {
|
||||
return idBinder.convertIdFromJson(idValue);
|
||||
return idBinder.convertFromJson(idValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2135,7 +2122,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
* included in the query.
|
||||
*/
|
||||
public String defaultOrderBy() {
|
||||
return idBinder.getDefaultOrderBy();
|
||||
return idBinder.orderBy();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2450,9 +2437,13 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
|
||||
BeanProperty _findBeanProperty(String propName) {
|
||||
BeanProperty prop = propMap.get(propName);
|
||||
if (prop == null && inheritInfo != null) {
|
||||
// search in sub types...
|
||||
return inheritInfo.findSubTypeProperty(propName);
|
||||
if (prop == null) {
|
||||
if ("_$IdClass$".equals(propName)) {
|
||||
return idProperty;
|
||||
} else if (inheritInfo != null) {
|
||||
// search in sub types...
|
||||
return inheritInfo.findSubTypeProperty(propName);
|
||||
}
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
@@ -3057,10 +3048,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
return idProperty;
|
||||
}
|
||||
|
||||
public String idSelect() {
|
||||
return idSelect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this bean should be inserted rather than updated.
|
||||
*
|
||||
|
||||
+1
-1
@@ -552,7 +552,7 @@ final class BeanDescriptorCacheHelp<T> {
|
||||
if (val == null) {
|
||||
return null;
|
||||
}
|
||||
sb.append(val).append(";");
|
||||
sb.append(val).append(';');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -23,11 +23,6 @@ abstract class BeanDescriptorElement<T> extends BeanDescriptor<T> {
|
||||
this.elementHelp = elementHelp;
|
||||
}
|
||||
|
||||
@Override
|
||||
String initIdSelect() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private String shortName(String name) {
|
||||
int pos = name.lastIndexOf('.');
|
||||
if (pos > 1) {
|
||||
|
||||
@@ -105,7 +105,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
private final String asOfViewSuffix;
|
||||
private final boolean jacksonCorePresent;
|
||||
private final int queryPlanTTLSeconds;
|
||||
private final BindMaxLength bindMaxLength;
|
||||
private int entityBeanCount;
|
||||
private List<BeanDescriptor<?>> immutableDescriptorList;
|
||||
/**
|
||||
@@ -160,19 +159,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
this.changeLogListener = config.changeLogListener(bootupClasses.getChangeLogListener());
|
||||
this.changeLogRegister = config.changeLogRegister(bootupClasses.getChangeLogRegister());
|
||||
this.jacksonCorePresent = config.isJacksonCorePresent();
|
||||
this.bindMaxLength = initMaxLength();
|
||||
}
|
||||
|
||||
BindMaxLength initMaxLength() {
|
||||
LengthCheck lengthCheck = this.config.getLengthCheck();
|
||||
switch (lengthCheck) {
|
||||
case OFF:
|
||||
return null;
|
||||
case UTF8:
|
||||
return BindMaxLength.ofUtf8();
|
||||
default:
|
||||
return BindMaxLength.ofStandard();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -532,7 +518,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
IdBinder idBinder = d.idBinder();
|
||||
if (idBinder instanceof IdBinderEmbedded) {
|
||||
IdBinderEmbedded embId = (IdBinderEmbedded) idBinder;
|
||||
BeanDescriptor<?> idBeanDescriptor = embId.getIdBeanDescriptor();
|
||||
BeanDescriptor<?> idBeanDescriptor = embId.descriptor();
|
||||
Class<?> idType = idBeanDescriptor.type();
|
||||
try {
|
||||
idType.getDeclaredMethod("hashCode");
|
||||
@@ -1516,10 +1502,6 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
return list;
|
||||
}
|
||||
|
||||
public BindMaxLength bindMaxLength() {
|
||||
return bindMaxLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparator to sort the BeanDescriptors by name.
|
||||
*/
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.Query;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.BeanCollectionAdd;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.common.BeanList;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -67,12 +67,6 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
|
||||
return beanList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
|
||||
BeanList<?> newBeanList = (BeanList<?>) server.findList(query, t);
|
||||
refresh(newBeanList, parentBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void refresh(BeanCollection<?> bc, EntityBean parentBean) {
|
||||
BeanList<?> newBeanList = (BeanList<?>) bc;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.Query;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.BeanCollectionAdd;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.common.BeanMap;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -113,12 +113,6 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
|
||||
return beanMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
|
||||
BeanMap<?, ?> newBeanMap = (BeanMap<?, ?>) server.findMap(query, t);
|
||||
refresh(newBeanMap, parentBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void refresh(BeanCollection<?> bc, EntityBean parentBean) {
|
||||
BeanMap<?, ?> newBeanMap = (BeanMap<?, ?>) bc;
|
||||
|
||||
@@ -69,7 +69,7 @@ public final class BeanNaturalKey {
|
||||
public String calculateKey(Map<String, Object> map) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (BeanProperty prop : props) {
|
||||
sb.append(prop.naturalKeyVal(map)).append(";");
|
||||
sb.append(prop.naturalKeyVal(map)).append(';');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import io.ebean.DataIntegrityException;
|
||||
import io.ebean.ValuePair;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.bean.EntityBeanIntercept;
|
||||
import io.ebean.bean.MutableValueInfo;
|
||||
import io.ebean.bean.PersistenceContext;
|
||||
import io.ebean.config.EncryptKey;
|
||||
import io.ebean.config.LengthCheck;
|
||||
import io.ebean.config.dbplatform.DbEncryptFunction;
|
||||
import io.ebean.config.dbplatform.DbPlatformType;
|
||||
import io.ebean.config.dbplatform.ExtraDbTypes;
|
||||
import io.ebean.core.type.DataReader;
|
||||
import io.ebean.core.type.DocPropertyType;
|
||||
import io.ebean.core.type.InputStreamInfo;
|
||||
import io.ebean.core.type.ScalarType;
|
||||
import io.ebean.plugin.Property;
|
||||
import io.ebean.text.StringParser;
|
||||
@@ -50,7 +46,6 @@ import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
@@ -171,7 +166,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
*/
|
||||
private final String dbComment;
|
||||
private final DbEncryptFunction dbEncryptFunction;
|
||||
private final BindMaxLength bindMaxLength;
|
||||
private int deployOrder;
|
||||
final boolean jsonSerialize;
|
||||
final boolean jsonDeserialize;
|
||||
@@ -264,7 +258,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
}
|
||||
this.jsonSerialize = deploy.isJsonSerialize();
|
||||
this.jsonDeserialize = deploy.isJsonDeserialize();
|
||||
this.bindMaxLength = deploy.bindMaxLength();
|
||||
}
|
||||
|
||||
private String tableAliasIntern(BeanDescriptor<?> descriptor, String s, boolean dbEncrypted, String dbColumn) {
|
||||
@@ -352,7 +345,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
this.elPlaceHolderEncrypted = override.replace(source.elPlaceHolderEncrypted, source.dbColumn);
|
||||
this.jsonSerialize = source.jsonSerialize;
|
||||
this.jsonDeserialize = source.jsonDeserialize;
|
||||
this.bindMaxLength = source.bindMaxLength;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -464,7 +456,8 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
@Override
|
||||
public void appendFrom(DbSqlContext ctx, SqlJoinType joinType, String manyWhere) {
|
||||
if (formula && sqlFormulaJoin != null) {
|
||||
ctx.appendFormulaJoin(sqlFormulaJoin, joinType, manyWhere);
|
||||
String alias = ctx.tableAliasManyWhere(manyWhere);
|
||||
ctx.appendFormulaJoin(sqlFormulaJoin, joinType, alias);
|
||||
} else if (secondaryTableJoin != null) {
|
||||
String relativePrefix = ctx.relativePrefix(secondaryTableJoinPrefix);
|
||||
secondaryTableJoin.addJoin(joinType, relativePrefix, ctx);
|
||||
@@ -562,18 +555,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void bind(DataBind b, Object value) throws SQLException {
|
||||
scalarType.bind(b, value);
|
||||
if (bindMaxLength != null) {
|
||||
Object obj = b.popLastObject();
|
||||
long length = bindMaxLength.length(dbLength, obj);
|
||||
if (length > dbLength) {
|
||||
b.closeInputStreams();
|
||||
String s = String.valueOf(value); // take original bind value here.
|
||||
if (s.length() > 50) {
|
||||
s = s.substring(0, 47) + "...";
|
||||
}
|
||||
throw new DataIntegrityException("Cannot bind value '" + s + "' (effective length=" + length + ") to column '" + dbColumn + "' (length=" + dbLength + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings(value = "unchecked")
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.Query;
|
||||
import io.ebean.SqlUpdate;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.core.type.DocPropertyType;
|
||||
import io.ebean.text.PathProperties;
|
||||
@@ -122,7 +124,7 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
|
||||
targetInheritInfo = targetDescriptor.inheritInfo();
|
||||
saveRecurseSkippable = targetDescriptor.isSaveRecurseSkippable();
|
||||
if (!targetIdBinder.isComplexId()) {
|
||||
targetIdProperty = targetIdBinder.getIdProperty();
|
||||
targetIdProperty = targetIdBinder.idSelect();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -570,4 +572,26 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
|
||||
+ " or a @JoinColumn needs an explicit referencedColumnName specified?";
|
||||
throw new PersistenceException(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create SqlUpdate statement to delete all child beans of the parent <code>id</code>.
|
||||
*/
|
||||
public abstract SqlUpdate deleteByParentId(Object id);
|
||||
|
||||
/**
|
||||
* Create SqlUpdate statement to delete all child beans of the parent ids in <code>idList</code>.
|
||||
*/
|
||||
public abstract SqlUpdate deleteByParentIdList(List<Object> idList);
|
||||
|
||||
/**
|
||||
* Find child beans of the parent <code>id</code>.
|
||||
*/
|
||||
public abstract List<Object> findIdsByParentId(Object id, Transaction transaction, boolean includeSoftDeletes);
|
||||
|
||||
/**
|
||||
* Find child beans of the parent ids in <code>idList</code>.
|
||||
*/
|
||||
public abstract List<Object> findIdsByParentIdList(List<Object> idList, Transaction transaction, boolean includeSoftDeletes);
|
||||
|
||||
}
|
||||
|
||||
|
||||
+33
-18
@@ -296,23 +296,38 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
// do not add to the selectChain at the top level of the Many bean
|
||||
}
|
||||
|
||||
public SpiSqlUpdate deleteByParentId(Object parentId, List<Object> parentIdist) {
|
||||
if (parentId != null) {
|
||||
return sqlHelp.deleteByParentId(parentId);
|
||||
} else {
|
||||
return sqlHelp.deleteByParentIdList(parentIdist);
|
||||
}
|
||||
@Override
|
||||
public SpiSqlUpdate deleteByParentId(Object parentId) {
|
||||
return sqlHelp.deleteByParentId(parentId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpiSqlUpdate deleteByParentIdList(List<Object> parentIdist) {
|
||||
return sqlHelp.deleteByParentIdList(parentIdist);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the Id's of detail beans given a parent Id
|
||||
*/
|
||||
@Override
|
||||
public List<Object> findIdsByParentId(Object parentId, Transaction t, boolean includeSoftDeletes) {
|
||||
return sqlHelp.findIdsByParentId(parentId, t, includeSoftDeletes, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the Id's of detail beans given a parent Id or list of parent Id's.
|
||||
* Find the Id's of detail beans given a parent Id and optionally exclude detail IDs
|
||||
*/
|
||||
public List<Object> findIdsByParentId(Object parentId, List<Object> parentIdList, Transaction t, List<Object> excludeDetailIds, boolean hard) {
|
||||
if (parentId != null) {
|
||||
return sqlHelp.findIdsByParentId(parentId, t, excludeDetailIds, hard);
|
||||
} else {
|
||||
return sqlHelp.findIdsByParentIdList(parentIdList, t, excludeDetailIds, hard);
|
||||
}
|
||||
public List<Object> findIdsByParentId(Object parentId, Transaction t, boolean includeSoftDeletes, Set<Object> excludeDetailIds) {
|
||||
return sqlHelp.findIdsByParentId(parentId, t, includeSoftDeletes, excludeDetailIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the Id's of detail beans given a list of parent Id's.
|
||||
*/
|
||||
@Override
|
||||
public List<Object> findIdsByParentIdList(List<Object> parentIdList, Transaction t, boolean includeSoftDeletes) {
|
||||
return sqlHelp.findIdsByParentIdList(parentIdList, t, includeSoftDeletes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -458,7 +473,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
*/
|
||||
@Override
|
||||
public Object[] assocIdValues(EntityBean bean) {
|
||||
return targetDescriptor.idBinder().getIdValues(bean);
|
||||
return targetDescriptor.idBinder().values(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -466,7 +481,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
*/
|
||||
@Override
|
||||
public String assocIdExpression(String prefix, String operator) {
|
||||
return targetDescriptor.idBinder().getAssocOneIdExpr(prefix, operator);
|
||||
return targetDescriptor.idBinder().assocExpr(prefix, operator);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -474,7 +489,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
*/
|
||||
@Override
|
||||
public String assocIdInValueExpr(boolean not, int size) {
|
||||
return targetDescriptor.idBinder().getIdInValueExpr(not, size);
|
||||
return targetDescriptor.idBinder().idInValueExpr(not, size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -482,7 +497,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
*/
|
||||
@Override
|
||||
public String assocIdInExpr(String prefix) {
|
||||
return targetDescriptor.idBinder().getAssocIdInExpr(prefix);
|
||||
return targetDescriptor.idBinder().assocInExpr(prefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -740,7 +755,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
throw new PersistenceException(from + ": Could not find mapKey property " + mapKey + " on " + to);
|
||||
}
|
||||
|
||||
public IntersectionRow buildManyDeleteChildren(EntityBean parentBean, List<Object> excludeDetailIds) {
|
||||
public IntersectionRow buildManyDeleteChildren(EntityBean parentBean, Set<Object> excludeDetailIds) {
|
||||
IntersectionRow row = new IntersectionRow(tableJoin.getTable(), targetDescriptor);
|
||||
if (excludeDetailIds != null && !excludeDetailIds.isEmpty()) {
|
||||
row.setExcludeIds(excludeDetailIds, targetDescriptor());
|
||||
|
||||
+110
-77
@@ -4,12 +4,13 @@ import io.ebean.Transaction;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.SpiSqlUpdate;
|
||||
import io.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
import io.ebeaninternal.server.deploy.visitor.BaseTablePropertyVisitor;
|
||||
import io.ebeaninternal.server.deploy.visitor.VisitProperties;
|
||||
import io.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
import io.ebeaninternal.server.util.Str;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
class BeanPropertyAssocManySqlHelp<T> {
|
||||
|
||||
@@ -21,13 +22,15 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
private final String deleteByParentIdSql;
|
||||
private final String deleteByParentIdInSql;
|
||||
private final String elementCollectionInsertSql;
|
||||
private final boolean idInExpandedForm;
|
||||
|
||||
BeanPropertyAssocManySqlHelp(BeanPropertyAssocMany<T> many, ExportedProperty[] exportedProperties) {
|
||||
this.many = many;
|
||||
this.exportedProperties = exportedProperties;
|
||||
this.hasJoinTable = many.hasJoinTable();
|
||||
this.descriptor = many.descriptor();
|
||||
this.exportedPropertyBindProto = deriveExportedPropertyBindProto();
|
||||
this.exportedPropertyBindProto = initExportedBindProto();
|
||||
this.idInExpandedForm = descriptor.idBinder().isIdInExpandedForm();
|
||||
|
||||
String delStmt;
|
||||
if (hasJoinTable) {
|
||||
@@ -35,8 +38,8 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
} else {
|
||||
delStmt = "delete from " + many.targetTable() + " where ";
|
||||
}
|
||||
deleteByParentIdSql = delStmt + deriveWhereParentIdSql(false, "");
|
||||
deleteByParentIdInSql = delStmt + deriveWhereParentIdSql(true, "");
|
||||
deleteByParentIdSql = delStmt + rawParentIdEQ("");
|
||||
deleteByParentIdInSql = delStmt;
|
||||
if (many.isElementCollection()) {
|
||||
elementCollectionInsertSql = elementCollectionInsert();
|
||||
} else {
|
||||
@@ -45,7 +48,7 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
}
|
||||
|
||||
private String elementCollectionInsert() {
|
||||
StringBuilder sb = new StringBuilder(200);
|
||||
final StringBuilder sb = new StringBuilder(200);
|
||||
sb.append("insert into ").append(many.targetTable()).append(" (");
|
||||
append(sb);
|
||||
|
||||
@@ -54,7 +57,7 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
sb.append(") values (");
|
||||
appendBind(sb, exportedProperties.length, true);
|
||||
appendBind(sb, cols.colCount, false);
|
||||
sb.append(")");
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -73,7 +76,7 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
|
||||
@Override
|
||||
public void visitEmbeddedScalar(BeanProperty p, BeanPropertyAssocOne<?> embedded) {
|
||||
sb.append(",").append(p.dbColumn());
|
||||
sb.append(',').append(p.dbColumn());
|
||||
colCount++;
|
||||
}
|
||||
|
||||
@@ -84,7 +87,7 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
|
||||
@Override
|
||||
public void visitScalar(BeanProperty p, boolean allowNonNull) {
|
||||
sb.append(",").append(p.dbColumn());
|
||||
sb.append(',').append(p.dbColumn());
|
||||
colCount++;
|
||||
}
|
||||
|
||||
@@ -96,14 +99,14 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
|
||||
String lazyFetchOrderBy(String fetchOrderBy) {
|
||||
// derive lazyFetchOrderBy
|
||||
StringBuilder sb = new StringBuilder(50);
|
||||
final String fkTableAlias = hasJoinTable ? "int_" : "t0";
|
||||
final var sb = new StringBuilder(50);
|
||||
for (int i = 0; i < exportedProperties.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
// these fk columns are either on the intersection (int_) or base table (t0)
|
||||
String fkTableAlias = hasJoinTable ? "int_" : "t0";
|
||||
sb.append(fkTableAlias).append(".").append(exportedProperties[i].getForeignDbColumn());
|
||||
sb.append(fkTableAlias).append('.').append(exportedProperties[i].getForeignDbColumn());
|
||||
}
|
||||
sb.append(", ").append(fetchOrderBy);
|
||||
return sb.toString().trim();
|
||||
@@ -113,56 +116,50 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
* Add a where clause to the query for a given list of parent Id's.
|
||||
*/
|
||||
void addWhereParentIdIn(SpiQuery<?> query, List<Object> parentIds) {
|
||||
String tableAlias = hasJoinTable ? "int_." : "t0.";
|
||||
final String tableAlias = hasJoinTable ? "int_." : "t0.";
|
||||
if (hasJoinTable) {
|
||||
query.setM2MIncludeJoin(many.inverseJoin);
|
||||
}
|
||||
String rawWhere = deriveWhereParentIdSql(true, tableAlias);
|
||||
String expr = descriptor.parentIdInExpr(parentIds.size(), rawWhere);
|
||||
many.bindParentIdsIn(expr, parentIds, query);
|
||||
final String rawWhere = rawParentIdIN(tableAlias, parentIds.size());
|
||||
many.bindParentIdsIn(rawWhere, parentIds, query);
|
||||
}
|
||||
|
||||
List<Object> findIdsByParentId(Object parentId, Transaction t, List<Object> excludeDetailIds, boolean hard) {
|
||||
String rawWhere = deriveWhereParentIdSql(false, "");
|
||||
SpiEbeanServer server = descriptor.ebeanServer();
|
||||
SpiQuery<?> q = many.newQuery(server);
|
||||
many.bindParentIdEq(rawWhere, parentId, q);
|
||||
if (hard) {
|
||||
q.setIncludeSoftDeletes();
|
||||
List<Object> findIdsByParentId(Object parentId, Transaction t, boolean includeSoftDeletes, Set<Object> excludeDetailIds) {
|
||||
final SpiEbeanServer server = descriptor.ebeanServer();
|
||||
final SpiQuery<?> query = many.newQuery(server);
|
||||
query.usingTransaction(t);
|
||||
many.bindParentIdEq(rawParentIdEQ(""), parentId, query);
|
||||
if (includeSoftDeletes) {
|
||||
query.setIncludeSoftDeletes();
|
||||
}
|
||||
|
||||
if (excludeDetailIds != null && !excludeDetailIds.isEmpty()) {
|
||||
q.where().not(q.getExpressionFactory().idIn(excludeDetailIds));
|
||||
query.where().not(query.getExpressionFactory().idIn(excludeDetailIds));
|
||||
}
|
||||
return server.findIds(q, t);
|
||||
return server.findIds(query);
|
||||
}
|
||||
|
||||
List<Object> findIdsByParentIdList(List<Object> parentIds, Transaction t, List<Object> excludeDetailIds, boolean hard) {
|
||||
String rawWhere = deriveWhereParentIdSql(true, "");
|
||||
String inClause = buildInClauseBinding(parentIds.size(), exportedPropertyBindProto);
|
||||
String expr = rawWhere + inClause;
|
||||
|
||||
SpiEbeanServer server = descriptor.ebeanServer();
|
||||
SpiQuery<?> q = many.newQuery(server);
|
||||
//Query<?> q = server.find(propertyType);
|
||||
many.bindParentIdsIn(expr, parentIds, q);
|
||||
if (hard) {
|
||||
q.setIncludeSoftDeletes();
|
||||
List<Object> findIdsByParentIdList(List<Object> parentIds, Transaction t, boolean includeSoftDeletes) {
|
||||
final SpiEbeanServer server = descriptor.ebeanServer();
|
||||
final SpiQuery<?> query = many.newQuery(server);
|
||||
query.usingTransaction(t);
|
||||
many.bindParentIdsIn(rawParentIdIN("", parentIds.size()), parentIds, query);
|
||||
if (includeSoftDeletes) {
|
||||
query.setIncludeSoftDeletes();
|
||||
}
|
||||
if (excludeDetailIds != null && !excludeDetailIds.isEmpty()) {
|
||||
q.where().not(q.getExpressionFactory().idIn(excludeDetailIds));
|
||||
}
|
||||
return server.findIds(q, t);
|
||||
return server.findIds(query);
|
||||
}
|
||||
|
||||
SpiSqlUpdate deleteByParentId(Object parentId) {
|
||||
DefaultSqlUpdate sqlDelete = new DefaultSqlUpdate(deleteByParentIdSql);
|
||||
final var sqlDelete = new DefaultSqlUpdate(deleteByParentIdSql);
|
||||
many.bindParentId(sqlDelete, parentId);
|
||||
return sqlDelete;
|
||||
}
|
||||
|
||||
SpiSqlUpdate deleteByParentIdList(List<Object> parentIds) {
|
||||
String sql = Str.add(deleteByParentIdInSql, buildInClauseBinding(parentIds.size(), exportedPropertyBindProto));
|
||||
DefaultSqlUpdate delete = new DefaultSqlUpdate(sql);
|
||||
final String rawWhere = rawParentIdIN("", parentIds.size());
|
||||
final String sql = Str.add(deleteByParentIdInSql, rawWhere);
|
||||
final var delete = new DefaultSqlUpdate(sql);
|
||||
many.bindParentIds(delete, parentIds);
|
||||
return delete;
|
||||
}
|
||||
@@ -170,73 +167,109 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
private void appendBind(StringBuilder sb, int count, boolean skipComma) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!skipComma || i > 0) {
|
||||
sb.append(",");
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append("?");
|
||||
sb.append('?');
|
||||
}
|
||||
}
|
||||
|
||||
private void append(StringBuilder sb) {
|
||||
for (int i = 0; i < exportedProperties.length; i++) {
|
||||
String fkColumn = exportedProperties[i].getForeignDbColumn();
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(fkColumn);
|
||||
sb.append(exportedProperties[i].getForeignDbColumn());
|
||||
}
|
||||
}
|
||||
|
||||
private String deriveWhereParentIdSql(boolean inClause, String tableAlias) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (inClause) {
|
||||
sb.append("(");
|
||||
private String rawParentIdIN(String tableAlias, int size) {
|
||||
if (idInExpandedForm) {
|
||||
return rawParentIdExpanded(tableAlias, size);
|
||||
} else {
|
||||
return rawParentIdStandard(tableAlias, size);
|
||||
}
|
||||
}
|
||||
|
||||
private String rawParentIdStandard(String tableAlias, int size) {
|
||||
if (descriptor.isSimpleId()) {
|
||||
return rawParentIdMultiBinder(tableAlias, size);
|
||||
}
|
||||
final var sb = new StringBuilder(100 + size * exportedPropertyBindProto.length());
|
||||
sb.append('(');
|
||||
for (int i = 0; i < exportedProperties.length; i++) {
|
||||
String fkColumn = exportedProperties[i].getForeignDbColumn();
|
||||
if (i > 0) {
|
||||
sb.append(inClause ? "," : " and ");
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(tableAlias).append(fkColumn);
|
||||
if (!inClause) {
|
||||
sb.append("=? ");
|
||||
}
|
||||
}
|
||||
if (inClause) {
|
||||
sb.append(")");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String buildInClauseBinding(int size, String bindProto) {
|
||||
if (descriptor.isSimpleId()) {
|
||||
return descriptor.idBinder().getIdInValueExpr(false, size);
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(10 + (size * (bindProto.length() + 1)));
|
||||
sb.append(" in");
|
||||
sb.append(" (");
|
||||
sb.append(") in (");
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(bindProto);
|
||||
sb.append(exportedPropertyBindProto);
|
||||
}
|
||||
sb.append(") ");
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String deriveExportedPropertyBindProto() {
|
||||
/**
|
||||
* Potentially a MultiValue binder like Postgres ANY Array binding.
|
||||
*/
|
||||
private String rawParentIdMultiBinder(String tableAlias, int size) {
|
||||
final String property = '(' + tableAlias + exportedProperties[0].getForeignDbColumn() + ')';
|
||||
final String inValueExpr = descriptor.idBinder().idInValueExpr(false, size);
|
||||
return property + inValueExpr;
|
||||
}
|
||||
|
||||
private String rawParentIdExpanded(String tableAlias, int size) {
|
||||
final String proto = parentIdExpandedProto(tableAlias);
|
||||
final var result = new StringBuilder(size * (proto.length() + 2) + 10).append('(');
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i > 0) {
|
||||
result.append(" or ");
|
||||
}
|
||||
result.append(proto);
|
||||
}
|
||||
return result.append(')').toString();
|
||||
}
|
||||
|
||||
private String parentIdExpandedProto(String tableAlias) {
|
||||
final var sb = new StringBuilder(60).append('(');
|
||||
for (int i = 0; i < exportedProperties.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(" and ");
|
||||
}
|
||||
sb.append(tableAlias).append(exportedProperties[i].getForeignDbColumn()).append("=?");
|
||||
}
|
||||
return sb.append(')').toString();
|
||||
}
|
||||
|
||||
private String rawParentIdEQ(String tableAlias) {
|
||||
final var sb = new StringBuilder(80);
|
||||
for (int i = 0; i < exportedProperties.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(" and ");
|
||||
}
|
||||
sb.append(tableAlias).append(exportedProperties[i].getForeignDbColumn()).append("=?");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String initExportedBindProto() {
|
||||
if (exportedProperties.length == 1) {
|
||||
return "?";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("(");
|
||||
final var sb = new StringBuilder(exportedProperties.length * 2 + 2);
|
||||
sb.append('(');
|
||||
for (int i = 0; i < exportedProperties.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append("?");
|
||||
sb.append('?');
|
||||
}
|
||||
sb.append(")");
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -237,51 +237,49 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
|
||||
return encrypted ? elPlaceHolderEncrypted : elPlaceHolder;
|
||||
}
|
||||
|
||||
public SqlUpdate deleteByParentId(Object parentId, List<Object> parentIdist) {
|
||||
if (parentId != null) {
|
||||
return deleteByParentId(parentId);
|
||||
} else {
|
||||
return deleteByParentIdList(parentIdist);
|
||||
}
|
||||
}
|
||||
|
||||
private SqlUpdate deleteByParentIdList(List<Object> parentIds) {
|
||||
String sql = deleteByParentIdInSql + targetIdBinder.getIdInValueExpr(false, parentIds.size());
|
||||
@Override
|
||||
public SqlUpdate deleteByParentIdList(List<Object> parentIds) {
|
||||
String sql = deleteByParentIdInSql + targetIdBinder.idInValueExpr(false, parentIds.size());
|
||||
DefaultSqlUpdate delete = new DefaultSqlUpdate(sql);
|
||||
bindParentIds(delete, parentIds);
|
||||
return delete;
|
||||
}
|
||||
|
||||
private SqlUpdate deleteByParentId(Object parentId) {
|
||||
@Override
|
||||
public SqlUpdate deleteByParentId(Object parentId) {
|
||||
DefaultSqlUpdate delete = new DefaultSqlUpdate(deleteByParentIdSql);
|
||||
bindParentId(delete, parentId);
|
||||
return delete;
|
||||
}
|
||||
|
||||
public List<Object> findIdsByParentId(Object parentId, List<Object> parentIds, Transaction t) {
|
||||
if (parentId != null) {
|
||||
return findIdsByParentId(parentId, t);
|
||||
} else {
|
||||
return findIdsByParentIdList(parentIds, t);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Object> findIdsByParentId(Object parentId, Transaction t) {
|
||||
@Override
|
||||
public List<Object> findIdsByParentId(Object parentId, Transaction t, boolean includeSoftDeletes) {
|
||||
String rawWhere = deriveWhereParentIdSql(false);
|
||||
SpiEbeanServer server = server();
|
||||
Query<?> q = server.find(type());
|
||||
SpiQuery<?> q = server.createQuery(type());
|
||||
q.usingTransaction(t);
|
||||
bindParentIdEq(rawWhere, parentId, q);
|
||||
return server.findIds(q, t);
|
||||
if (includeSoftDeletes) {
|
||||
q.setIncludeSoftDeletes();
|
||||
}
|
||||
return server.findIds(q);
|
||||
}
|
||||
|
||||
private List<Object> findIdsByParentIdList(List<Object> parentIds, Transaction t) {
|
||||
@Override
|
||||
public List<Object> findIdsByParentIdList(List<Object> parentIds, Transaction t, boolean includeSoftDeletes) {
|
||||
String rawWhere = deriveWhereParentIdSql(true);
|
||||
String inClause = idBinder().getIdInValueExpr(false, parentIds.size());
|
||||
String inClause = idBinder().idInValueExpr(false, parentIds.size());
|
||||
String expr = rawWhere + inClause;
|
||||
SpiEbeanServer server = server();
|
||||
Query<?> q = server.find(type());
|
||||
SpiQuery<?> q = server.createQuery(type());
|
||||
q.usingTransaction(t);
|
||||
bindParentIdsIn(expr, parentIds, q);
|
||||
return server.findIds(q, t);
|
||||
if (includeSoftDeletes) {
|
||||
q.setIncludeSoftDeletes();
|
||||
}
|
||||
return server.findIds(q);
|
||||
}
|
||||
|
||||
void addFkey() {
|
||||
@@ -487,7 +485,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
|
||||
*/
|
||||
@Override
|
||||
public Object[] assocIdValues(EntityBean bean) {
|
||||
return targetDescriptor.idBinder().getIdValues(bean);
|
||||
return targetDescriptor.idBinder().values(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -495,7 +493,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
|
||||
*/
|
||||
@Override
|
||||
public String assocIdExpression(String prefix, String operator) {
|
||||
return targetDescriptor.idBinder().getAssocOneIdExpr(prefix, operator);
|
||||
return targetDescriptor.idBinder().assocExpr(prefix, operator);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -503,7 +501,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
|
||||
*/
|
||||
@Override
|
||||
public String assocIdInValueExpr(boolean not, int size) {
|
||||
return targetDescriptor.idBinder().getIdInValueExpr(not, size);
|
||||
return targetDescriptor.idBinder().idInValueExpr(not, size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -511,7 +509,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
|
||||
*/
|
||||
@Override
|
||||
public String assocIdInExpr(String prefix) {
|
||||
return targetDescriptor.idBinder().getAssocIdInExpr(prefix);
|
||||
return targetDescriptor.idBinder().assocInExpr(prefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -613,12 +611,24 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add table join with explicit table alias.
|
||||
*/
|
||||
@Override
|
||||
public SqlJoinType addJoin(SqlJoinType joinType, String a1, String a2, DbSqlContext ctx) {
|
||||
if (sqlFormulaJoin != null) {
|
||||
ctx.appendFormulaJoin(sqlFormulaJoin, joinType, a1);
|
||||
}
|
||||
return super.addJoin(joinType, a1, a2, ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendFrom(DbSqlContext ctx, SqlJoinType joinType, String manyWhere) {
|
||||
if (!isTransient && !primaryKeyExport) {
|
||||
localHelp.appendFrom(ctx, joinType);
|
||||
if (sqlFormulaJoin != null) {
|
||||
ctx.appendFormulaJoin(sqlFormulaJoin, joinType, manyWhere);
|
||||
String alias = ctx.tableAliasManyWhere(manyWhere);
|
||||
ctx.appendFormulaJoin(sqlFormulaJoin, joinType, alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.Query;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.BeanCollectionAdd;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.common.BeanSet;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -72,12 +72,6 @@ public class BeanSetHelp<T> extends BaseCollectionHelp<T> {
|
||||
return beanSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
|
||||
BeanSet<?> newBeanSet = (BeanSet<?>) server.findSet(query, t);
|
||||
refresh(newBeanSet, parentBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void refresh(BeanCollection<?> bc, EntityBean parentBean) {
|
||||
BeanSet<?> newBeanSet = (BeanSet<?>) bc;
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.core.type.InputStreamInfo;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public interface BindMaxLength {
|
||||
|
||||
/**
|
||||
* Return a UTF8 based implementation.
|
||||
*/
|
||||
static BindMaxLength ofUtf8() {
|
||||
return new UTF8();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a standard implementation.
|
||||
*/
|
||||
static BindMaxLength ofStandard() {
|
||||
return new Standard();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length of the object.
|
||||
*/
|
||||
long length(int dbLength, Object obj);
|
||||
|
||||
final class UTF8 implements BindMaxLength {
|
||||
|
||||
@Override
|
||||
public long length(int dbLength, Object obj) {
|
||||
if (obj instanceof String) {
|
||||
String s = (String) obj;
|
||||
int stringLength = s.length();
|
||||
if (stringLength > dbLength) {
|
||||
return stringLength;
|
||||
} else if (stringLength * 4 <= dbLength) {
|
||||
return -1;
|
||||
} else {
|
||||
return s.getBytes(StandardCharsets.UTF_8).length;
|
||||
}
|
||||
|
||||
} else if (obj instanceof byte[]) {
|
||||
return ((byte[]) obj).length;
|
||||
} else if (obj instanceof InputStreamInfo) {
|
||||
return ((InputStreamInfo) obj).length();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class Standard implements BindMaxLength {
|
||||
|
||||
@Override
|
||||
public long length(int dbLength, Object obj) {
|
||||
if (obj instanceof String) {
|
||||
return ((String) obj).length();
|
||||
} else if (obj instanceof byte[]) {
|
||||
return ((byte[]) obj).length;
|
||||
} else if (obj instanceof InputStreamInfo) {
|
||||
return ((InputStreamInfo) obj).length();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ public interface DbSqlContext {
|
||||
* Append a Sql Formula join. This converts the "${ta}" keyword to the current
|
||||
* table alias.
|
||||
*/
|
||||
void appendFormulaJoin(String sqlFormulaJoin, SqlJoinType joinType, String manyWhere);
|
||||
void appendFormulaJoin(String sqlFormulaJoin, SqlJoinType joinType, String tableAlias);
|
||||
|
||||
/**
|
||||
* Return the current content length.
|
||||
|
||||
@@ -72,7 +72,7 @@ final class DetermineAggPath {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < pos; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(".");
|
||||
sb.append('.');
|
||||
}
|
||||
sb.append(paths[i]);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ final class ExportedProperty {
|
||||
public void appendWhere(StringBuilder sb, String alias, String path) {
|
||||
sb.append(alias).append(foreignDbColumn).append(" = ");
|
||||
if (path != null) {
|
||||
sb.append(path).append(".");
|
||||
sb.append(path).append('.');
|
||||
}
|
||||
sb.append(property.name());
|
||||
}
|
||||
|
||||
@@ -51,9 +51,9 @@ public final class IntersectionBuilder {
|
||||
if (i > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append("?");
|
||||
sb.append('?');
|
||||
}
|
||||
sb.append(")");
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,13 +11,14 @@ import io.ebeaninternal.server.persist.DeleteMode;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public final class IntersectionRow {
|
||||
|
||||
private final String tableName;
|
||||
private final BeanDescriptor<?> targetDescriptor;
|
||||
private final LinkedHashMap<String, Object> values = new LinkedHashMap<>();
|
||||
private List<Object> excludeIds;
|
||||
private Set<Object> excludeIds;
|
||||
private BeanDescriptor<?> excludeDescriptor;
|
||||
|
||||
IntersectionRow(String tableName, BeanDescriptor<?> targetDescriptor) {
|
||||
@@ -33,7 +34,7 @@ public final class IntersectionRow {
|
||||
/**
|
||||
* Set Id's to exclude. This is for deleting non-attached detail Id's.
|
||||
*/
|
||||
void setExcludeIds(List<Object> excludeIds, BeanDescriptor<?> excludeDescriptor) {
|
||||
void setExcludeIds(Set<Object> excludeIds, BeanDescriptor<?> excludeDescriptor) {
|
||||
this.excludeIds = excludeIds;
|
||||
this.excludeDescriptor = excludeDescriptor;
|
||||
}
|
||||
@@ -59,9 +60,9 @@ public final class IntersectionRow {
|
||||
if (i > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append("?");
|
||||
sb.append('?');
|
||||
}
|
||||
sb.append(")");
|
||||
sb.append(')');
|
||||
return new DefaultSqlUpdate(server, sb.toString(), bindParams);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,9 +105,9 @@ public final class TableJoin {
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(30);
|
||||
sb.append(type).append(" ").append(table).append(" ");
|
||||
sb.append(type).append(' ').append(table).append(' ');
|
||||
for (TableJoinColumn column : columns) {
|
||||
sb.append(column).append(" ");
|
||||
sb.append(column).append(' ');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
@@ -160,9 +160,9 @@ public final class TableJoin {
|
||||
if (i > 0) {
|
||||
sb.append(" and ");
|
||||
}
|
||||
sb.append(a1).append(".").append(pair.getLocalDbColumn());
|
||||
sb.append(a1).append('.').append(pair.getLocalDbColumn());
|
||||
sb.append(" = ");
|
||||
sb.append(a2).append(".").append(pair.getForeignDbColumn());
|
||||
sb.append(a2).append('.').append(pair.getForeignDbColumn());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ public interface IdBinder {
|
||||
*/
|
||||
void initialise();
|
||||
|
||||
String idSelect();
|
||||
|
||||
/**
|
||||
* Return true if this is a compound key and must use expanded and or form.
|
||||
*/
|
||||
@@ -41,19 +43,10 @@ public interface IdBinder {
|
||||
*/
|
||||
Object readData(DataInput dataInput) throws IOException;
|
||||
|
||||
/**
|
||||
* Return the name(s) of the Id property(s). Comma delimited if there is more
|
||||
* than one.
|
||||
* <p>
|
||||
* This can be used to include in a query.
|
||||
* </p>
|
||||
*/
|
||||
String getIdProperty();
|
||||
|
||||
/**
|
||||
* Return the Id BeanProperty.
|
||||
*/
|
||||
STreeProperty getBeanProperty();
|
||||
STreeProperty beanProperty();
|
||||
|
||||
/**
|
||||
* Find a BeanProperty that is mapped to the database column.
|
||||
@@ -66,13 +59,25 @@ public interface IdBinder {
|
||||
*/
|
||||
boolean isComplexId();
|
||||
|
||||
/**
|
||||
* Return the number of properties that make up the id.
|
||||
*/
|
||||
default int size() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default order by that may need to be used if the query includes
|
||||
* a many property.
|
||||
*/
|
||||
String getDefaultOrderBy();
|
||||
String orderBy();
|
||||
|
||||
String getOrderBy(String pathPrefix, boolean ascending);
|
||||
String orderBy(String pathPrefix, boolean ascending);
|
||||
|
||||
/**
|
||||
* Return the id values for a given bean.
|
||||
*/
|
||||
Object[] values(EntityBean bean);
|
||||
|
||||
/**
|
||||
* Return the values as an array of scalar bindable values.
|
||||
@@ -84,8 +89,7 @@ public interface IdBinder {
|
||||
* Added primarily for Query.addWhere().add(Expr.idEq()) support.
|
||||
* </p>
|
||||
*/
|
||||
Object[] getBindValues(Object idValue);
|
||||
|
||||
Object[] bindValues(Object idValue);
|
||||
|
||||
/**
|
||||
* For EmbeddedId convert the idValue into a simple map.
|
||||
@@ -94,7 +98,7 @@ public interface IdBinder {
|
||||
* This is used to provide a simple JSON serializable version of the id value.
|
||||
* </p>
|
||||
*/
|
||||
Object getIdForJson(EntityBean idValue);
|
||||
Object convertForJson(EntityBean idValue);
|
||||
|
||||
/**
|
||||
* For EmbeddedId the value is assumed to be a Map and this is
|
||||
@@ -106,12 +110,7 @@ public interface IdBinder {
|
||||
* This is used to provide a simple JSON serializable version of the id value.
|
||||
* </p>
|
||||
*/
|
||||
Object convertIdFromJson(Object value);
|
||||
|
||||
/**
|
||||
* Return the id values for a given bean.
|
||||
*/
|
||||
Object[] getIdValues(EntityBean bean);
|
||||
Object convertFromJson(Object value);
|
||||
|
||||
/**
|
||||
* Build a string of the logical expressions.
|
||||
@@ -119,12 +118,12 @@ public interface IdBinder {
|
||||
* Typically used to build a id = ? string.
|
||||
* </p>
|
||||
*/
|
||||
String getAssocOneIdExpr(String prefix, String operator);
|
||||
String assocExpr(String prefix, String operator);
|
||||
|
||||
/**
|
||||
* Return the logical id in expression taking into account embedded id's.
|
||||
*/
|
||||
String getAssocIdInExpr(String prefix);
|
||||
String assocInExpr(String prefix);
|
||||
|
||||
/**
|
||||
* Binds an id value to a prepared statement.
|
||||
@@ -139,27 +138,27 @@ public interface IdBinder {
|
||||
/**
|
||||
* Binds multiple id value to an update.
|
||||
*/
|
||||
void addIdInBindValues(DefaultSqlUpdate sqlUpdate, Collection<?> ids);
|
||||
void addBindValues(DefaultSqlUpdate sqlUpdate, Collection<?> ids);
|
||||
|
||||
/**
|
||||
* Binds multiple id value to a request.
|
||||
*/
|
||||
void addIdInBindValues(SpiExpressionRequest request, Collection<?> ids);
|
||||
void addBindValues(SpiExpressionRequest request, Collection<?> ids);
|
||||
|
||||
/**
|
||||
* Return the sql for binding the id using an IN clause.
|
||||
*/
|
||||
String getBindIdInSql(String baseTableAlias);
|
||||
String bindInSql(String baseTableAlias);
|
||||
|
||||
/**
|
||||
* Return the binding expression (like "?" or "(?,?)")for the Id.
|
||||
*/
|
||||
String getIdInValueExpr(boolean not, int size);
|
||||
String idInValueExpr(boolean not, int size);
|
||||
|
||||
/**
|
||||
* Same as getIdInValueExpr but for delete by id.
|
||||
*/
|
||||
String getIdInValueExprDelete(int size);
|
||||
String idInValueExprDelete(int size);
|
||||
|
||||
void buildRawSqlSelectChain(String prefix, List<String> selectChain);
|
||||
|
||||
@@ -188,7 +187,7 @@ public interface IdBinder {
|
||||
* Return the sql for binding the id to. This includes table alias and columns
|
||||
* that make up the id.
|
||||
*/
|
||||
String getBindIdSql(String baseTableAlias);
|
||||
String bindEqSql(String baseTableAlias);
|
||||
|
||||
/**
|
||||
* Cast or convert the Id value if necessary and optionally set it.
|
||||
|
||||
@@ -35,7 +35,7 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
public IdBinderEmbedded(boolean idInExpandedForm, BeanPropertyAssocOne<?> embIdProperty) {
|
||||
this.idInExpandedForm = idInExpandedForm;
|
||||
this.embIdProperty = embIdProperty;
|
||||
this.idClass = "_idClass".equals(embIdProperty.name());
|
||||
this.idClass = "_$IdClass$".equals(embIdProperty.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,71 +45,50 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
this.idInValueSql = idInExpandedForm ? idInExpanded() : idInCompressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idSelect() {
|
||||
return embIdProperty.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIdInExpandedForm() {
|
||||
return idInExpandedForm;
|
||||
}
|
||||
|
||||
private String idInExpanded() {
|
||||
StringBuilder sb = new StringBuilder(30);
|
||||
sb.append("(");
|
||||
final StringBuilder sb = new StringBuilder(30);
|
||||
sb.append('(');
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(" and ");
|
||||
}
|
||||
sb.append(idDesc.baseTableAlias()).append(".").append(props[i].dbColumn()).append("=?");
|
||||
sb.append(idDesc.baseTableAlias()).append('.').append(props[i].dbColumn()).append("=?");
|
||||
}
|
||||
sb.append(")");
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String idInCompressed() {
|
||||
StringBuilder sb = new StringBuilder(20).append("(");
|
||||
final StringBuilder sb = new StringBuilder(props.length * 2 + 2).append('(');
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append("?");
|
||||
sb.append('?');
|
||||
}
|
||||
sb.append(")");
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanProperty getBeanProperty() {
|
||||
public BeanProperty beanProperty() {
|
||||
return embIdProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOrderBy(String pathPrefix, boolean ascending) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
if (pathPrefix != null) {
|
||||
sb.append(pathPrefix).append(".");
|
||||
}
|
||||
if (!idClass) {
|
||||
sb.append(embIdProperty.name()).append(".");
|
||||
}
|
||||
sb.append(props[i].name());
|
||||
if (!ascending) {
|
||||
sb.append(" desc");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public BeanDescriptor<?> getIdBeanDescriptor() {
|
||||
public BeanDescriptor<?> descriptor() {
|
||||
return idDesc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdProperty() {
|
||||
return embIdProperty.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildRawSqlSelectChain(String prefix, List<String> selectChain) {
|
||||
if (!idClass) {
|
||||
@@ -136,57 +115,73 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultOrderBy() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
public int size() {
|
||||
return props.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String orderBy() {
|
||||
return orderBy(null, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String orderBy(String pathPrefix, boolean ascending) {
|
||||
final StringBuilder sb = new StringBuilder(100);
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
if (pathPrefix != null) {
|
||||
sb.append(pathPrefix).append('.');
|
||||
}
|
||||
if (!idClass) {
|
||||
sb.append(embIdProperty.name()).append(".");
|
||||
sb.append(embIdProperty.name()).append('.');
|
||||
}
|
||||
sb.append(props[i].name());
|
||||
if (!ascending) {
|
||||
sb.append(" desc");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public BeanProperty[] getProperties() {
|
||||
public BeanProperty[] properties() {
|
||||
return props;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdInValueExprDelete(int size) {
|
||||
public String idInValueExprDelete(int size) {
|
||||
if (size <= 0) {
|
||||
throw new IndexOutOfBoundsException("The size must be at least 1");
|
||||
}
|
||||
if (!idInExpandedForm) {
|
||||
return getIdInValueExpr(false, size);
|
||||
return idInValueExpr(false, size);
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("(");
|
||||
final StringBuilder sb = new StringBuilder(80);
|
||||
sb.append('(');
|
||||
for (int j = 0; j < size; j++) {
|
||||
if (j > 0) {
|
||||
sb.append(" or ");
|
||||
}
|
||||
sb.append("(");
|
||||
sb.append('(');
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(" and ");
|
||||
}
|
||||
sb.append(props[i].dbColumn()).append("=?");
|
||||
}
|
||||
sb.append(")");
|
||||
sb.append(')');
|
||||
}
|
||||
sb.append(") ");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdInValueExpr(boolean not, int size) {
|
||||
public String idInValueExpr(boolean not, int size) {
|
||||
if (size <= 0) {
|
||||
throw new IndexOutOfBoundsException("The size must be at least 1");
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
final StringBuilder sb = new StringBuilder(80);
|
||||
if (not) {
|
||||
sb.append(" not");
|
||||
}
|
||||
@@ -209,20 +204,16 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getIdValues(EntityBean bean) {
|
||||
Object val = embIdProperty.getValue(bean);
|
||||
Object[] bindValues = new Object[props.length];
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
bindValues[i] = props[i].getValue((EntityBean) val);
|
||||
}
|
||||
return bindValues;
|
||||
public Object[] values(EntityBean bean) {
|
||||
return bindValues(embIdProperty.getValue(bean));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getBindValues(Object value) {
|
||||
Object[] bindValues = new Object[props.length];
|
||||
public Object[] bindValues(Object value) {
|
||||
final EntityBean bean = (EntityBean) value;
|
||||
final Object[] bindValues = new Object[props.length];
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
bindValues[i] = props[i].getValue((EntityBean) value);
|
||||
bindValues[i] = props[i].getValue(bean);
|
||||
}
|
||||
return bindValues;
|
||||
}
|
||||
@@ -231,9 +222,9 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
* Convert from embedded bean to Map.
|
||||
*/
|
||||
@Override
|
||||
public Object getIdForJson(EntityBean bean) {
|
||||
EntityBean ebValue = (EntityBean) embIdProperty.getValue(bean);
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
public Object convertForJson(EntityBean bean) {
|
||||
final EntityBean ebValue = (EntityBean) embIdProperty.getValue(bean);
|
||||
final Map<String, Object> map = new LinkedHashMap<>();
|
||||
for (BeanProperty prop : props) {
|
||||
map.put(prop.name(), prop.getValue(ebValue));
|
||||
}
|
||||
@@ -245,9 +236,9 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object convertIdFromJson(Object value) {
|
||||
Map<String, Object> map = (Map<String, Object>) value;
|
||||
EntityBean idValue = idDesc.createEntityBean();
|
||||
public Object convertFromJson(Object value) {
|
||||
final Map<String, Object> map = (Map<String, Object>) value;
|
||||
final EntityBean idValue = idDesc.createEntityBean();
|
||||
for (BeanProperty prop : props) {
|
||||
prop.setValue(idValue, map.get(prop.name()));
|
||||
}
|
||||
@@ -256,42 +247,43 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
|
||||
@Override
|
||||
public void bindId(DefaultSqlUpdate sqlUpdate, Object value) {
|
||||
final EntityBean bean = (EntityBean) value;
|
||||
for (BeanProperty prop : props) {
|
||||
Object embFieldValue = prop.getValue((EntityBean) value);
|
||||
sqlUpdate.setParameter(embFieldValue);
|
||||
sqlUpdate.setParameter(prop.getValue(bean));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindId(DataBind dataBind, Object value) throws SQLException {
|
||||
final EntityBean bean = (EntityBean) value;
|
||||
for (BeanProperty prop : props) {
|
||||
Object embFieldValue = prop.getValue((EntityBean) value);
|
||||
prop.bind(dataBind, embFieldValue);
|
||||
prop.bind(dataBind, prop.getValue(bean));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addIdInBindValues(DefaultSqlUpdate sqlUpdate, Collection<?> values) {
|
||||
public void addBindValues(DefaultSqlUpdate sqlUpdate, Collection<?> values) {
|
||||
for (Object value : values) {
|
||||
bindId(sqlUpdate, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addIdInBindValues(SpiExpressionRequest request, Collection<?> values) {
|
||||
public void addBindValues(SpiExpressionRequest request, Collection<?> values) {
|
||||
for (Object value : values) {
|
||||
final EntityBean bean = (EntityBean) value;
|
||||
for (BeanProperty prop : props) {
|
||||
request.addBindValue(prop.getValue((EntityBean) value));
|
||||
request.addBindValue(prop.getValue(bean));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
EntityBean embId = idDesc.createEntityBean();
|
||||
final EntityBean embId = idDesc.createEntityBean();
|
||||
boolean notNull = true;
|
||||
for (BeanProperty prop : props) {
|
||||
Object value = prop.readData(dataInput);
|
||||
final Object value = prop.readData(dataInput);
|
||||
prop.setValue(embId, value);
|
||||
if (value == null) {
|
||||
notNull = false;
|
||||
@@ -302,9 +294,9 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
|
||||
@Override
|
||||
public void writeData(DataOutput dataOutput, Object idValue) throws IOException {
|
||||
final EntityBean bean = (EntityBean) idValue;
|
||||
for (BeanProperty prop : props) {
|
||||
Object embFieldValue = prop.getValue((EntityBean) idValue);
|
||||
prop.writeData(dataOutput, embFieldValue);
|
||||
prop.writeData(dataOutput, prop.getValue(bean));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,10 +309,10 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
|
||||
@Override
|
||||
public Object read(DbReadContext ctx) throws SQLException {
|
||||
EntityBean embId = idDesc.createEntityBean();
|
||||
final EntityBean embId = idDesc.createEntityBean();
|
||||
boolean nullValue = true;
|
||||
for (BeanProperty prop : props) {
|
||||
Object value = prop.read(ctx);
|
||||
final Object value = prop.read(ctx);
|
||||
if (value != null) {
|
||||
prop.setValue(embId, value);
|
||||
nullValue = false;
|
||||
@@ -348,34 +340,34 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAssocIdInExpr(String prefix) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("(");
|
||||
public String assocInExpr(String prefix) {
|
||||
final StringBuilder sb = new StringBuilder(80);
|
||||
sb.append('(');
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
if (prefix != null) {
|
||||
sb.append(prefix).append(".");
|
||||
sb.append(prefix).append('.');
|
||||
}
|
||||
sb.append(props[i].name());
|
||||
}
|
||||
sb.append(")");
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAssocOneIdExpr(String prefix, String operator) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
public String assocExpr(String prefix, String operator) {
|
||||
final StringBuilder sb = new StringBuilder(100);
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(" and ");
|
||||
}
|
||||
if (prefix != null) {
|
||||
sb.append(prefix).append(".");
|
||||
sb.append(prefix).append('.');
|
||||
}
|
||||
if (!idClass) {
|
||||
sb.append(embIdProperty.name()).append(".");
|
||||
sb.append(embIdProperty.name()).append('.');
|
||||
}
|
||||
sb.append(props[i].name()).append(operator);
|
||||
}
|
||||
@@ -383,14 +375,14 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBindIdSql(String baseTableAlias) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
public String bindEqSql(String baseTableAlias) {
|
||||
final StringBuilder sb = new StringBuilder(80);
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(" and ");
|
||||
}
|
||||
if (baseTableAlias != null) {
|
||||
sb.append(baseTableAlias).append(".");
|
||||
sb.append(baseTableAlias).append('.');
|
||||
}
|
||||
sb.append(props[i].dbColumn()).append("=?");
|
||||
}
|
||||
@@ -398,22 +390,22 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBindIdInSql(String baseTableAlias) {
|
||||
public String bindInSql(String baseTableAlias) {
|
||||
if (idInExpandedForm) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("(");
|
||||
final StringBuilder sb = new StringBuilder(80);
|
||||
sb.append('(');
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
sb.append(',');
|
||||
}
|
||||
if (baseTableAlias != null) {
|
||||
sb.append(baseTableAlias).append(".");
|
||||
sb.append(baseTableAlias).append('.');
|
||||
}
|
||||
sb.append(props[i].dbColumn());
|
||||
}
|
||||
sb.append(")");
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -442,14 +434,14 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
|
||||
@Override
|
||||
public String cacheKey(Object value) {
|
||||
EntityBean bean = (EntityBean)value;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
final EntityBean bean = (EntityBean)value;
|
||||
final StringBuilder sb = new StringBuilder(80);
|
||||
for (BeanProperty prop : props) {
|
||||
Object val = prop.getValue(bean);
|
||||
if (val != null) {
|
||||
sb.append(prop.format(val));
|
||||
}
|
||||
sb.append("|");
|
||||
sb.append('|');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@ package io.ebeaninternal.server.deploy.id;
|
||||
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||
import io.ebeaninternal.server.bind.DataBind;
|
||||
import io.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.deploy.DbReadContext;
|
||||
import io.ebeaninternal.server.deploy.DbSqlContext;
|
||||
import io.ebeaninternal.server.bind.DataBind;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
@@ -27,13 +27,18 @@ final class IdBinderEmpty implements IdBinder {
|
||||
public void initialise() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idSelect() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIdInExpandedForm() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOrderBy(String pathPrefix, boolean ascending) {
|
||||
public String orderBy(String pathPrefix, boolean ascending) {
|
||||
return pathPrefix;
|
||||
}
|
||||
|
||||
@@ -42,12 +47,7 @@ final class IdBinderEmpty implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanProperty getBeanProperty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdProperty() {
|
||||
public BeanProperty beanProperty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -62,58 +62,58 @@ final class IdBinderEmpty implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultOrderBy() {
|
||||
public String orderBy() {
|
||||
// this should never happen?
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBindIdSql(String baseTableAlias) {
|
||||
public String bindEqSql(String baseTableAlias) {
|
||||
return bindIdSql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAssocOneIdExpr(String prefix, String operator) {
|
||||
public String assocExpr(String prefix, String operator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAssocIdInExpr(String prefix) {
|
||||
public String assocInExpr(String prefix) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdInValueExprDelete(int size) {
|
||||
return getIdInValueExpr(false, size);
|
||||
public String idInValueExprDelete(int size) {
|
||||
return idInValueExpr(false, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdInValueExpr(boolean not, int size) {
|
||||
public String idInValueExpr(boolean not, int size) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBindIdInSql(String baseTableAlias) {
|
||||
public String bindInSql(String baseTableAlias) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getIdValues(EntityBean bean) {
|
||||
public Object[] values(EntityBean bean) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getBindValues(Object idValue) {
|
||||
public Object[] bindValues(Object idValue) {
|
||||
return new Object[]{idValue};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getIdForJson(EntityBean bean) {
|
||||
public Object convertForJson(EntityBean bean) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertIdFromJson(Object value) {
|
||||
public Object convertFromJson(Object value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -126,11 +126,11 @@ final class IdBinderEmpty implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addIdInBindValues(DefaultSqlUpdate sqlUpdate, Collection<?> ids) {
|
||||
public void addBindValues(DefaultSqlUpdate sqlUpdate, Collection<?> ids) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addIdInBindValues(SpiExpressionRequest request, Collection<?> ids) {
|
||||
public void addBindValues(SpiExpressionRequest request, Collection<?> ids) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,16 +45,21 @@ public final class IdBinderSimple implements IdBinder {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public String idSelect() {
|
||||
return idProperty.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIdInExpandedForm() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOrderBy(String pathPrefix, boolean ascending) {
|
||||
public String orderBy(String pathPrefix, boolean ascending) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (pathPrefix != null) {
|
||||
sb.append(pathPrefix).append(".");
|
||||
sb.append(pathPrefix).append('.');
|
||||
}
|
||||
sb.append(idProperty.name());
|
||||
if (!ascending) {
|
||||
@@ -69,15 +74,10 @@ public final class IdBinderSimple implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanProperty getBeanProperty() {
|
||||
public BeanProperty beanProperty() {
|
||||
return idProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdProperty() {
|
||||
return idProperty.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanProperty findBeanProperty(String dbColumnName) {
|
||||
if (dbColumnName.equalsIgnoreCase(idProperty.dbColumn())) {
|
||||
@@ -92,12 +92,12 @@ public final class IdBinderSimple implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultOrderBy() {
|
||||
public String orderBy() {
|
||||
return idProperty.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBindIdInSql(String baseTableAlias) {
|
||||
public String bindInSql(String baseTableAlias) {
|
||||
if (baseTableAlias == null) {
|
||||
return idProperty.dbColumn();
|
||||
} else {
|
||||
@@ -106,7 +106,7 @@ public final class IdBinderSimple implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBindIdSql(String baseTableAlias) {
|
||||
public String bindEqSql(String baseTableAlias) {
|
||||
if (baseTableAlias == null) {
|
||||
return bindIdSql;
|
||||
} else {
|
||||
@@ -115,22 +115,22 @@ public final class IdBinderSimple implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getIdValues(EntityBean bean) {
|
||||
public Object[] values(EntityBean bean) {
|
||||
return new Object[]{idProperty.getValue(bean)};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getBindValues(Object idValue) {
|
||||
public Object[] bindValues(Object idValue) {
|
||||
return new Object[]{idValue};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdInValueExprDelete(int size) {
|
||||
return getIdInValueExpr(false, size);
|
||||
public String idInValueExprDelete(int size) {
|
||||
return idInValueExpr(false, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdInValueExpr(boolean not, int size) {
|
||||
public String idInValueExpr(boolean not, int size) {
|
||||
if (size <= 0) {
|
||||
throw new IndexOutOfBoundsException("The size must be at least 1");
|
||||
}
|
||||
@@ -138,24 +138,24 @@ public final class IdBinderSimple implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addIdInBindValues(DefaultSqlUpdate sqlUpdate, Collection<?> ids) {
|
||||
public void addBindValues(DefaultSqlUpdate sqlUpdate, Collection<?> ids) {
|
||||
sqlUpdate.setParameter(new MultiValueWrapper(ids));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addIdInBindValues(SpiExpressionRequest request, Collection<?> values) {
|
||||
public void addBindValues(SpiExpressionRequest request, Collection<?> values) {
|
||||
List<Object> copy = new ArrayList<>(values);
|
||||
copy.replaceAll(idValue -> convertSetId(idValue, null));
|
||||
request.addBindValue(new MultiValueWrapper(copy));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getIdForJson(EntityBean bean) {
|
||||
public Object convertForJson(EntityBean bean) {
|
||||
return idProperty.getValue(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertIdFromJson(Object value) {
|
||||
public Object convertFromJson(Object value) {
|
||||
// handle simple type conversion if required
|
||||
return convertId(value);
|
||||
}
|
||||
@@ -208,11 +208,11 @@ public final class IdBinderSimple implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAssocOneIdExpr(String prefix, String operator) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
public String assocExpr(String prefix, String operator) {
|
||||
StringBuilder sb = new StringBuilder(25);
|
||||
if (prefix != null) {
|
||||
sb.append(prefix);
|
||||
sb.append(".");
|
||||
sb.append('.');
|
||||
}
|
||||
sb.append(idProperty.name());
|
||||
sb.append(operator);
|
||||
@@ -220,11 +220,11 @@ public final class IdBinderSimple implements IdBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAssocIdInExpr(String prefix) {
|
||||
public String assocInExpr(String prefix) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (prefix != null) {
|
||||
sb.append(prefix);
|
||||
sb.append(".");
|
||||
sb.append('.');
|
||||
}
|
||||
sb.append(idProperty.name());
|
||||
return sb.toString();
|
||||
|
||||
+2
-6
@@ -139,10 +139,6 @@ public class DeployBeanDescriptor<T> {
|
||||
this.beanType = beanType;
|
||||
}
|
||||
|
||||
public BindMaxLength bindMaxLength() {
|
||||
return manager.bindMaxLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the IdClass to use.
|
||||
*/
|
||||
@@ -658,7 +654,7 @@ public class DeployBeanDescriptor<T> {
|
||||
public void postAnnotations() {
|
||||
if (idClass != null) {
|
||||
idClassProperty = new DeployBeanPropertyAssocOne<>(this, idClass);
|
||||
idClassProperty.setName("_idClass");
|
||||
idClassProperty.setName("_$IdClass$");
|
||||
idClassProperty.setEmbedded();
|
||||
idClassProperty.setNullable(false);
|
||||
}
|
||||
@@ -813,7 +809,7 @@ public class DeployBeanDescriptor<T> {
|
||||
for (DeployBeanProperty prop : propMap.values()) {
|
||||
if (!prop.isTransient() && !(prop instanceof DeployBeanPropertyAssocMany<?>)) {
|
||||
if (prop.isFetchEager()) {
|
||||
sb.append(prop.getName()).append(",");
|
||||
sb.append(prop.getName()).append(',');
|
||||
} else {
|
||||
hasLazyFetch = true;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user