mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
79
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19d2b04175 | ||
|
|
d1844c9b5a | ||
|
|
93803eade4 | ||
|
|
ca6171f697 | ||
|
|
aa80bc0c10 | ||
|
|
638cfbca5e | ||
|
|
afa9d89cfe | ||
|
|
22a433997e | ||
|
|
b9d8a9c532 | ||
|
|
1f0191b9e4 | ||
|
|
2d78c5c5e8 | ||
|
|
7c54d21760 | ||
|
|
b9a502ca85 | ||
|
|
b622d85292 | ||
|
|
320ffb4a2d | ||
|
|
0292b4b558 | ||
|
|
2c8ae16179 | ||
|
|
381ac58eed | ||
|
|
af9459e41e | ||
|
|
5882169641 | ||
|
|
f694f2946a | ||
|
|
4c0144de61 | ||
|
|
5e70ea5095 | ||
|
|
acb28925f2 | ||
|
|
3d2a68782c | ||
|
|
8c97d4d0fe | ||
|
|
eb7de343a8 | ||
|
|
4ca1645f9f | ||
|
|
d1fe79005c | ||
|
|
015ee44de3 | ||
|
|
714bbadbc0 | ||
|
|
9e811e9aef | ||
|
|
f97dcb60c0 | ||
|
|
65c76cb2c0 | ||
|
|
874427dac1 | ||
|
|
1176c2e97a | ||
|
|
44e0585fb7 | ||
|
|
889c0f12e0 | ||
|
|
0135263dbd | ||
|
|
564194042b | ||
|
|
244d45674a | ||
|
|
4722f10f5e | ||
|
|
3f5140e7f3 | ||
|
|
43dec17d08 | ||
|
|
f1ee45d7d1 | ||
|
|
3263e7bfc3 | ||
|
|
e01f19b3aa | ||
|
|
20f6a659fe | ||
|
|
09fe923770 | ||
|
|
e6f5e42c2d | ||
|
|
010f73fea2 | ||
|
|
5150ecba62 | ||
|
|
978b1dbe02 | ||
|
|
9813703ce5 | ||
|
|
09001e80b5 | ||
|
|
4aa3ca6d95 | ||
|
|
5ec8469ddc | ||
|
|
39099bbcc9 | ||
|
|
cb2ca0de11 | ||
|
|
b25233b0b9 | ||
|
|
743f1b10e3 | ||
|
|
371f50fb4d | ||
|
|
a3be2041c8 | ||
|
|
09a831f2d6 | ||
|
|
27d9e03691 | ||
|
|
61d6cccbcb | ||
|
|
a3540057b7 | ||
|
|
9720cd8189 | ||
|
|
bc4d9837c6 | ||
|
|
4a0f8931a0 | ||
|
|
3c8c52ca7f | ||
|
|
d29ef8934d | ||
|
|
a4c3949cfc | ||
|
|
97bbce321d | ||
|
|
0b9d199829 | ||
|
|
3da924b943 | ||
|
|
5ad313d290 | ||
|
|
8565f5f807 | ||
|
|
96e79248dc |
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-clickhouse</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-clickhouse</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-cockroach</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-db2</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-db2</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-h2</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-hana</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-hana</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-mariadb</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mariadb</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-mysql</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mysql</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-nuodb</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-nuodb</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-oracle</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-oracle</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-postgres</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-sqlite</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlite</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-sqlserver</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-yugabyte</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean (all platforms)</name>
|
||||
@@ -16,31 +16,31 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-joda-time</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-jsonnode</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-mapper</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -53,18 +53,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-all</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>composites</artifactId>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean api</name>
|
||||
|
||||
@@ -30,6 +30,13 @@ public final class Expr {
|
||||
private Expr() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the underlying expression factory.
|
||||
*/
|
||||
public static ExpressionFactory factory() {
|
||||
return DB.expressionFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Equal To - property equal to the given value.
|
||||
*/
|
||||
|
||||
@@ -1730,4 +1730,8 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> endNot();
|
||||
|
||||
/**
|
||||
* Clears the current expression list.
|
||||
*/
|
||||
ExpressionList<T> clear();
|
||||
}
|
||||
|
||||
@@ -1768,4 +1768,31 @@ public interface Query<T> extends CancelableQuery {
|
||||
*/
|
||||
Query<T> orderById(boolean orderById);
|
||||
|
||||
/**
|
||||
* Type safe query bean properties and expressions (marker interface).
|
||||
* <p>
|
||||
* Implemented by query bean properties and expressions based on those properties.
|
||||
* <p>
|
||||
* The base type determines which {@link StdOperators} can be used on the property.
|
||||
*
|
||||
* @param <T> The property type.
|
||||
*/
|
||||
interface Property<T> {
|
||||
|
||||
/**
|
||||
* Return a property given the expression.
|
||||
*/
|
||||
static <T> Property<T> of(String expression) {
|
||||
return new SimpleProperty<>(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the property in string expression form.
|
||||
* <p>
|
||||
* This is a path to a database column (like "name" or "billingAddress.city") or a function
|
||||
* wrapping a path (like <em>lower(name)</em>, <em>concat(name, '-', billingAddress.city)</em>
|
||||
*/
|
||||
@Override
|
||||
String toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.ebean;
|
||||
|
||||
final class SimpleProperty<T> implements Query.Property<T> {
|
||||
|
||||
private final String expression;
|
||||
|
||||
SimpleProperty(String expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.Query.Property;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Standard Operators for use with strongly typed query construction.
|
||||
* <p>
|
||||
* This is currently deemed to be experimental and subject to change.
|
||||
*/
|
||||
@Deprecated(since = "experimental")
|
||||
public final class StdOperators {
|
||||
|
||||
// ---- Functions ---- //
|
||||
|
||||
/**
|
||||
* Sum of the given property.
|
||||
*/
|
||||
public static Property<Number> sum(Property<? extends Number> property) {
|
||||
return Property.of("sum(" + property + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Count of the given property.
|
||||
*/
|
||||
public static Property<Number> count(Property<?> property) {
|
||||
return Property.of("count(" + property + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Average of the given property.
|
||||
*/
|
||||
public static <T> Property<T> avg(Property<T> property) {
|
||||
return Property.of("avg(" + property + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Max of the given property.
|
||||
*/
|
||||
public static <T> Property<T> max(Property<T> property) {
|
||||
return Property.of("max(" + property + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Min of the given property.
|
||||
*/
|
||||
public static <T> Property<T> min(Property<T> property) {
|
||||
return Property.of("min(" + property + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Coalesce of the property and value.
|
||||
*/
|
||||
public static <T> Property<T> coalesce(Property<T> property, Object value) {
|
||||
return Property.of("coalesce(" + property.toString() + "," + sqlValue(value) + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Lower of the given property.
|
||||
*/
|
||||
public static Property<String> lower(Property<String> property) {
|
||||
return Property.of("lower(" + property + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Upper of the given property.
|
||||
*/
|
||||
public static Property<String> upper(Property<String> property) {
|
||||
return Property.of("upper(" + property + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Concat of the given property and values or other properties.
|
||||
*/
|
||||
public static Property<String> concat(Property<?> property, Object... values) {
|
||||
StringBuilder expression = new StringBuilder(50);
|
||||
expression.append("concat(").append(property.toString());
|
||||
for (Object value : values) {
|
||||
expression.append(",").append(sqlConcatString(value));
|
||||
}
|
||||
expression.append(")");
|
||||
return Property.of(expression.toString());
|
||||
}
|
||||
|
||||
private static String sqlConcatString(Object value) {
|
||||
if (value instanceof Property) {
|
||||
return value.toString();
|
||||
} else {
|
||||
return sqlQuote(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows numbers to be unquoted.
|
||||
*/
|
||||
private static String sqlValue(Object value) {
|
||||
if (value instanceof Property || value instanceof Number) {
|
||||
return value.toString();
|
||||
} else {
|
||||
return sqlQuote(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL quoted escaping single quotes.
|
||||
*/
|
||||
private static String sqlQuote(Object value) {
|
||||
return "'" + String.valueOf(value).replace("'", "''") + "'";
|
||||
}
|
||||
|
||||
// ---- Operators ---- //
|
||||
|
||||
/**
|
||||
* Equal to - for a property and value.
|
||||
*/
|
||||
public static <T> Expression eq(Property<T> property, T value) {
|
||||
return Expr.eq(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equal to - for a property and sub-query.
|
||||
*/
|
||||
public static <T> Expression eq(Property<T> property, Query<?> subQuery) {
|
||||
return Expr.in(property.toString(), subQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equal to or null - for a property and value.
|
||||
*/
|
||||
public static <T> Expression eqOrNull(Property<T> property, T value) {
|
||||
return Expr.factory().eqOrNull(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not equal to - for a property and value.
|
||||
*/
|
||||
public static <T> Expression ne(Property<T> property, T value) {
|
||||
return Expr.ne(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not equal to - for a property and sub-query.
|
||||
*/
|
||||
public static <T> Expression ne(Property<T> property, Query<?> subQuery) {
|
||||
return Expr.ne(property.toString(), subQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than - for a property and value.
|
||||
*/
|
||||
public static <T> Expression gt(Property<T> property, T value) {
|
||||
return Expr.gt(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than - for a property and sub-query.
|
||||
*/
|
||||
public static <T> Expression gt(Property<T> property, Query<?> subQuery) {
|
||||
return Expr.gt(property.toString(), subQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or null - for a property and value.
|
||||
*/
|
||||
public static <T> Expression gtOrNull(Property<T> property, T value) {
|
||||
return Expr.factory().gtOrNull(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or equal to - for a property and value.
|
||||
*/
|
||||
public static <T> Expression ge(Property<T> property, T value) {
|
||||
return Expr.ge(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or equal to - for a property and sub-query.
|
||||
*/
|
||||
public static <T> Expression ge(Property<T> property, Query<?> subQuery) {
|
||||
return Expr.ge(property.toString(), subQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or null - for a property and value.
|
||||
*/
|
||||
public static <T> Expression geOrNull(Property<T> property, T value) {
|
||||
return Expr.factory().geOrNull(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Less than - for a property and value.
|
||||
*/
|
||||
public static <T> Expression lt(Property<T> property, T value) {
|
||||
return Expr.lt(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Less than - for a property and sub-query.
|
||||
*/
|
||||
public static <T> Expression lt(Property<T> property, Query<?> subQuery) {
|
||||
return Expr.lt(property.toString(), subQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Less than or null - for a property and value.
|
||||
*/
|
||||
public static <T> Expression ltOrNull(Property<T> property, T value) {
|
||||
return Expr.factory().ltOrNull(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or equal to - for a property and value.
|
||||
*/
|
||||
public static <T> Expression le(Property<T> property, T value) {
|
||||
return Expr.le(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or equal to - for a property and sub-query.
|
||||
*/
|
||||
public static <T> Expression le(Property<T> property, Query<?> subQuery) {
|
||||
return Expr.le(property.toString(), subQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or equal to or null - for a property and value.
|
||||
*/
|
||||
public static <T> Expression leOrNull(Property<T> property, T value) {
|
||||
return Expr.factory().leOrNull(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* In range - for a property and values.
|
||||
*/
|
||||
public static <T> Expression inRange(Property<T> property, T lowValue, T highValue) {
|
||||
return Expr.factory().inRange(property.toString(), lowValue, highValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* In range - for properties and a value.
|
||||
*/
|
||||
public static <T> Expression inRange(Property<T> lowProperty, Property<T> highProperty, T value) {
|
||||
return Expr.factory().inRangeWith(lowProperty.toString(), highProperty.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* In range - for properties.
|
||||
*/
|
||||
public static <T> Expression inRange(Property<T> lowProperty, Property<T> property, Property<T> highProperty) {
|
||||
return Expr.factory().inRangeWithProperties(lowProperty.toString(), property.toString(), highProperty.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* In - for a given property and collection of values.
|
||||
*/
|
||||
public static <T> Expression in(Property<T> property, Collection<T> value) {
|
||||
return Expr.in(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* In - for a given property and sub-query.
|
||||
*/
|
||||
public static <T> Expression in(Property<T> property, Query<?> subQuery) {
|
||||
return Expr.in(property.toString(), subQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* In or empty - for a given property and collection of values.
|
||||
*/
|
||||
public static <T> Expression inOrEmpty(Property<T> property, Collection<T> value) {
|
||||
return Expr.inOrEmpty(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not In - for a given property and collection of values.
|
||||
*/
|
||||
public static <T> Expression notIn(Property<T> property, Collection<T> value) {
|
||||
return Expr.factory().notIn(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not In - for a given property and sub-query.
|
||||
*/
|
||||
public static <T> Expression notIn(Property<T> property, Query<?> subQuery) {
|
||||
return Expr.factory().notIn(property.toString(), subQuery);
|
||||
}
|
||||
|
||||
// ---- String operators ---- //
|
||||
|
||||
/**
|
||||
* Like - for a given property and value.
|
||||
*/
|
||||
public static Expression like(Property<String> property, String value) {
|
||||
return Expr.like(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Case-insensitive Like - for a given property and value.
|
||||
*/
|
||||
public static Expression ilike(Property<String> property, String value) {
|
||||
return Expr.ilike(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts with - for a given property and value.
|
||||
*/
|
||||
public static Expression startsWith(Property<String> property, String value) {
|
||||
return Expr.startsWith(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Case-insensitive starts with - for a given property and value.
|
||||
*/
|
||||
public static Expression istartsWith(Property<String> property, String value) {
|
||||
return Expr.istartsWith(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains - for a given property and value.
|
||||
*/
|
||||
public static Expression contains(Property<String> property, String value) {
|
||||
return Expr.contains(property.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Case-insensitive contains - for a given property and value.
|
||||
*/
|
||||
public static Expression icontains(Property<String> property, String value) {
|
||||
return Expr.icontains(property.toString(), value);
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ package io.ebean;
|
||||
*
|
||||
* int rows = DB.update(Customer.class)
|
||||
* .set("status", Customer.Status.ACTIVE)
|
||||
* .set("updtime", new Timestamp(System.currentTimeMillis()))
|
||||
* .set("whenUpdated", Instant.now())
|
||||
* .where()
|
||||
* .gt("id", 1000)
|
||||
* .update();
|
||||
@@ -25,6 +25,20 @@ package io.ebean;
|
||||
* update o_customer set status=?, updtime=? where id > ?
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <h4>Example: Using query bean</h4>
|
||||
* <pre>{@code
|
||||
*
|
||||
* var cust = QCustomer.alias();
|
||||
*
|
||||
* int rows = new QCustomer()
|
||||
* .id.gt(1000)
|
||||
* .asUpdate()
|
||||
* .set(cust.status, Customer.Status.COMPLETE)
|
||||
* .set(cust.whenUpdated, Instant.now())
|
||||
* .update();
|
||||
*
|
||||
* }</pre>
|
||||
* <p>
|
||||
* Note that if the where() clause contains a join then the SQL update changes to use a
|
||||
* <code> WHERE ID IN () </code> form.
|
||||
@@ -40,7 +54,7 @@ package io.ebean;
|
||||
*
|
||||
* int rows = DB.update(Customer.class)
|
||||
* .set("status", Customer.Status.ACTIVE)
|
||||
* .set("updtime", new Timestamp(System.currentTimeMillis()))
|
||||
* .set("whenUpdated", Instant.now())
|
||||
* .where()
|
||||
* .eq("status", Customer.Status.NEW)
|
||||
* .eq("billingAddress.country", nz)
|
||||
@@ -73,7 +87,7 @@ public interface UpdateQuery<T> {
|
||||
*
|
||||
* int rows = DB.update(Customer.class)
|
||||
* .set("status", Customer.Status.ACTIVE)
|
||||
* .set("updtime", new Timestamp(System.currentTimeMillis()))
|
||||
* .set("whenUpdated", Instant.now())
|
||||
* .where()
|
||||
* .gt("id", 1000)
|
||||
* .update();
|
||||
@@ -85,6 +99,27 @@ public interface UpdateQuery<T> {
|
||||
*/
|
||||
UpdateQuery<T> set(String property, Object value);
|
||||
|
||||
/**
|
||||
* Set the value of a property.
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* var cust = QCustomer.alias();
|
||||
*
|
||||
* int rows = new QCustomer()
|
||||
* .id.gt(1000)
|
||||
* .asUpdate()
|
||||
* .set(cust.status, Customer.Status.COMPLETE)
|
||||
* .set(cust.whenUpdated, Instant.now())
|
||||
* .update();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param property The bean property to be set
|
||||
* @param value The value to set the property to
|
||||
*/
|
||||
<P> UpdateQuery<T> set(Query.Property<P> property, P value);
|
||||
|
||||
/**
|
||||
* Set the property to be null.
|
||||
* <p>
|
||||
@@ -102,6 +137,13 @@ public interface UpdateQuery<T> {
|
||||
*/
|
||||
UpdateQuery<T> setNull(String property);
|
||||
|
||||
/**
|
||||
* Set the property to be null.
|
||||
*
|
||||
* @param property The bean property to be set
|
||||
*/
|
||||
UpdateQuery<T> setNull(Query.Property<?> property);
|
||||
|
||||
/**
|
||||
* Set using a property expression that does not need any bind values.
|
||||
* <p>
|
||||
|
||||
@@ -725,7 +725,7 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
|
||||
loader.loadBean(this);
|
||||
if (lazyLoadFailure) {
|
||||
// failed when lazy loading this bean
|
||||
throw new EntityNotFoundException("Lazy loading failed on type:" + owner.getClass().getName() + " id:" + ownerId + " - Bean has been deleted.");
|
||||
throw new EntityNotFoundException("Lazy loading failed on type:" + owner.getClass().getName() + " id:" + ownerId + " - Bean has been deleted. BeanLoader: " + beanLoader);
|
||||
}
|
||||
// bean should be loaded and intercepting now. setLoaded() has
|
||||
// been called by the lazy loading mechanism
|
||||
|
||||
@@ -29,6 +29,11 @@ public class ServerCacheStatistics {
|
||||
|
||||
protected long evictCount;
|
||||
|
||||
protected long gcCount;
|
||||
protected long idleCount;
|
||||
protected long ttlCount;
|
||||
protected long lruCount;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
//noinspection StringBufferReplaceableByString
|
||||
@@ -43,6 +48,10 @@ public class ServerCacheStatistics {
|
||||
sb.append(" remove:").append(removeCount);
|
||||
sb.append(" clear:").append(clearCount);
|
||||
sb.append(" evict:").append(evictCount);
|
||||
sb.append(" gc:").append(gcCount);
|
||||
sb.append(" idle:").append(idleCount);
|
||||
sb.append(" ttl:").append(ttlCount);
|
||||
sb.append(" lru:").append(lruCount);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -191,4 +200,37 @@ public class ServerCacheStatistics {
|
||||
return evictCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the count of entries removed by the garbage collection.
|
||||
*/
|
||||
public void setGcCount(long gcCount) {
|
||||
this.gcCount = gcCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the count of entries removed by the garbage collection.
|
||||
*/
|
||||
public long getGcCount() {
|
||||
return gcCount;
|
||||
}
|
||||
|
||||
public void setIdleCount(long idleCount) {
|
||||
this.idleCount = idleCount;
|
||||
}
|
||||
|
||||
public long getIdleCount() {
|
||||
return idleCount;
|
||||
}
|
||||
|
||||
public void setTtlCount(long ttlCount) {
|
||||
this.ttlCount = ttlCount;
|
||||
}
|
||||
|
||||
public long getTtlCount() {
|
||||
return ttlCount;
|
||||
}
|
||||
|
||||
public void setLruCount(long lruCount) {
|
||||
this.lruCount = lruCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
ebean-version: 141
|
||||
ebean-version: 142
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package io.ebean;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import static io.ebean.StdOperators.*;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class StdOperatorsTest {
|
||||
|
||||
final Query.Property<Number> amount = Query.Property.of("amount");
|
||||
final Query.Property<String> foo = Query.Property.of("foo");
|
||||
final Query.Property<String> bar = Query.Property.of("bar");
|
||||
|
||||
@Test
|
||||
void testAvg() {
|
||||
assertThat(avg(foo).toString()).isEqualTo("avg(foo)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCount() {
|
||||
assertThat(count(foo).toString()).isEqualTo("count(foo)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMax() {
|
||||
assertThat(max(foo).toString()).isEqualTo("max(foo)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMin() {
|
||||
assertThat(min(foo).toString()).isEqualTo("min(foo)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSum() {
|
||||
assertThat(sum(amount).toString()).isEqualTo("sum(amount)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLower() {
|
||||
assertThat(lower(foo).toString()).isEqualTo("lower(foo)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpper() {
|
||||
assertThat(upper(foo).toString()).isEqualTo("upper(foo)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConcat() {
|
||||
assertThat(concat(foo, "+").toString()).isEqualTo("concat(foo,'+')");
|
||||
assertThat(concat(foo, 42).toString()).isEqualTo("concat(foo,'42')");
|
||||
assertThat(concat(foo, LocalDate.of(2022, 9, 1)).toString()).isEqualTo("concat(foo,'2022-09-01')");
|
||||
assertThat(concat(foo, bar).toString()).isEqualTo("concat(foo,bar)");
|
||||
assertThat(concat(foo, ":", 42, bar).toString()).isEqualTo("concat(foo,':','42',bar)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCoalesce() {
|
||||
assertThat(coalesce(foo, bar).toString()).isEqualTo("coalesce(foo,bar)");
|
||||
assertThat(coalesce(foo, 42).toString()).isEqualTo("coalesce(foo,42)");
|
||||
assertThat(coalesce(foo, 0).toString()).isEqualTo("coalesce(foo,0)");
|
||||
assertThat(coalesce(foo, "apple").toString()).isEqualTo("coalesce(foo,'apple')");
|
||||
assertThat(coalesce(foo, "banana").toString()).isEqualTo("coalesce(foo,'banana')");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCoalesceWithQuoted() {
|
||||
assertThat(coalesce(foo, "ba'nana").toString()).isEqualTo("coalesce(foo,'ba''nana')");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConcatWithQuoted() {
|
||||
assertThat(concat(foo, "ba'nana").toString()).isEqualTo("concat(foo,'ba''nana')");
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
<!-- <parent>-->
|
||||
<!-- <groupId>org.avaje</groupId>-->
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
|
||||
<name>ebean autotune</name>
|
||||
@@ -26,7 +26,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
+29
-47
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean bom</name>
|
||||
@@ -89,192 +89,174 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-joda-time</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-jsonnode</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-mapper</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-xml</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-autotune</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>querybean-generator</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>kotlin-querybean-generator</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgis</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-redis</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- platforms -->
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-all</artifactId>
|
||||
<version>13.11.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-clickhouse</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-db2</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-h2</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-hana</artifactId>
|
||||
<version>13.11.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-hsqldb</artifactId>
|
||||
<version>13.11.2-SNAPSHOT</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-mariadb</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-mysql</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-nuodb</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-oracle</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgres</artifactId>
|
||||
<version>13.11.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-sqlanywhere</artifactId>
|
||||
<version>13.11.2-SNAPSHOT</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-sqlite</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-sqlserver</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
@@ -16,7 +16,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
+8
-8
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core</artifactId>
|
||||
@@ -15,14 +15,14 @@
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -46,13 +46,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -143,21 +143,21 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -9,4 +9,5 @@ public final class CoreLog {
|
||||
|
||||
public static final System.Logger log = AppLog.getLogger("io.ebean.core");
|
||||
public static final System.Logger internal = AppLog.getLogger("io.ebean.internal");
|
||||
public static final System.Logger markedAsDeleted = AppLog.getLogger("io.ebean.MarkedAsDeleted");
|
||||
}
|
||||
|
||||
@@ -6,10 +6,7 @@ import io.ebeaninternal.api.SpiQuery.Mode;
|
||||
import io.ebeaninternal.server.core.OrmQueryRequest;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Request for loading ManyToOne and OneToOne relationships.
|
||||
@@ -103,7 +100,7 @@ public final class LoadBeanRequest extends LoadRequest {
|
||||
/**
|
||||
* Load the beans into the L2 cache if that is requested and check for load failures due to deletes.
|
||||
*/
|
||||
public void postLoad(List<?> list) {
|
||||
public Result postLoad(List<?> list) {
|
||||
Set<Object> loadedIds = new HashSet<>();
|
||||
BeanDescriptor<?> desc = loadBuffer.descriptor();
|
||||
// collect Ids and maybe load bean cache
|
||||
@@ -114,6 +111,7 @@ public final class LoadBeanRequest extends LoadRequest {
|
||||
desc.cacheBeanPutAll(list);
|
||||
}
|
||||
if (lazyLoadProperty != null) {
|
||||
Set<Object> missedIds = new HashSet<>();
|
||||
for (EntityBeanIntercept ebi : batch) {
|
||||
// check if the underlying row in DB was deleted. Mark the bean as 'failed' if
|
||||
// necessary but allow processing to continue until it is accessed by client code
|
||||
@@ -121,8 +119,36 @@ public final class LoadBeanRequest extends LoadRequest {
|
||||
if (!loadedIds.contains(id)) {
|
||||
// assume this is logically deleted (hence not found)
|
||||
desc.markAsDeleted(ebi.getOwner());
|
||||
missedIds.add(id);
|
||||
}
|
||||
}
|
||||
return new Result(loadedIds, missedIds);
|
||||
}
|
||||
return EMPTY_RESULT;
|
||||
}
|
||||
|
||||
static final Result EMPTY_RESULT = new Result(Collections.emptySet(),Collections.emptySet());
|
||||
|
||||
public static class Result {
|
||||
|
||||
private final Set<Object> loadedIds;
|
||||
private final Set<Object> missedIds;
|
||||
|
||||
Result(Set<Object> loadedIds, Set<Object> missedIds) {
|
||||
this.loadedIds = loadedIds;
|
||||
this.missedIds = missedIds;
|
||||
}
|
||||
|
||||
public boolean markedDeleted() {
|
||||
return !missedIds.isEmpty();
|
||||
}
|
||||
|
||||
public Set<Object> missedIds() {
|
||||
return missedIds;
|
||||
}
|
||||
|
||||
public Set<Object> loadedIds() {
|
||||
return loadedIds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,4 +50,9 @@ public interface LoadContext {
|
||||
* Register a collection for lazy loading.
|
||||
*/
|
||||
void register(String path, BeanPropertyAssocMany<?> many, BeanCollection<?> bc);
|
||||
|
||||
/**
|
||||
* Use soft-references for streaming queries, so unreachable entries can be garbage collected.
|
||||
*/
|
||||
void useReferences(boolean useReferences);
|
||||
}
|
||||
|
||||
@@ -6,16 +6,30 @@ import io.ebean.bean.PersistenceContext;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A buffer of bean collections for batch lazy loading and secondary query loading.
|
||||
*/
|
||||
public interface LoadManyBuffer {
|
||||
|
||||
int getBatchSize();
|
||||
/**
|
||||
* The batch (max) size;
|
||||
*/
|
||||
int batchSize();
|
||||
|
||||
List<BeanCollection<?>> getBatch();
|
||||
/**
|
||||
* The actual size.
|
||||
*/
|
||||
int size();
|
||||
|
||||
/**
|
||||
* Get the <code>i</code>th element from buffer. This can be null.
|
||||
*/
|
||||
BeanCollection<?> get(int i);
|
||||
|
||||
/**
|
||||
* Removes an element from the buffer. This will NOT affect size.
|
||||
*/
|
||||
boolean removeFromBuffer(BeanCollection<?> collection);
|
||||
|
||||
BeanPropertyAssocMany<?> getBeanProperty();
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@ import static java.lang.System.Logger.Level.DEBUG;
|
||||
public final class LoadManyRequest extends LoadRequest {
|
||||
|
||||
private static final System.Logger log = CoreLog.log;
|
||||
|
||||
private final List<BeanCollection<?>> batch;
|
||||
private final LoadManyBuffer loadContext;
|
||||
private final boolean onlyIds;
|
||||
private final boolean loadCache;
|
||||
@@ -42,7 +40,6 @@ public final class LoadManyRequest extends LoadRequest {
|
||||
private LoadManyRequest(LoadManyBuffer loadContext, OrmQueryRequest<?> parentRequest, boolean lazy, boolean onlyIds, boolean loadCache) {
|
||||
super(parentRequest, lazy);
|
||||
this.loadContext = loadContext;
|
||||
this.batch = loadContext.getBatch();
|
||||
this.onlyIds = onlyIds;
|
||||
this.loadCache = loadCache;
|
||||
}
|
||||
@@ -59,9 +56,12 @@ public final class LoadManyRequest extends LoadRequest {
|
||||
private List<Object> parentIdList(SpiEbeanServer server) {
|
||||
List<Object> idList = new ArrayList<>();
|
||||
BeanPropertyAssocMany<?> many = many();
|
||||
for (BeanCollection<?> bc : batch) {
|
||||
idList.add(many.parentId(bc.getOwnerBean()));
|
||||
bc.setLoader(server); // don't use the load buffer again
|
||||
for (int i = 0; i < loadContext.size(); i++) {
|
||||
BeanCollection<?> bc = loadContext.get(i);
|
||||
if (bc != null) {
|
||||
idList.add(many.parentId(bc.getOwnerBean()));
|
||||
bc.setLoader(server); // don't use the load buffer again
|
||||
}
|
||||
}
|
||||
if (many.targetDescriptor().isPadInExpression()) {
|
||||
BindPadding.padIds(idList);
|
||||
@@ -91,7 +91,7 @@ public final class LoadManyRequest extends LoadRequest {
|
||||
query.setPersistenceContext(loadContext.getPersistenceContext());
|
||||
query.setLoadDescription(lazy ? "+lazy" : "+query", description());
|
||||
if (lazy) {
|
||||
query.setLazyLoadBatchSize(loadContext.getBatchSize());
|
||||
query.setLazyLoadBatchSize(loadContext.batchSize());
|
||||
} else {
|
||||
query.setBeanCacheMode(CacheMode.OFF);
|
||||
}
|
||||
@@ -112,15 +112,18 @@ public final class LoadManyRequest extends LoadRequest {
|
||||
BeanPropertyAssocMany<?> many = many();
|
||||
// check for BeanCollection's that where never processed
|
||||
// in the +query or +lazy load due to no rows (predicates)
|
||||
for (BeanCollection<?> bc : batch) {
|
||||
if (bc.checkEmptyLazyLoad()) {
|
||||
if (log.isLoggable(DEBUG)) {
|
||||
EntityBean ownerBean = bc.getOwnerBean();
|
||||
Object parentId = desc.getId(ownerBean);
|
||||
log.log(DEBUG, "BeanCollection after lazy load was empty. type:{0} id:{1} owner:{2}", ownerBean.getClass().getName(), parentId, ownerBean);
|
||||
for (int i = 0; i < loadContext.size(); i++) {
|
||||
BeanCollection<?> bc = loadContext.get(i);
|
||||
if (bc != null) {
|
||||
if (bc.checkEmptyLazyLoad()) {
|
||||
if (log.isLoggable(DEBUG)) {
|
||||
EntityBean ownerBean = bc.getOwnerBean();
|
||||
Object parentId = desc.getId(ownerBean);
|
||||
log.log(DEBUG, "BeanCollection after lazy load was empty. type:{0} id:{1} owner:{2}", ownerBean.getClass().getName(), parentId, ownerBean);
|
||||
}
|
||||
} else if (loadCache && many.isUseCache()) {
|
||||
desc.cacheManyPropPut(many, bc, desc.cacheKeyForBean(bc.getOwnerBean()));
|
||||
}
|
||||
} else if (loadCache && many.isUseCache()) {
|
||||
desc.cacheManyPropPut(many, bc, desc.cacheKeyForBean(bc.getOwnerBean()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,18 +10,25 @@ package io.ebeaninternal.api;
|
||||
public interface SpiLogManager {
|
||||
|
||||
/**
|
||||
* Return the SQL logger.
|
||||
* Enable bind logging.
|
||||
*/
|
||||
boolean enableBindLog();
|
||||
|
||||
/**
|
||||
* Logger used for general transactions.
|
||||
*/
|
||||
SpiTxnLogger logger();
|
||||
|
||||
/**
|
||||
* Logger used for read only transactions.
|
||||
*/
|
||||
SpiTxnLogger readOnlyLogger();
|
||||
|
||||
/**
|
||||
* Hmmmm, return the SQL logger for logging truncate statements.
|
||||
* <p>
|
||||
* Maybe we should get rid of this
|
||||
*/
|
||||
SpiLogger sql();
|
||||
|
||||
/**
|
||||
* Return the TXN logger.
|
||||
*/
|
||||
SpiLogger txn();
|
||||
|
||||
/**
|
||||
* Return the Summary logger.
|
||||
*/
|
||||
SpiLogger sum();
|
||||
|
||||
}
|
||||
|
||||
@@ -14,18 +14,9 @@ public interface SpiLogger {
|
||||
*/
|
||||
boolean isDebug();
|
||||
|
||||
/**
|
||||
* Is trace logging enabled.
|
||||
*/
|
||||
boolean isTrace();
|
||||
|
||||
/**
|
||||
* Log a debug level message.
|
||||
*/
|
||||
void debug(String msg);
|
||||
void debug(String msg, Object... args);
|
||||
|
||||
/**
|
||||
* Log a trace level message.
|
||||
*/
|
||||
void trace(String msg);
|
||||
}
|
||||
|
||||
@@ -27,10 +27,6 @@ public interface SpiTransaction extends Transaction {
|
||||
*/
|
||||
String getLabel();
|
||||
|
||||
/**
|
||||
* Return the string prefix with the transaction id and label used in logging.
|
||||
*/
|
||||
String getLogPrefix();
|
||||
|
||||
/**
|
||||
* Return true if generated SQL and Bind values should be logged to the
|
||||
@@ -47,12 +43,17 @@ public interface SpiTransaction extends Transaction {
|
||||
/**
|
||||
* Log a message to the SQL logger.
|
||||
*/
|
||||
void logSql(String msg);
|
||||
void logSql(String msg, Object... args);
|
||||
|
||||
/**
|
||||
* Log a message to the SUMMARY logger.
|
||||
* Log a summary message to the SUMMARY logger.
|
||||
*/
|
||||
void logSummary(String msg);
|
||||
void logSummary(String msg, Object... args);
|
||||
|
||||
/**
|
||||
* Log a transaction message to the transaction logger.
|
||||
*/
|
||||
void logTxn(String msg, Object... args);
|
||||
|
||||
/**
|
||||
* Register a "Deferred Relationship" that requires an additional update later.
|
||||
|
||||
@@ -137,10 +137,6 @@ public abstract class SpiTransactionProxy implements SpiTransaction {
|
||||
transaction.setDocStoreBatchSize(batchSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogPrefix() {
|
||||
return transaction.getLogPrefix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogSql() {
|
||||
@@ -153,13 +149,18 @@ public abstract class SpiTransactionProxy implements SpiTransaction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSql(String msg) {
|
||||
transaction.logSql(msg);
|
||||
public void logSql(String msg, Object... args) {
|
||||
transaction.logSql(msg, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSummary(String msg) {
|
||||
transaction.logSummary(msg);
|
||||
public void logSummary(String msg, Object... args) {
|
||||
transaction.logSummary(msg, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logTxn(String msg, Object... args) {
|
||||
transaction.logTxn(msg, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package io.ebeaninternal.api;
|
||||
|
||||
/**
|
||||
* Per Transaction logging of SQL, TXN and Summary messages.
|
||||
*/
|
||||
public interface SpiTxnLogger {
|
||||
|
||||
String id();
|
||||
|
||||
/**
|
||||
* Is debug logging enabled.
|
||||
*/
|
||||
boolean isLogSql();
|
||||
|
||||
/**
|
||||
* Is summary logging enabled.
|
||||
*/
|
||||
boolean isLogSummary();
|
||||
|
||||
/**
|
||||
* Log a SQL message.
|
||||
*/
|
||||
void sql(String msg, Object... args);
|
||||
|
||||
/**
|
||||
* Log a Summary message.
|
||||
*/
|
||||
void sum(String msg, Object... args);
|
||||
|
||||
/**
|
||||
* Log a Transaction message.
|
||||
*/
|
||||
void txn(String msg, Object... args);
|
||||
|
||||
/**
|
||||
* Transaction Committed.
|
||||
*/
|
||||
void notifyCommit();
|
||||
|
||||
/**
|
||||
* Query only transaction completed.
|
||||
*/
|
||||
void notifyQueryOnly();
|
||||
|
||||
/**
|
||||
* Transaction Rolled back.
|
||||
*/
|
||||
void notifyRollback(Throwable cause);
|
||||
}
|
||||
+24
-1
@@ -44,7 +44,10 @@ public class DefaultServerCache implements ServerCache {
|
||||
protected final CountMetric removeCount;
|
||||
protected final CountMetric clearCount;
|
||||
protected final CountMetric evictCount;
|
||||
|
||||
protected final CountMetric gcCount;
|
||||
protected final CountMetric idleCount;
|
||||
protected final CountMetric ttlCount;
|
||||
protected final CountMetric lruCount;
|
||||
protected final String name;
|
||||
protected final String shortName;
|
||||
protected final int maxSize;
|
||||
@@ -55,6 +58,7 @@ public class DefaultServerCache implements ServerCache {
|
||||
protected final ReentrantLock lock = new ReentrantLock();
|
||||
protected final AtomicLong mutationCounter = new AtomicLong();
|
||||
|
||||
|
||||
public DefaultServerCache(DefaultServerCacheConfig config) {
|
||||
this.name = config.getName();
|
||||
this.shortName = config.getShortName();
|
||||
@@ -73,6 +77,11 @@ public class DefaultServerCache implements ServerCache {
|
||||
this.removeCount = factory.createCountMetric(prefix + shortName + ".remove");
|
||||
this.clearCount = factory.createCountMetric(prefix + shortName + ".clear");
|
||||
this.evictCount = factory.createCountMetric(prefix + shortName + ".evict");
|
||||
this.gcCount = factory.createCountMetric(prefix + shortName + ".gc");
|
||||
this.idleCount = factory.createCountMetric(prefix + shortName + ".idle");
|
||||
this.ttlCount = factory.createCountMetric(prefix + shortName + ".ttl");
|
||||
this.lruCount = factory.createCountMetric(prefix + shortName + ".lru");
|
||||
|
||||
}
|
||||
|
||||
public void periodicTrim(BackgroundExecutor executor) {
|
||||
@@ -90,6 +99,10 @@ public class DefaultServerCache implements ServerCache {
|
||||
removeCount.visit(visitor);
|
||||
clearCount.visit(visitor);
|
||||
evictCount.visit(visitor);
|
||||
gcCount.visit(visitor);
|
||||
idleCount.visit(visitor);
|
||||
ttlCount.visit(visitor);
|
||||
lruCount.visit(visitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,6 +117,10 @@ public class DefaultServerCache implements ServerCache {
|
||||
cacheStats.setRemoveCount(removeCount.get(reset));
|
||||
cacheStats.setClearCount(clearCount.get(reset));
|
||||
cacheStats.setEvictCount(evictCount.get(reset));
|
||||
cacheStats.setGcCount(gcCount.get(reset));
|
||||
cacheStats.setIdleCount(idleCount.get(reset));
|
||||
cacheStats.setTtlCount(ttlCount.get(reset));
|
||||
cacheStats.setLruCount(lruCount.get(reset));
|
||||
return cacheStats;
|
||||
}
|
||||
|
||||
@@ -289,6 +306,12 @@ public class DefaultServerCache implements ServerCache {
|
||||
evictCount.add(trimmedByGC);
|
||||
evictCount.add(trimmedByTTL);
|
||||
evictCount.add(trimmedByLRU);
|
||||
|
||||
gcCount.add(trimmedByGC);
|
||||
idleCount.add(trimmedByIdle);
|
||||
ttlCount.add(trimmedByTTL);
|
||||
lruCount.add(trimmedByLRU);
|
||||
|
||||
if (logger.isLoggable(TRACE)) {
|
||||
long exeMicros = TimeUnit.MICROSECONDS.convert(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
|
||||
logger.log(TRACE, "Executed trim of cache {0} in [{1}]millis idle[{2}] timeToLive[{3}] accessTime[{4}] gc[{5}]",
|
||||
|
||||
@@ -4,7 +4,6 @@ import io.ebean.CancelableQuery;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.util.JdbcClose;
|
||||
import io.ebeaninternal.api.*;
|
||||
import io.ebeaninternal.server.util.Str;
|
||||
import io.ebeaninternal.server.persist.Binder;
|
||||
import io.ebeaninternal.server.persist.TrimLogSql;
|
||||
import io.ebeaninternal.server.util.BindParamsParser;
|
||||
@@ -151,7 +150,7 @@ public abstract class AbstractSqlQueryRequest implements CancelableQuery {
|
||||
}
|
||||
if (isLogSql()) {
|
||||
long micros = (System.nanoTime() - startNano) / 1000L;
|
||||
transaction.logSql(Str.add(TrimLogSql.trim(sql), "; --bind(", bindLog, ") --micros(", micros + ")"));
|
||||
transaction.logSql("{0}; --bind({1}) --micros({2})", TrimLogSql.trim(sql), bindLog, micros);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
|
||||
@@ -14,10 +14,11 @@ import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import io.ebeaninternal.server.transaction.DefaultPersistenceContext;
|
||||
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
|
||||
/**
|
||||
* Helper to handle lazy loading and refreshing of beans.
|
||||
@@ -137,8 +138,12 @@ final class DefaultBeanLoader {
|
||||
|
||||
SpiQuery<?> query = server.createQuery(loadRequest.beanType());
|
||||
loadRequest.configureQuery(query, idList);
|
||||
List<?> list = executeQuery(loadRequest, query);
|
||||
loadRequest.postLoad(list);
|
||||
final List<?> list = executeQuery(loadRequest, query);
|
||||
final LoadBeanRequest.Result result = loadRequest.postLoad(list);
|
||||
if (result.markedDeleted() && CoreLog.markedAsDeleted.isLoggable(DEBUG)) {
|
||||
String msg = MessageFormat.format("Loaded bean marked as deleted for {0} missedIds:{1} loadedIds:{2} sql:{3} list:{4}", loadRequest.beanType(), result.missedIds(), result.loadedIds(), query.getGeneratedSql(), list);
|
||||
CoreLog.markedAsDeleted.log(DEBUG, msg, new RuntimeException("LoadBeanRequest markedAsDeleted"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -229,6 +229,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
persistenceContext.beginIterate();
|
||||
}
|
||||
loadContext = new DLoadContext(this, secondaryQueries);
|
||||
loadContext.useReferences(Type.ITERATE == query.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -700,8 +701,8 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
/**
|
||||
* Log the SQL if the logLevel is appropriate.
|
||||
*/
|
||||
public void logSql(String sql) {
|
||||
transaction.logSql(sql);
|
||||
public void logSql(String msg, Object... args) {
|
||||
transaction.logSql(msg, args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -928,20 +928,20 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
}
|
||||
|
||||
private void logSummaryMessage() {
|
||||
String draft = (beanDescriptor.isDraftable() && !publish) ? "] draft[true]" : "]";
|
||||
String draft = (beanDescriptor.isDraftable() && !publish) ? " draft[true]" : "";
|
||||
String name = beanDescriptor.name();
|
||||
switch (type) {
|
||||
case INSERT:
|
||||
transaction.logSummary("Inserted [" + name + "] [" + (idValue == null ? "" : idValue) + draft);
|
||||
transaction.logSummary("Inserted [{0}] [{1}]{2}", name, (idValue == null ? "" : idValue), draft);
|
||||
break;
|
||||
case UPDATE:
|
||||
transaction.logSummary("Updated [" + name + "] [" + idValue + draft);
|
||||
transaction.logSummary("Updated [{0}] [{1}]{2}", name, idValue , draft);
|
||||
break;
|
||||
case DELETE:
|
||||
transaction.logSummary("Deleted [" + name + "] [" + idValue + draft);
|
||||
transaction.logSummary("Deleted [{0}] [{1}]{2}", name, idValue , draft);
|
||||
break;
|
||||
case DELETE_SOFT:
|
||||
transaction.logSummary("SoftDelete [" + name + "] [" + idValue + draft);
|
||||
transaction.logSummary("SoftDelete [{0}] [{1}]{2}", name, idValue , draft);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
+2
-6
@@ -1,12 +1,8 @@
|
||||
package io.ebeaninternal.server.core;
|
||||
|
||||
import io.ebean.CallableSql;
|
||||
import io.ebeaninternal.api.BindParams;
|
||||
import io.ebeaninternal.api.*;
|
||||
import io.ebeaninternal.api.BindParams.Param;
|
||||
import io.ebeaninternal.api.SpiCallableSql;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
import io.ebeaninternal.api.TransactionEventTable;
|
||||
import io.ebeaninternal.server.persist.PersistExecute;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
@@ -86,7 +82,7 @@ public final class PersistRequestCallableSql extends PersistRequest {
|
||||
persistExecute.collectSqlCall(label, startNanos);
|
||||
}
|
||||
if (transaction.isLogSummary()) {
|
||||
transaction.logSummary("CallableSql label[" + callableSql.getLabel() + "]" + " rows[" + rowCount + "]" + " bind[" + bindLog + "]");
|
||||
transaction.logSummary("CallableSql label[{0}] rows[{1}] bind[{2}]", callableSql.getLabel(), rowCount, bindLog);
|
||||
}
|
||||
|
||||
// register table modifications with the transaction event
|
||||
|
||||
@@ -83,7 +83,7 @@ public final class PersistRequestOrmUpdate extends PersistRequest {
|
||||
OrmUpdateType ormUpdateType = ormUpdate.getOrmUpdateType();
|
||||
String tableName = ormUpdate.getBaseTable();
|
||||
if (transaction.isLogSummary()) {
|
||||
transaction.logSummary(ormUpdateType + " table[" + tableName + "] rows[" + rowCount + "] bind[" + bindLog + "]");
|
||||
transaction.logSummary("{0} table[{1}] rows[{2}] bind[{3}]", ormUpdateType, tableName, rowCount, bindLog);
|
||||
}
|
||||
if (ormUpdate.isNotifyCache()) {
|
||||
// add the modification info to the TransactionEvent
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.ebeaninternal.server.core;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiSqlUpdate;
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
import io.ebeaninternal.server.util.Str;
|
||||
import io.ebeaninternal.server.persist.BatchControl;
|
||||
import io.ebeaninternal.server.persist.PersistExecute;
|
||||
import io.ebeaninternal.server.persist.TrimLogSql;
|
||||
@@ -148,7 +147,7 @@ public final class PersistRequestUpdateSql extends PersistRequest {
|
||||
*/
|
||||
public void logSqlBatchBind() {
|
||||
if (transaction.isLogSql()) {
|
||||
transaction.logSql(Str.add(" -- bind(", bindLog, ")"));
|
||||
transaction.logSql(" -- bind({0})", bindLog);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +160,7 @@ public final class PersistRequestUpdateSql extends PersistRequest {
|
||||
persistExecute.collectSqlUpdate(label, startNanos);
|
||||
}
|
||||
if (transaction.isLogSql() && !batchThisRequest) {
|
||||
transaction.logSql(Str.add(TrimLogSql.trim(updateSql.getGeneratedSql()), "; -- bind(", bindLog, ") rows(", String.valueOf(rowCount), ")"));
|
||||
transaction.logSql("{0}; -- bind({1}) rows({2})", TrimLogSql.trim(updateSql.getGeneratedSql()), bindLog, rowCount);
|
||||
}
|
||||
if (updateSql.isAutoTableMod()) {
|
||||
// add the modification info to the TransactionEvent
|
||||
|
||||
@@ -123,7 +123,7 @@ public final class RelationalQueryRequest extends AbstractSqlQueryRequest {
|
||||
public void logSummary() {
|
||||
if (transaction.isLogSummary()) {
|
||||
long micros = (System.nanoTime() - startNano) / 1000L;
|
||||
transaction.logSummary("SqlQuery rows[" + rows + "] micros[" + micros + "] bind[" + bindLog + "]");
|
||||
transaction.logSummary("SqlQuery rows[{0}] micros[{1}] bind[{2}]", rows, micros, bindLog);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,13 +38,10 @@ public final class BeanCollectionUtil {
|
||||
// returns a collection of beans
|
||||
return bc.getActualEntries();
|
||||
}
|
||||
|
||||
if (o instanceof Map<?, ?>) {
|
||||
// yes, we want the entrySet (to set the keys)
|
||||
return ((Map<?, ?>) o).entrySet();
|
||||
|
||||
} else if (o instanceof Collection<?>) {
|
||||
if (o instanceof Collection<?>) {
|
||||
return ((Collection<?>) o);
|
||||
} else if (o instanceof Map<?, ?>) {
|
||||
return ((Map<?, ?>) o).entrySet();
|
||||
}
|
||||
throw new PersistenceException("expecting a Map or Collection but got " + o.getClass().getName());
|
||||
}
|
||||
|
||||
@@ -1268,4 +1268,10 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionList<T> clear() {
|
||||
list.clear();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1068,4 +1068,9 @@ final class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expr
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionList<T> clear() {
|
||||
return exprList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ public final class DLoadContext implements LoadContext {
|
||||
private final ProfilingListener profilingListener;
|
||||
private final Map<String, ObjectGraphNode> nodePathMap = new HashMap<>();
|
||||
private final PersistenceContext persistenceContext;
|
||||
boolean useReferences;
|
||||
private List<OrmQueryProperties> secQuery;
|
||||
private Object tenantId;
|
||||
|
||||
@@ -118,7 +119,6 @@ public final class DLoadContext implements LoadContext {
|
||||
this.origin = null;
|
||||
this.relativePath = null;
|
||||
}
|
||||
|
||||
// initialise rootBeanContext after origin and relativePath have been set
|
||||
this.rootBeanContext = new DLoadBeanContext(this, rootDescriptor, null, null);
|
||||
registerSecondaryQueries(secondaryQueries);
|
||||
@@ -156,6 +156,11 @@ public final class DLoadContext implements LoadContext {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void useReferences(boolean useReferences) {
|
||||
this.useReferences = useReferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the load context at this path with OrmQueryProperties which is
|
||||
* used to build the appropriate query for +query or +lazy loading.
|
||||
|
||||
+127
-23
@@ -14,7 +14,10 @@ import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import io.ebeaninternal.server.querydefn.OrmQueryProperties;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@@ -38,7 +41,7 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
|
||||
}
|
||||
|
||||
private LoadBuffer createBuffer(int size) {
|
||||
LoadBuffer buffer = new LoadBuffer(this, size);
|
||||
LoadBuffer buffer = parent.useReferences ? new LoadBufferWeakRef(this, size) : new LoadBufferHardRef(this, size);
|
||||
if (bufferList != null) {
|
||||
bufferList.add(buffer);
|
||||
}
|
||||
@@ -94,7 +97,7 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
|
||||
try {
|
||||
if (bufferList != null) {
|
||||
for (LoadBuffer loadBuffer : bufferList) {
|
||||
if (!loadBuffer.list.isEmpty()) {
|
||||
if (loadBuffer.size() > 0) {
|
||||
LoadManyRequest req = new LoadManyRequest(loadBuffer, parentRequest);
|
||||
parent.getEbeanServer().loadMany(req);
|
||||
}
|
||||
@@ -115,13 +118,12 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
|
||||
* A buffer for batch loading bean collections on a given path.
|
||||
* Supports batch lazy loading and secondary query loading.
|
||||
*/
|
||||
static class LoadBuffer implements BeanCollectionLoader, LoadManyBuffer {
|
||||
static abstract class LoadBuffer implements BeanCollectionLoader, LoadManyBuffer {
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
private final PersistenceContext persistenceContext;
|
||||
private final DLoadManyContext context;
|
||||
private final int batchSize;
|
||||
private final List<BeanCollection<?>> list;
|
||||
final int batchSize;
|
||||
|
||||
LoadBuffer(DLoadManyContext context, int batchSize) {
|
||||
this.context = context;
|
||||
@@ -129,7 +131,6 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
|
||||
// case it changes as part of a findIterate etc
|
||||
this.persistenceContext = context.getPersistenceContext();
|
||||
this.batchSize = batchSize;
|
||||
this.list = new ArrayList<>(batchSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,7 +139,7 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBatchSize() {
|
||||
public int batchSize() {
|
||||
return batchSize;
|
||||
}
|
||||
|
||||
@@ -146,20 +147,15 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
|
||||
* Return true if the buffer is full.
|
||||
*/
|
||||
public boolean isFull() {
|
||||
return batchSize == list.size();
|
||||
return batchSize() == size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the buffer is full.
|
||||
*/
|
||||
public void add(BeanCollection<?> bc) {
|
||||
list.add(bc);
|
||||
}
|
||||
public abstract void add(BeanCollection<?> bc);
|
||||
|
||||
@Override
|
||||
public List<BeanCollection<?>> getBatch() {
|
||||
return list;
|
||||
}
|
||||
abstract void clear();
|
||||
|
||||
@Override
|
||||
public BeanPropertyAssocMany<?> getBeanProperty() {
|
||||
@@ -208,25 +204,133 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext
|
||||
final String parentKey = parentDesc.cacheKey(parentId);
|
||||
if (parentDesc.cacheManyPropLoad(context.property, bc, parentKey, context.parent.isReadOnly())) {
|
||||
// we loaded the bean collection from cache so remove it from the buffer
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
// find it using instance equality - avoiding equals() and potential deadlock issue
|
||||
if (list.get(i) == bc) {
|
||||
list.remove(i);
|
||||
bc.setLoader(context.parent.getEbeanServer());
|
||||
return;
|
||||
}
|
||||
if (removeFromBuffer(bc)) {
|
||||
bc.setLoader(context.parent.getEbeanServer());
|
||||
}
|
||||
// find it using instance equality - avoiding equals() and potential deadlock issue
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
context.parent.getEbeanServer().loadMany(new LoadManyRequest(this, onlyIds, useCache));
|
||||
// clear the buffer as all entries have been loaded
|
||||
list.clear();
|
||||
clear();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class LoadBufferHardRef extends LoadBuffer {
|
||||
private final BeanCollection<?>[] list;
|
||||
|
||||
private int size;
|
||||
|
||||
LoadBufferHardRef(DLoadManyContext context, int batchSize) {
|
||||
super(context, batchSize);
|
||||
this.list = new BeanCollection<?>[batchSize];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the buffer is full.
|
||||
*/
|
||||
@Override
|
||||
public void add(BeanCollection<?> bc) {
|
||||
list[size++] = bc;
|
||||
}
|
||||
|
||||
@Override
|
||||
void clear() {
|
||||
Arrays.fill(list, null);
|
||||
size = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollection<?> get(int i) {
|
||||
return list[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFromBuffer(BeanCollection<?> collection) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
// find it using instance equality - avoiding equals() and potential deadlock issue
|
||||
if (list[i] == collection) {
|
||||
list[i] = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This load buffer uses weak references, so unreachable beanCollections will drop out from the buffer.
|
||||
*/
|
||||
static class LoadBufferWeakRef extends LoadBuffer {
|
||||
private final Reference<BeanCollection<?>>[] list;
|
||||
|
||||
private int size;
|
||||
|
||||
LoadBufferWeakRef(DLoadManyContext context, int batchSize) {
|
||||
super(context, batchSize);
|
||||
this.list = new Reference[batchSize];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the buffer is full.
|
||||
*/
|
||||
@Override
|
||||
public void add(BeanCollection<?> bc) {
|
||||
list[size++] = new WeakReference<>(bc);
|
||||
}
|
||||
|
||||
@Override
|
||||
void clear() {
|
||||
Arrays.fill(list, null);
|
||||
size = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollection<?> get(int i) {
|
||||
Reference<BeanCollection<?>> ref = list[i];
|
||||
if (ref == null) {
|
||||
return null;
|
||||
}
|
||||
BeanCollection<?> bc = ref.get();
|
||||
if (bc == null) {
|
||||
// remove dead references
|
||||
list[i] = null;
|
||||
}
|
||||
return bc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFromBuffer(BeanCollection<?> collection) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (list[i] != null) {
|
||||
BeanCollection<?> bc = list[i].get();
|
||||
if (bc == null) {
|
||||
// remove dead references
|
||||
list[i] = null;
|
||||
}
|
||||
// find it using instance equality - avoiding equals() and potential deadlock issue
|
||||
if (bc == collection) {
|
||||
list[i] = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,22 +2,30 @@ package io.ebeaninternal.server.logger;
|
||||
|
||||
import io.ebeaninternal.api.SpiLogManager;
|
||||
import io.ebeaninternal.api.SpiLogger;
|
||||
import io.ebeaninternal.api.SpiTxnLogger;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public final class DLogManager implements SpiLogManager {
|
||||
|
||||
private final SpiLogger sql;
|
||||
private final SpiLogger summary;
|
||||
private final SpiLogger txn;
|
||||
private final boolean useIds;
|
||||
private final AtomicLong counter = new AtomicLong(1000);
|
||||
private final DTxnLogger readOnly;
|
||||
|
||||
public DLogManager(SpiLogger sql, SpiLogger summary, SpiLogger txn) {
|
||||
this.sql = sql;
|
||||
this.summary = summary;
|
||||
this.txn = txn;
|
||||
this.useIds = txn.isDebug();
|
||||
this.readOnly = new DTxnLogger(null, sql, summary, txn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpiLogger txn() {
|
||||
return txn;
|
||||
public boolean enableBindLog() {
|
||||
return sql.isDebug();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -26,8 +34,13 @@ public final class DLogManager implements SpiLogManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpiLogger sum() {
|
||||
return summary;
|
||||
public SpiTxnLogger logger() {
|
||||
String id = useIds ? Long.toString(counter.incrementAndGet()) : "";
|
||||
return new DTxnLogger(id, sql, summary, txn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpiTxnLogger readOnlyLogger() {
|
||||
return readOnly;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.ebeaninternal.server.logger;
|
||||
import io.ebeaninternal.api.SpiLogger;
|
||||
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
import static java.lang.System.Logger.Level.TRACE;
|
||||
|
||||
final class DSpiLogger implements SpiLogger {
|
||||
|
||||
@@ -19,17 +18,7 @@ final class DSpiLogger implements SpiLogger {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrace() {
|
||||
return logger.isLoggable(TRACE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String msg) {
|
||||
logger.log(DEBUG, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(String msg) {
|
||||
logger.log(TRACE, msg);
|
||||
public void debug(String msg, Object... args) {
|
||||
logger.log(DEBUG, msg, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package io.ebeaninternal.server.logger;
|
||||
|
||||
import io.ebeaninternal.api.SpiLogger;
|
||||
import io.ebeaninternal.api.SpiTxnLogger;
|
||||
import io.ebeaninternal.server.util.Str;
|
||||
|
||||
final class DTxnLogger implements SpiTxnLogger {
|
||||
|
||||
private final String id;
|
||||
private final String logPrefix;
|
||||
private final SpiLogger sql;
|
||||
private final SpiLogger sum;
|
||||
private final SpiLogger txn;
|
||||
|
||||
DTxnLogger(String id, SpiLogger sql, SpiLogger sum, SpiLogger txn) {
|
||||
this.id = id;
|
||||
this.logPrefix = id == null ? "" : "txn[" + id + "] ";
|
||||
this.sql = sql;
|
||||
this.sum = sum;
|
||||
this.txn = txn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogSql() {
|
||||
return sql.isDebug();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogSummary() {
|
||||
return sum.isDebug();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sql(String msg, Object... args) {
|
||||
sql.debug(Str.add(logPrefix, msg), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sum(String msg, Object... args) {
|
||||
sum.debug(Str.add(logPrefix, msg), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void txn(String msg, Object... args) {
|
||||
txn.debug(Str.add(logPrefix, msg), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyCommit() {
|
||||
txn.debug(Str.add(logPrefix, "Commit"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyQueryOnly() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyRollback(Throwable cause) {
|
||||
if (txn.isDebug()) {
|
||||
String msg = logPrefix + "Rollback";
|
||||
if (cause != null) {
|
||||
msg += " error: " + formatThrowable(cause);
|
||||
}
|
||||
txn.debug(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private String formatThrowable(Throwable e) {
|
||||
if (e == null) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
formatThrowable(e, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void formatThrowable(Throwable e, StringBuilder sb) {
|
||||
sb.append(e.toString());
|
||||
StackTraceElement[] stackTrace = e.getStackTrace();
|
||||
if (stackTrace.length > 0) {
|
||||
sb.append(" stack0: ");
|
||||
sb.append(stackTrace[0]);
|
||||
}
|
||||
Throwable cause = e.getCause();
|
||||
if (cause != null) {
|
||||
sb.append(" cause: ");
|
||||
formatThrowable(cause, sb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,7 +313,7 @@ public final class BatchControl {
|
||||
BatchedBeanHolder[] bsArray = beanHolderArray();
|
||||
Arrays.sort(bsArray, depthComparator);
|
||||
if (transaction.isLogSummary()) {
|
||||
transaction.logSummary("BatchControl flush " + Arrays.toString(bsArray));
|
||||
transaction.logSummary("BatchControl flush {0}", Arrays.toString(bsArray));
|
||||
}
|
||||
for (BatchedBeanHolder beanHolder : bsArray) {
|
||||
beanHolder.executeNow();
|
||||
|
||||
@@ -44,7 +44,7 @@ public final class Binder {
|
||||
this.dbExpressionHandler = dbExpressionHandler;
|
||||
this.dataTimeZone = dataTimeZone;
|
||||
this.multiValueBind = multiValueBind;
|
||||
this.enableBindLog = logManager.sql().isDebug();
|
||||
this.enableBindLog = logManager.enableBindLog();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -672,7 +672,7 @@ public final class DefaultPersister implements Persister {
|
||||
if (idList != null) {
|
||||
q.where().idIn(idList);
|
||||
if (t.isLogSummary()) {
|
||||
t.logSummary("-- DeleteById of " + descriptor.name() + " ids[" + idList + "] requires fetch of foreign key values");
|
||||
t.logSummary("-- DeleteById of {0} ids[{1}] requires fetch of foreign key values", descriptor.name(), idList);
|
||||
}
|
||||
List<?> beanList = server.findList(q, t);
|
||||
deleteCascade(beanList, t, deleteMode, false);
|
||||
@@ -681,7 +681,7 @@ public final class DefaultPersister implements Persister {
|
||||
} else {
|
||||
q.where().idEq(id);
|
||||
if (t.isLogSummary()) {
|
||||
t.logSummary("-- DeleteById of " + descriptor.name() + " id[" + id + "] requires fetch of foreign key values");
|
||||
t.logSummary("-- DeleteById of {0} id[{1}] requires fetch of foreign key values", descriptor.name(), id);
|
||||
}
|
||||
EntityBean bean = (EntityBean) server.findOne(q, t);
|
||||
if (bean == null) {
|
||||
@@ -741,7 +741,7 @@ public final class DefaultPersister implements Persister {
|
||||
for (BeanPropertyAssocMany<?> many : manys) {
|
||||
SqlUpdate sqlDelete = many.deleteByParentId(id, idList);
|
||||
if (t.isLogSummary()) {
|
||||
t.logSummary("-- Deleting intersection table entries: " + many.fullName());
|
||||
t.logSummary("-- Deleting intersection table entries: {0}", many.fullName());
|
||||
}
|
||||
executeSqlUpdate(sqlDelete, t);
|
||||
}
|
||||
@@ -751,9 +751,9 @@ public final class DefaultPersister implements Persister {
|
||||
SqlUpdate deleteById = descriptor.deleteById(id, idList, deleteMode);
|
||||
if (t.isLogSummary()) {
|
||||
if (idList != null) {
|
||||
t.logSummary("-- Deleting " + descriptor.name() + " Ids: " + idList);
|
||||
t.logSummary("-- Deleting {0} Ids: {1}", descriptor.name(), idList);
|
||||
} else {
|
||||
t.logSummary("-- Deleting " + descriptor.name() + " Id: " + id);
|
||||
t.logSummary("-- Deleting {0} Id: {1}", descriptor.name(), id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -861,7 +861,7 @@ public final class DefaultPersister implements Persister {
|
||||
SpiTransaction t = request.transaction();
|
||||
EntityBean orphanForRemoval = request.importedOrphanForRemoval();
|
||||
if (orphanForRemoval != null) {
|
||||
delete(orphanForRemoval, request.transaction(), true);
|
||||
delete(orphanForRemoval, request.transaction(), false);
|
||||
}
|
||||
|
||||
// exported ones with cascade save
|
||||
@@ -1079,7 +1079,7 @@ public final class DefaultPersister implements Persister {
|
||||
private void deleteOrphan(PersistRequestBean<?> request, BeanPropertyAssocOne<?> prop) {
|
||||
Object origValue = request.getOrigValue(prop);
|
||||
if (origValue instanceof EntityBean) {
|
||||
delete((EntityBean) origValue, request.transaction(), true);
|
||||
delete((EntityBean) origValue, request.transaction(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ final class DeleteUnloadedForeignKeys {
|
||||
|
||||
SpiTransaction t = request.transaction();
|
||||
if (t.isLogSummary()) {
|
||||
t.logSummary("-- Ebean fetching foreign key values for delete of " + descriptor.name() + " id:" + id);
|
||||
t.logSummary("-- Ebean fetching foreign key values for delete of {0} id:{1}", descriptor.name(), id);
|
||||
}
|
||||
beanWithForeignKeys = (EntityBean) server.findOne(q, t);
|
||||
}
|
||||
|
||||
@@ -35,8 +35,9 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
private final boolean untouchedBeanCollection;
|
||||
private final Collection<?> collection;
|
||||
private final boolean hasOrderColumn;
|
||||
private final boolean forcedUpdate;
|
||||
private int sortOrder;
|
||||
private boolean insertAllChildren;
|
||||
private boolean forceOrphanRemoval;
|
||||
|
||||
SaveManyBeans(DefaultPersister persister, boolean insertedParent, BeanPropertyAssocMany<?> many, EntityBean parentBean, PersistRequestBean<?> request) {
|
||||
super(persister, insertedParent, many, parentBean, request);
|
||||
@@ -49,6 +50,7 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
this.untouchedBeanCollection = untouchedBeanCollection();
|
||||
this.collection = cascade ? BeanCollectionUtil.getActualEntries(value) : null;
|
||||
this.hasOrderColumn = many.hasOrderColumn();
|
||||
this.forcedUpdate = request.isForcedUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,10 +129,8 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
targetDescriptor.preAllocateIds(collection.size());
|
||||
}
|
||||
if (forcedUpdateOrphanRemoval()) {
|
||||
// collect the Id's (to exclude from deleteManyDetails)
|
||||
List<Object> detailIds = collectIds(collection, targetDescriptor, isMap);
|
||||
// deleting missing children - children not in our collected detailIds
|
||||
persister.deleteManyDetails(transaction, many.descriptor(), parentBean, many, detailIds, deleteMode);
|
||||
// deleting orphans, anything not in our detailsIds
|
||||
persister.deleteManyDetails(transaction, many.descriptor(), parentBean, many, detailIds(), deleteMode);
|
||||
}
|
||||
transaction.depth(+1);
|
||||
saveAllBeans(orderColumn);
|
||||
@@ -141,7 +141,7 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
}
|
||||
|
||||
private boolean forcedUpdateOrphanRemoval() {
|
||||
return !insertedParent && many.isOrphanRemoval() && request.isForcedUpdate();
|
||||
return !insertedParent && many.isOrphanRemoval() && (forceOrphanRemoval || forcedUpdate);
|
||||
}
|
||||
|
||||
private void saveAllBeans(final BeanProperty orderColumn) {
|
||||
@@ -177,10 +177,6 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
skipSavingThisBean = false;
|
||||
// set the parent bean to detailBean
|
||||
many.setJoinValuesToChild(parentBean, detail, mapKeyValue);
|
||||
} else if (insertAllChildren) {
|
||||
ebi.setNew();
|
||||
skipSavingThisBean = false;
|
||||
many.setJoinValuesToChild(parentBean, detail, mapKeyValue);
|
||||
} else {
|
||||
skipSavingThisBean = saveRecurseSkippable;
|
||||
}
|
||||
@@ -215,12 +211,10 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the Id values of the details to remove 'missing children' for stateless updates.
|
||||
* Return the Id values of beans we know are being updated (any others are orphans)
|
||||
*/
|
||||
private List<Object> collectIds(Collection<?> collection, BeanDescriptor<?> targetDescriptor, boolean isMap) {
|
||||
List<Object> detailIds = new ArrayList<>();
|
||||
// stateless update with deleteMissingChildren so first
|
||||
// collect the Id values to remove the 'missing children'
|
||||
private List<Object> detailIds() {
|
||||
final var detailIds = new ArrayList<>();
|
||||
for (Object detailBean : collection) {
|
||||
if (isMap) {
|
||||
detailBean = ((Map.Entry<?, ?>) detailBean).getValue();
|
||||
@@ -228,8 +222,10 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
if (detailBean instanceof EntityBean) {
|
||||
Object id = targetDescriptor.id(detailBean);
|
||||
if (!isNullOrZero(id)) {
|
||||
// remember the Id (other details not in the collection) will be removed
|
||||
detailIds.add(id);
|
||||
if (forcedUpdate || !((EntityBean) detailBean)._ebean_getIntercept().isNew()) {
|
||||
// Id of bean that will be updated, exclude it from orphan removal
|
||||
detailIds.add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -261,8 +257,7 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
}
|
||||
|
||||
private void saveAssocManyIntersection(boolean queue) {
|
||||
boolean forcedUpdate = request.isForcedUpdate();
|
||||
boolean vanillaCollection = !(value instanceof BeanCollection<?>);
|
||||
final boolean vanillaCollection = !(value instanceof BeanCollection<?>);
|
||||
if (vanillaCollection || forcedUpdate) {
|
||||
// delete all intersection rows and then treat all
|
||||
// beans in the collection as additions
|
||||
@@ -321,7 +316,7 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
CoreLog.log.log(System.Logger.Level.WARNING, m);
|
||||
} else {
|
||||
if (!many.hasImportedId(otherBean)) {
|
||||
throw new PersistenceException("ManyToMany bean " + otherBean + " does not have an Id value.");
|
||||
throw new PersistenceException("ManyToMany bean does not have an Id value? " + otherBean);
|
||||
} else {
|
||||
// build a intersection row for 'insert'
|
||||
IntersectionRow intRow = many.buildManyToManyMapBean(parentBean, otherBean, publish);
|
||||
@@ -344,10 +339,7 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
return;
|
||||
}
|
||||
if (!(value instanceof BeanCollection<?>)) {
|
||||
if (!forcedUpdateOrphanRemoval() && (!insertedParent && cascade && isChangedProperty())) {
|
||||
persister.addToFlushQueue(many.deleteByParentId(request.beanId(), null), transaction, 0);
|
||||
insertAllChildren = true;
|
||||
}
|
||||
forceOrphanRemoval = !insertedParent && isChangedProperty();
|
||||
} else {
|
||||
BeanCollection<?> c = (BeanCollection<?>) value;
|
||||
Set<?> modifyRemovals = c.getModifyRemovals();
|
||||
@@ -359,7 +351,9 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
if (!hasOrderColumn) {
|
||||
c.modifyReset();
|
||||
}
|
||||
if (modifyRemovals != null && !modifyRemovals.isEmpty()) {
|
||||
if (modifyRemovals == null || modifyRemovals.isEmpty()) {
|
||||
forceOrphanRemoval = !insertedParent && isChangedProperty();
|
||||
} else {
|
||||
for (Object removedBean : modifyRemovals) {
|
||||
if (removedBean instanceof EntityBean) {
|
||||
EntityBean eb = (EntityBean) removedBean;
|
||||
|
||||
@@ -8,7 +8,6 @@ import io.ebeaninternal.server.persist.BatchedPstmt;
|
||||
import io.ebeaninternal.server.persist.BatchedPstmtHolder;
|
||||
import io.ebeaninternal.server.persist.dmlbind.BindableRequest;
|
||||
import io.ebeaninternal.server.bind.DataBind;
|
||||
import io.ebeaninternal.server.util.Str;
|
||||
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import java.sql.Connection;
|
||||
@@ -102,7 +101,7 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
|
||||
} catch (OptimisticLockException e) {
|
||||
// add the SQL and bind values to error message
|
||||
final String m = e.getMessage() + " sql[" + sql + "] bind[" + bindLog + "]";
|
||||
persistRequest.transaction().logSummary("OptimisticLockException:" + m);
|
||||
persistRequest.transaction().logSummary("OptimisticLockException:{0}", m);
|
||||
throw new OptimisticLockException(m, null, e.getEntity());
|
||||
}
|
||||
}
|
||||
@@ -146,15 +145,15 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
|
||||
switch (batchedStatus) {
|
||||
case BATCHED_FIRST: {
|
||||
transaction.logSql(sql);
|
||||
transaction.logSql(Str.add(" -- bind(", bindLog.toString(), ")"));
|
||||
transaction.logSql(" -- bind({0})", bindLog);
|
||||
return;
|
||||
}
|
||||
case BATCHED: {
|
||||
transaction.logSql(Str.add(" -- bind(", bindLog.toString(), ")"));
|
||||
transaction.logSql(" -- bind({0})", bindLog);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
transaction.logSql(Str.add(sql, "; -- bind(", bindLog.toString(), ")"));
|
||||
transaction.logSql("{0}; -- bind({1})", sql, bindLog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import io.ebeaninternal.server.core.OrmQueryRequest;
|
||||
import io.ebeaninternal.server.core.SpiResultSet;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.persist.Binder;
|
||||
import io.ebeaninternal.server.util.Str;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.sql.ResultSet;
|
||||
@@ -73,7 +72,7 @@ public final class CQueryEngine {
|
||||
try {
|
||||
int rows = query.execute();
|
||||
if (request.logSql()) {
|
||||
request.logSql(Str.add(query.generatedSql(), "; --bind(", query.bindLog(), ") --micros(", query.micros() + ") --rows(", rows + ")"));
|
||||
request.logSql("{0}; --bind({1}) --micros({2}) --rows({3})", query.generatedSql(), query.bindLog(), query.micros(), rows);
|
||||
}
|
||||
return rows;
|
||||
} catch (SQLException e) {
|
||||
@@ -129,7 +128,7 @@ public final class CQueryEngine {
|
||||
SpiTransaction t = request.transaction();
|
||||
if (t.isLogSummary()) {
|
||||
// log the error to the transaction log
|
||||
t.logSummary("ERROR executing query, bindLog[" + bindLog + "] error:" + StringHelper.removeNewLines(e.getMessage()));
|
||||
t.logSummary("ERROR executing query, bindLog[{0}] error:{1}", bindLog, StringHelper.removeNewLines(e.getMessage()));
|
||||
}
|
||||
// ensure 'rollback' is logged if queryOnly transaction
|
||||
t.connection();
|
||||
@@ -147,7 +146,7 @@ public final class CQueryEngine {
|
||||
}
|
||||
|
||||
private <T> void logGeneratedSql(OrmQueryRequest<T> request, String sql, String bindLog, long micros) {
|
||||
request.logSql(Str.add(sql, "; --bind(", bindLog, ") --micros(", micros + ")"));
|
||||
request.logSql("{0}; --bind({1}) --micros({2})", sql, bindLog, micros);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -403,7 +402,7 @@ public final class CQueryEngine {
|
||||
* Log the generated SQL to the transaction log.
|
||||
*/
|
||||
private void logSql(CQuery<?> query) {
|
||||
query.transaction().logSql(Str.add(query.generatedSql(), "; --bind(", query.bindLog(), ") --micros(", query.micros() + ")"));
|
||||
query.transaction().logSql("{0}; --bind({1}) --micros({2})", query.generatedSql(), query.bindLog(), query.micros());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.ebean.bean.EntityBean;
|
||||
import io.ebean.bean.EntityBeanIntercept;
|
||||
import io.ebean.bean.PersistenceContext;
|
||||
import io.ebean.core.type.ScalarDataReader;
|
||||
import io.ebeaninternal.api.CoreLog;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.SpiQuery.Mode;
|
||||
import io.ebeaninternal.server.deploy.DbReadContext;
|
||||
@@ -14,6 +15,8 @@ import io.ebeaninternal.server.deploy.id.IdBinder;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
|
||||
/**
|
||||
* Normal bean included in the query.
|
||||
*/
|
||||
@@ -211,6 +214,9 @@ class SqlTreeLoadBean implements SqlTreeLoad {
|
||||
contextBean = ((STreePropertyAssocOne)nodeBeanProp).valueAsEntityBean(parentBean);
|
||||
if (contextBean != null) {
|
||||
desc.markAsDeleted(contextBean);
|
||||
if (CoreLog.markedAsDeleted.isLoggable(DEBUG)) {
|
||||
CoreLog.markedAsDeleted.log(DEBUG, contextBean + " contextBean markedAsDeleted", new RuntimeException(contextBean + " contextBean markedAsDeleted"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package io.ebeaninternal.server.querydefn;
|
||||
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.ebean.*;
|
||||
import io.ebean.OrderBy.Property;
|
||||
import io.ebean.bean.CallOrigin;
|
||||
import io.ebean.bean.ObjectGraphNode;
|
||||
import io.ebean.bean.ObjectGraphOrigin;
|
||||
@@ -420,7 +419,7 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
havingExpressions.containsMany(beanDescriptor, manyWhere);
|
||||
}
|
||||
if (orderBy != null) {
|
||||
for (Property orderProperty : orderBy.getProperties()) {
|
||||
for (OrderBy.Property orderProperty : orderBy.getProperties()) {
|
||||
ElPropertyDeploy elProp = beanDescriptor.elPropertyDeploy(orderProperty.getProperty());
|
||||
if (elProp != null && elProp.containsFormulaWithJoin()) {
|
||||
manyWhere.addFormulaWithJoin(elProp.elPrefix(), elProp.name());
|
||||
@@ -460,10 +459,10 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
for (OrmQueryProperties joinPath : queryJoins) {
|
||||
// loop through the orderBy properties and
|
||||
// move any ones related to the query join
|
||||
List<Property> properties = orderBy.getProperties();
|
||||
Iterator<Property> it = properties.iterator();
|
||||
List<OrderBy.Property> properties = orderBy.getProperties();
|
||||
Iterator<OrderBy.Property> it = properties.iterator();
|
||||
while (it.hasNext()) {
|
||||
Property property = it.next();
|
||||
OrderBy.Property property = it.next();
|
||||
if (property.getProperty().startsWith(joinPath.getPath())) {
|
||||
// remove this orderBy segment and
|
||||
// add it to the secondary join
|
||||
@@ -1963,7 +1962,7 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
havingExpressions.validate(validation);
|
||||
}
|
||||
if (orderBy != null) {
|
||||
for (Property property : orderBy.getProperties()) {
|
||||
for (OrderBy.Property property : orderBy.getProperties()) {
|
||||
validation.validate(property.getProperty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.ebeaninternal.server.querydefn;
|
||||
|
||||
import io.ebean.ExpressionList;
|
||||
import io.ebean.ProfileLocation;
|
||||
import io.ebean.Query;
|
||||
import io.ebean.UpdateQuery;
|
||||
import io.ebean.core.type.ScalarType;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
@@ -34,6 +35,16 @@ public final class DefaultUpdateQuery<T> implements UpdateQuery<T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <P> UpdateQuery<T> set(Query.Property<P> property, P value) {
|
||||
return set(property.toString(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateQuery<T> setNull(Query.Property<?> property) {
|
||||
return setNull(property.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateQuery<T> setNull(String property) {
|
||||
values.setNull(property);
|
||||
|
||||
+2
-2
@@ -10,8 +10,8 @@ public final class DocStoreOnlyTransaction extends JdbcTransaction {
|
||||
/**
|
||||
* Create a new DocStore only Transaction.
|
||||
*/
|
||||
public DocStoreOnlyTransaction(String id, boolean explicit, TransactionManager manager) {
|
||||
super(id, explicit, null, manager);
|
||||
public DocStoreOnlyTransaction(boolean explicit, TransactionManager manager) {
|
||||
super(explicit, null, manager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -25,11 +25,11 @@ public final class DocStoreTransactionManager extends TransactionManager {
|
||||
|
||||
@Override
|
||||
public SpiTransaction createReadOnlyTransaction(Object tenantId) {
|
||||
return new DocStoreOnlyTransaction("", false, this);
|
||||
return new DocStoreOnlyTransaction(false, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SpiTransaction createTransaction(boolean explicit, Connection c) {
|
||||
return new DocStoreOnlyTransaction(nextTxnId(), explicit, this);
|
||||
return new DocStoreOnlyTransaction(explicit, this);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -25,14 +25,14 @@ public class ExternalJdbcTransaction extends JdbcTransaction {
|
||||
* </p>
|
||||
*/
|
||||
public ExternalJdbcTransaction(Connection connection) {
|
||||
super(null, true, connection, null);
|
||||
super(true, connection, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct will all explicit parameters.
|
||||
*/
|
||||
public ExternalJdbcTransaction(String id, boolean explicit, Connection connection, TransactionManager manager) {
|
||||
super(id, explicit, connection, manager);
|
||||
public ExternalJdbcTransaction(boolean explicit, Connection connection, TransactionManager manager) {
|
||||
super(explicit, connection, manager);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+13
-11
@@ -33,6 +33,7 @@ final class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEve
|
||||
private static final String notExpectedMessage = "Not expected on read only transaction";
|
||||
|
||||
private final TransactionManager manager;
|
||||
private final SpiTxnLogger logger;
|
||||
private final boolean logSql;
|
||||
private final boolean logSummary;
|
||||
|
||||
@@ -61,8 +62,9 @@ final class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEve
|
||||
*/
|
||||
ImplicitReadOnlyTransaction(TransactionManager manager, Connection connection) {
|
||||
this.manager = manager;
|
||||
this.logSql = manager.isLogSql();
|
||||
this.logSummary = manager.isLogSummary();
|
||||
this.logger = manager.loggerReadOnly();
|
||||
this.logSql = logger.isLogSql();
|
||||
this.logSummary = logger.isLogSummary();
|
||||
this.active = true;
|
||||
this.connection = connection;
|
||||
this.persistenceContext = new DefaultPersistenceContext();
|
||||
@@ -147,11 +149,6 @@ final class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEve
|
||||
public void setSkipCache(boolean skipCache) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogPrefix() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBeanChange(BeanChange beanChange) {
|
||||
throw new IllegalStateException(notExpectedMessage);
|
||||
@@ -433,13 +430,18 @@ final class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEve
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSql(String msg) {
|
||||
manager.log().sql().debug(msg);
|
||||
public void logSql(String msg, Object... args) {
|
||||
logger.sql(msg, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSummary(String msg) {
|
||||
manager.log().sum().debug(msg);
|
||||
public void logSummary(String msg, Object... args) {
|
||||
logger.sum(msg, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logTxn(String msg, Object... args) {
|
||||
// never called
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,7 +11,6 @@ import io.ebeaninternal.server.core.PersistDeferredRelationship;
|
||||
import io.ebeaninternal.server.core.PersistRequestBean;
|
||||
import io.ebeaninternal.server.persist.BatchControl;
|
||||
import io.ebeaninternal.server.persist.BatchedSqlException;
|
||||
import io.ebeaninternal.server.util.Str;
|
||||
import io.ebeanservice.docstore.api.DocStoreTransaction;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
@@ -33,8 +32,8 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
|
||||
private static final String illegalStateMessage = "Transaction is Inactive";
|
||||
|
||||
final TransactionManager manager;
|
||||
private final SpiTxnLogger logger;
|
||||
private final String id;
|
||||
private final String logPrefix;
|
||||
private final boolean logSql;
|
||||
private final boolean logSummary;
|
||||
private final boolean explicit;
|
||||
@@ -95,17 +94,17 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
|
||||
private final long startNanos;
|
||||
private boolean autoPersistUpdates;
|
||||
|
||||
JdbcTransaction(String id, boolean explicit, Connection connection, TransactionManager manager) {
|
||||
JdbcTransaction(boolean explicit, Connection connection, TransactionManager manager) {
|
||||
try {
|
||||
this.active = true;
|
||||
this.id = id;
|
||||
this.logPrefix = deriveLogPrefix(id);
|
||||
this.explicit = explicit;
|
||||
this.manager = manager;
|
||||
this.connection = connection;
|
||||
this.persistenceContext = new DefaultPersistenceContext();
|
||||
this.startNanos = System.nanoTime();
|
||||
if (manager == null) {
|
||||
this.logger = null;
|
||||
this.id = "";
|
||||
this.logSql = false;
|
||||
this.logSummary = false;
|
||||
this.skipCacheAfterWrite = true;
|
||||
@@ -113,9 +112,11 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
|
||||
this.batchOnCascadeMode = false;
|
||||
this.onQueryOnlyCommit = false;
|
||||
} else {
|
||||
this.logger = manager.logger();
|
||||
this.id = logger.id();
|
||||
this.autoPersistUpdates = explicit && manager.isAutoPersistUpdates();
|
||||
this.logSql = manager.isLogSql();
|
||||
this.logSummary = manager.isLogSummary();
|
||||
this.logSql = logger.isLogSql();
|
||||
this.logSummary = logger.isLogSummary();
|
||||
this.skipCacheAfterWrite = manager.isSkipCacheAfterWrite();
|
||||
this.batchMode = manager.isPersistBatch();
|
||||
this.batchOnCascadeMode = manager.isPersistBatchOnCascade();
|
||||
@@ -188,16 +189,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
|
||||
}
|
||||
}
|
||||
|
||||
private static String deriveLogPrefix(String id) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("txn[");
|
||||
if (id != null) {
|
||||
sb.append(id);
|
||||
}
|
||||
sb.append("] ");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setAutoPersistUpdates(boolean autoPersistUpdates) {
|
||||
@@ -226,17 +218,13 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
|
||||
this.skipCache = skipCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getLogPrefix() {
|
||||
return logPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (active) {
|
||||
return logPrefix;
|
||||
return id;
|
||||
} else {
|
||||
return logPrefix + "(inactive)";
|
||||
return id + "(inactive)";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,13 +714,18 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void logSql(String msg) {
|
||||
manager.log().sql().debug(Str.add(logPrefix, msg));
|
||||
public void logSql(String msg, Object... args) {
|
||||
logger.sql(msg, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void logSummary(String msg) {
|
||||
manager.log().sum().debug(Str.add(logPrefix, msg));
|
||||
public final void logSummary(String msg, Object... args) {
|
||||
logger.sum(msg, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logTxn(String msg, Object... args) {
|
||||
logger.txn(msg, args);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -805,9 +798,11 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
|
||||
final void notifyCommit() {
|
||||
if (manager != null) {
|
||||
if (queryOnly) {
|
||||
logger.notifyQueryOnly();
|
||||
manager.notifyOfQueryOnly(this);
|
||||
} else {
|
||||
manager.notifyOfCommit(this);
|
||||
logger.notifyCommit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -966,6 +961,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
|
||||
manager.notifyOfQueryOnly(this);
|
||||
} else {
|
||||
manager.notifyOfRollback(this, cause);
|
||||
logger.notifyRollback(cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ public final class JtaTransaction extends JdbcTransaction {
|
||||
/**
|
||||
* Create the JtaTransaction.
|
||||
*/
|
||||
public JtaTransaction(String id, boolean explicit, UserTransaction utx, DataSource ds, TransactionManager manager) {
|
||||
super(id, explicit, null, manager);
|
||||
public JtaTransaction(boolean explicit, UserTransaction utx, DataSource ds, TransactionManager manager) {
|
||||
super(explicit, null, manager);
|
||||
userTransaction = utx;
|
||||
try {
|
||||
newTransaction = userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION;
|
||||
|
||||
+1
-2
@@ -105,8 +105,7 @@ public final class JtaTransactionManager implements ExternalTransactionManager {
|
||||
// This is a transaction that Ebean has not seen before.
|
||||
|
||||
// "wrap" it in a Ebean specific JtaTransaction
|
||||
String txnId = String.valueOf(System.currentTimeMillis());
|
||||
JtaTransaction newTrans = new JtaTransaction(txnId, true, ut, dataSource(), transactionManager);
|
||||
JtaTransaction newTrans = new JtaTransaction( true, ut, dataSource(), transactionManager);
|
||||
|
||||
// create and register transaction listener
|
||||
JtaTxnListener txnListener = createJtaTxnListener(newTrans);
|
||||
|
||||
@@ -117,10 +117,6 @@ final class NoTransaction implements SpiTransaction {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogPrefix() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogSql() {
|
||||
@@ -133,12 +129,17 @@ final class NoTransaction implements SpiTransaction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSql(String msg) {
|
||||
public void logSql(String msg, Object... args) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSummary(String msg) {
|
||||
public void logSummary(String msg, Object... args) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logTxn(String msg, Object... args) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
+7
-12
@@ -21,7 +21,6 @@ final class SavepointTransaction extends SpiTransactionProxy {
|
||||
private final TransactionManager manager;
|
||||
private final Savepoint savepoint;
|
||||
private final Connection connection;
|
||||
private final String logPrefix;
|
||||
private final String spPrefix;
|
||||
|
||||
private boolean rollbackOnly;
|
||||
@@ -33,13 +32,12 @@ final class SavepointTransaction extends SpiTransactionProxy {
|
||||
this.transaction = transaction;
|
||||
this.connection = transaction.getInternalConnection();
|
||||
this.savepoint = connection.setSavepoint();
|
||||
if (manager.isTxnDebug()) {
|
||||
if (transaction.isLogSql()) {
|
||||
int savepointId = manager.isSupportsSavepointId() ? savepoint.getSavepointId() : 0;
|
||||
this.spPrefix = "sp[" + savepointId + "] ";
|
||||
} else {
|
||||
this.spPrefix = "sp[] ";
|
||||
}
|
||||
this.logPrefix = transaction.getLogPrefix() + spPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,18 +49,13 @@ final class SavepointTransaction extends SpiTransactionProxy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogPrefix() {
|
||||
return logPrefix;
|
||||
public void logSql(String msg, Object... args) {
|
||||
transaction.logSql(Str.add(spPrefix, msg), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSql(String msg) {
|
||||
transaction.logSql(Str.add(spPrefix, msg));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logSummary(String msg) {
|
||||
transaction.logSummary(Str.add(spPrefix, msg));
|
||||
public void logSummary(String msg, Object... args) {
|
||||
transaction.logSummary(Str.add(spPrefix, msg), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,6 +92,7 @@ final class SavepointTransaction extends SpiTransactionProxy {
|
||||
connection.releaseSavepoint(savepoint);
|
||||
state = STATE_COMMITTED;
|
||||
manager.notifyOfCommit(this);
|
||||
transaction.logTxn(spPrefix + "commit");
|
||||
} catch (SQLException e) {
|
||||
throw new PersistenceException("Error trying to commit/release Savepoint", e);
|
||||
}
|
||||
@@ -109,6 +103,7 @@ final class SavepointTransaction extends SpiTransactionProxy {
|
||||
connection.rollback(savepoint);
|
||||
state = STATE_ROLLED_BACK;
|
||||
manager.notifyOfRollback(this, cause);
|
||||
transaction.logTxn(spPrefix + "rollback");//TODO: Pass the cause
|
||||
} catch (SQLException e) {
|
||||
throw new PersistenceException("Error trying to rollback Savepoint", e);
|
||||
}
|
||||
|
||||
@@ -43,9 +43,6 @@ abstract class TransactionFactory {
|
||||
throw new PersistenceException(e);
|
||||
}
|
||||
}
|
||||
if (explicit && manager.log().txn().isTrace()) {
|
||||
manager.log().txn().trace(t.getLogPrefix() + "Begin");
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-77
@@ -36,7 +36,6 @@ import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
import static java.lang.System.Logger.Level.ERROR;
|
||||
@@ -63,8 +62,6 @@ public class TransactionManager implements SpiTransactionManager {
|
||||
* Prefix for transaction id's (logging).
|
||||
*/
|
||||
final String prefix;
|
||||
private final String externalTransPrefix;
|
||||
private final AtomicLong counter = new AtomicLong(1000L);
|
||||
|
||||
/**
|
||||
* The dataSource of connections.
|
||||
@@ -96,8 +93,6 @@ public class TransactionManager implements SpiTransactionManager {
|
||||
private final boolean skipCacheAfterWrite;
|
||||
private final TransactionFactory transactionFactory;
|
||||
private final SpiLogManager logManager;
|
||||
private final SpiLogger txnLogger;
|
||||
private final boolean txnDebug;
|
||||
private final DatabasePlatform databasePlatform;
|
||||
private final SpiProfileHandler profileHandler;
|
||||
private final TimedMetric txnMain;
|
||||
@@ -115,8 +110,6 @@ public class TransactionManager implements SpiTransactionManager {
|
||||
public TransactionManager(TransactionManagerOptions options) {
|
||||
this.server = options.server;
|
||||
this.logManager = options.logManager;
|
||||
this.txnLogger = logManager.txn();
|
||||
this.txnDebug = txnLogger.isDebug();
|
||||
this.databasePlatform = options.config.getDatabasePlatform();
|
||||
this.supportsSavepointId = databasePlatform.supportsSavepointId();
|
||||
this.skipCacheAfterWrite = options.config.isSkipCacheAfterWrite();
|
||||
@@ -142,7 +135,6 @@ public class TransactionManager implements SpiTransactionManager {
|
||||
this.profileHandler = options.profileHandler;
|
||||
this.bulkEventListenerMap = new BulkEventListenerMap(options.config.getBulkTableEventListeners());
|
||||
this.prefix = "";
|
||||
this.externalTransPrefix = "e";
|
||||
|
||||
CurrentTenantProvider tenantProvider = options.config.getCurrentTenantProvider();
|
||||
this.transactionFactory = TransactionFactoryBuilder.build(this, dataSourceSupplier, tenantProvider);
|
||||
@@ -273,14 +265,7 @@ public class TransactionManager implements SpiTransactionManager {
|
||||
* Wrap the externally supplied Connection.
|
||||
*/
|
||||
public SpiTransaction wrapExternalConnection(Connection c) {
|
||||
return wrapExternalConnection(externalTransPrefix + c.hashCode(), c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap an externally supplied Connection with a known transaction id.
|
||||
*/
|
||||
private SpiTransaction wrapExternalConnection(String id, Connection c) {
|
||||
ExternalJdbcTransaction t = new ExternalJdbcTransaction(id, true, c, this);
|
||||
ExternalJdbcTransaction t = new ExternalJdbcTransaction(true, c, this);
|
||||
// set the default batch mode
|
||||
t.setBatchMode(persistBatch);
|
||||
t.setBatchOnCascade(persistBatchOnCascade);
|
||||
@@ -313,14 +298,7 @@ public class TransactionManager implements SpiTransactionManager {
|
||||
* Create a new transaction.
|
||||
*/
|
||||
SpiTransaction createTransaction(boolean explicit, Connection c) {
|
||||
return new JdbcTransaction(nextTxnId(), explicit, c, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next transaction id.
|
||||
*/
|
||||
String nextTxnId() {
|
||||
return txnDebug ? prefix + counter.incrementAndGet() : prefix;
|
||||
return new JdbcTransaction(explicit, c, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -328,17 +306,7 @@ public class TransactionManager implements SpiTransactionManager {
|
||||
*/
|
||||
@Override
|
||||
public final void notifyOfRollback(SpiTransaction transaction, Throwable cause) {
|
||||
try {
|
||||
if (txnLogger.isDebug()) {
|
||||
String msg = transaction.getLogPrefix() + "Rollback";
|
||||
if (cause != null) {
|
||||
msg += " error: " + formatThrowable(cause);
|
||||
}
|
||||
txnLogger.debug(msg);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
log.log(ERROR, "Error while notifying TransactionEventListener of rollback event", ex);
|
||||
}
|
||||
// Do nothing now
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -347,32 +315,6 @@ public class TransactionManager implements SpiTransactionManager {
|
||||
@Override
|
||||
public final void notifyOfQueryOnly(SpiTransaction transaction) {
|
||||
// Nothing that interesting here
|
||||
if (txnLogger.isTrace()) {
|
||||
txnLogger.trace(transaction.getLogPrefix() + "Commit - query only");
|
||||
}
|
||||
}
|
||||
|
||||
private String formatThrowable(Throwable e) {
|
||||
if (e == null) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
formatThrowable(e, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void formatThrowable(Throwable e, StringBuilder sb) {
|
||||
sb.append(e.toString());
|
||||
StackTraceElement[] stackTrace = e.getStackTrace();
|
||||
if (stackTrace.length > 0) {
|
||||
sb.append(" stack0: ");
|
||||
sb.append(stackTrace[0]);
|
||||
}
|
||||
Throwable cause = e.getCause();
|
||||
if (cause != null) {
|
||||
sb.append(" cause: ");
|
||||
formatThrowable(cause, sb);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -381,9 +323,6 @@ public class TransactionManager implements SpiTransactionManager {
|
||||
@Override
|
||||
public final void notifyOfCommit(SpiTransaction transaction) {
|
||||
try {
|
||||
if (txnLogger.isDebug()) {
|
||||
txnLogger.debug(transaction.getLogPrefix() + "Commit");
|
||||
}
|
||||
PostCommitProcessing postCommit = new PostCommitProcessing(clusterManager, this, transaction);
|
||||
postCommit.notifyLocalCache();
|
||||
backgroundExecutor.execute(postCommit.backgroundNotify());
|
||||
@@ -676,25 +615,18 @@ public class TransactionManager implements SpiTransactionManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if Transaction debug is on.
|
||||
*/
|
||||
public final boolean isTxnDebug() {
|
||||
return txnDebug;
|
||||
public SpiTxnLogger logger() {
|
||||
return logManager.logger();
|
||||
}
|
||||
|
||||
public SpiTxnLogger loggerReadOnly() {
|
||||
return logManager.readOnlyLogger();
|
||||
}
|
||||
|
||||
public final SpiLogManager log() {
|
||||
return logManager;
|
||||
}
|
||||
|
||||
public final boolean isLogSql() {
|
||||
return logManager.sql().isDebug();
|
||||
}
|
||||
|
||||
public final boolean isLogSummary() {
|
||||
return logManager.sum().isDebug();
|
||||
}
|
||||
|
||||
/**
|
||||
* Experimental - find dirty beans in the persistence context and persist them.
|
||||
*/
|
||||
@@ -704,4 +636,5 @@ public class TransactionManager implements SpiTransactionManager {
|
||||
server.updateAll(dirtyBeans, transaction);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,4 +43,24 @@ public final class Str {
|
||||
return sb.append(s0).append(s1).toString();
|
||||
}
|
||||
|
||||
public static String add(String s0, String[] s1) {
|
||||
if (s1 == null || s1.length == 0) {
|
||||
return s0;
|
||||
}
|
||||
int len = s0.length();
|
||||
for (String s : s1) {
|
||||
if (s != null) {
|
||||
len += s.length();
|
||||
}
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
sb.append(s0);
|
||||
for (String s : s1) {
|
||||
if (s != null) {
|
||||
sb.append(s);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
@@ -99,6 +99,14 @@ public class DefaultExpressionListTest extends BaseExpressionTest {
|
||||
.isSameByBind(spi(exp().eq("a", 10).eq("b", 20)))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSameWithClear() {
|
||||
DefaultExpressionList<?> exp1 = spi(exp().eq("a", 10).eq("b", 20).clear().eq("c", 30));
|
||||
DefaultExpressionList<?> exp2 = spi(exp().eq("c", 30));
|
||||
same(exp1, exp2);
|
||||
assertThat(exp1.isSameByBind(exp2)).isTrue();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
void copy() {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-csv-reader</artifactId>
|
||||
@@ -14,21 +14,21 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean ddl generation</name>
|
||||
@@ -28,14 +28,14 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-all</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean external mapping api</name>
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>ebean-parent-13.11.2</tag>
|
||||
<tag>ebean-parent-13.13.0</tag>
|
||||
</scm>
|
||||
|
||||
<name>ebean external mapping xml</name>
|
||||
@@ -21,7 +21,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-api</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -54,21 +54,21 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
ebean-version: 141
|
||||
ebean-version: 142
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-jackson-jsonnode</artifactId>
|
||||
@@ -14,7 +14,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ final class ScalarTypeJodaDateMidnight extends ScalarTypeBaseDate<DateMidnight>
|
||||
|
||||
@Override
|
||||
protected String toIsoFormat(DateMidnight value) {
|
||||
return value.toString();
|
||||
return value.toLocalDate().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,6 +28,11 @@ final class ScalarTypeJodaLocalDateTime extends ScalarTypeBaseDateTime<LocalDate
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LocalDateTime fromJsonISO8601(String value) {
|
||||
return LocalDateTime.parse(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long convertToMillis(LocalDateTime value) {
|
||||
return value.toDateTime().getMillis();
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package io.ebean.joda.time;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import io.ebean.config.JsonConfig;
|
||||
import org.joda.time.DateMidnight;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class ScalarTypeJodaDateMidnightTest {
|
||||
|
||||
ScalarTypeJodaDateMidnight type = new ScalarTypeJodaDateMidnight(JsonConfig.Date.ISO8601);
|
||||
JsonFactory jsonFactory = new JsonFactory();
|
||||
|
||||
@Test
|
||||
void testIsoFormat() throws IOException {
|
||||
// long millis = 1674472451640L;
|
||||
JsonParser parser = jsonFactory.createParser(new StringReader("\"2023-01-23\""));
|
||||
JsonToken token = parser.nextToken();
|
||||
assertEquals(JsonToken.VALUE_STRING, token);
|
||||
DateMidnight dm = type.jsonRead(parser);
|
||||
String iso = type.toIsoFormat(dm);
|
||||
assertEquals("2023-01-23", iso);
|
||||
}
|
||||
}
|
||||
+18
-4
@@ -1,21 +1,37 @@
|
||||
package io.ebean.joda.time;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import io.ebean.config.JsonConfig;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class ScalarTypeJodaLocalDateTimeTest {
|
||||
class ScalarTypeJodaLocalDateTimeTest {
|
||||
|
||||
ScalarTypeJodaLocalDateTime type = new ScalarTypeJodaLocalDateTime(JsonConfig.DateTime.ISO8601);
|
||||
JsonFactory jsonFactory = new JsonFactory();
|
||||
|
||||
@Test
|
||||
public void testConvertFromTimestamp() throws Exception {
|
||||
void testIsoFormat() throws IOException {
|
||||
JsonParser parser = jsonFactory.createParser(new StringReader("\"2023-01-23T12:14:11.640\""));
|
||||
JsonToken token = parser.nextToken();
|
||||
assertEquals(JsonToken.VALUE_STRING, token);
|
||||
|
||||
LocalDateTime ldt1 = type.jsonRead(parser);
|
||||
String iso = type.toJsonISO8601(ldt1);
|
||||
assertEquals("2023-01-23T12:14:11.640", iso);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConvertFromTimestamp() {
|
||||
long now = System.currentTimeMillis();
|
||||
Timestamp nowTs = new Timestamp(now);
|
||||
|
||||
@@ -30,12 +46,10 @@ public class ScalarTypeJodaLocalDateTimeTest {
|
||||
assertEquals(ts1, ts2);
|
||||
}
|
||||
|
||||
|
||||
LocalDateTime localConvertFromTimestamp(Timestamp ts) {
|
||||
return new LocalDateTime(ts.getTime(), DateTimeZone.getDefault());
|
||||
}
|
||||
|
||||
|
||||
Timestamp localConvertToTimestamp(LocalDateTime t) {
|
||||
return new Timestamp(t.toDateTime(DateTimeZone.getDefault()).getMillis());
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2-SNAPSHOT</version>
|
||||
<version>13.13.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-kotlin</artifactId>
|
||||
@@ -28,7 +28,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2-SNAPSHOT</version>
|
||||
<version>13.13.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.11.2-SNAPSHOT</version>
|
||||
<version>13.13.0-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean postgis</name>
|
||||
@@ -22,14 +22,14 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- provided scope -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean querybean</name>
|
||||
@@ -17,7 +17,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -63,21 +63,21 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>querybean-generator</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.11.2</version>
|
||||
<version>13.13.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ package io.ebean.typequery;
|
||||
* @param <R> the root query bean type
|
||||
* @param <E> the element type of the DbArray
|
||||
*/
|
||||
public final class PArray<R, E> extends TQPropertyBase<R> {
|
||||
public final class PArray<R, E> extends TQPropertyBase<R, E> {
|
||||
|
||||
/**
|
||||
* Construct with a property name and root instance.
|
||||
|
||||
+17
-16
@@ -9,8 +9,7 @@ import io.ebean.Query;
|
||||
* @param <R> the root query bean type
|
||||
* @param <T> the type of the scalar property
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
|
||||
public abstract class PBaseComparable<R, T> extends PBaseValueEqual<R, T> {
|
||||
|
||||
/**
|
||||
* Construct with a property name and root instance.
|
||||
@@ -18,14 +17,14 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
|
||||
* @param name property name
|
||||
* @param root the root query bean instance
|
||||
*/
|
||||
public PBaseCompareable(String name, R root) {
|
||||
public PBaseComparable(String name, R root) {
|
||||
super(name, root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with additional path prefix.
|
||||
*/
|
||||
public PBaseCompareable(String name, R root, String prefix) {
|
||||
public PBaseComparable(String name, R root, String prefix) {
|
||||
super(name, root, prefix);
|
||||
}
|
||||
|
||||
@@ -44,12 +43,14 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
|
||||
|
||||
/**
|
||||
* Greater than other property.
|
||||
* <p>
|
||||
* Note that the other property must have the same common "Base type" (String, Number, Temporal, Boolean or Object).
|
||||
*
|
||||
* @param other the other property to compare
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R gt(TQProperty<?> other) {
|
||||
expr().raw(_name + " > " + other.propertyName());
|
||||
public final R gt(Query.Property<T> other) {
|
||||
expr().raw(_name + " > " + other.toString());
|
||||
return _root;
|
||||
}
|
||||
|
||||
@@ -81,8 +82,8 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
|
||||
* @param other the other property to compare
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R ge(TQProperty<?> other) {
|
||||
expr().raw(_name + " >= " + other.propertyName());
|
||||
public final R ge(Query.Property<T> other) {
|
||||
expr().raw(_name + " >= " + other.toString());
|
||||
return _root;
|
||||
}
|
||||
|
||||
@@ -114,8 +115,8 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
|
||||
* @param other the other property to compare
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R lt(TQProperty<?> other) {
|
||||
expr().raw(_name + " < " + other.propertyName());
|
||||
public final R lt(Query.Property<T> other) {
|
||||
expr().raw(_name + " < " + other.toString());
|
||||
return _root;
|
||||
}
|
||||
|
||||
@@ -147,8 +148,8 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
|
||||
* @param other the other property to compare
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R le(TQProperty<?> other) {
|
||||
expr().raw(_name + " <= " + other.propertyName());
|
||||
public final R le(Query.Property<T> other) {
|
||||
expr().raw(_name + " <= " + other.toString());
|
||||
return _root;
|
||||
}
|
||||
|
||||
@@ -197,8 +198,8 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
|
||||
* The most common use of this could be called "effective dating" where 2 date or
|
||||
* timestamp columns represent the date range in which
|
||||
*/
|
||||
public final R inRangeWith(TQProperty<R> highProperty, T value) {
|
||||
expr().inRangeWith(_name, highProperty._name, value);
|
||||
public final R inRangeWith(Query.Property<T> highProperty, T value) {
|
||||
expr().inRangeWith(_name, highProperty.toString(), value);
|
||||
return _root;
|
||||
}
|
||||
|
||||
@@ -220,8 +221,8 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
|
||||
* <p>
|
||||
* This is a convenience expression combining a number of simple expressions.
|
||||
*/
|
||||
public final R inRangeWith(TQProperty<?> lowProperty, TQProperty<?> highProperty) {
|
||||
expr().inRangeWithProperties(_name, lowProperty.propertyName(), highProperty.propertyName());
|
||||
public final R inRangeWith(Query.Property<T> lowProperty, Query.Property<T> highProperty) {
|
||||
expr().inRangeWithProperties(_name, lowProperty.toString(), highProperty.toString());
|
||||
return _root;
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ package io.ebean.typequery;
|
||||
* Base property for date and date time types.
|
||||
*
|
||||
* @param <R> the root query bean type
|
||||
* @param <D> the date time type
|
||||
* @param <T> the scalar type
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public abstract class PBaseDate<R, D extends Comparable> extends PBaseCompareable<R, D> {
|
||||
public abstract class PBaseDate<R, T extends Comparable> extends PBaseComparable<R, T> {
|
||||
|
||||
/**
|
||||
* Construct with a property name and root instance.
|
||||
@@ -32,7 +32,7 @@ public abstract class PBaseDate<R, D extends Comparable> extends PBaseCompareabl
|
||||
* @param value the equal to bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R after(D value) {
|
||||
public final R after(T value) {
|
||||
expr().gt(_name, value);
|
||||
return _root;
|
||||
}
|
||||
@@ -43,7 +43,7 @@ public abstract class PBaseDate<R, D extends Comparable> extends PBaseCompareabl
|
||||
* @param value the equal to bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R before(D value) {
|
||||
public final R before(T value) {
|
||||
expr().lt(_name, value);
|
||||
return _root;
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ package io.ebean.typequery;
|
||||
* Base property for number types.
|
||||
*
|
||||
* @param <R> the root query bean type
|
||||
* @param <T> the number type
|
||||
* @param <T> the property type
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public abstract class PBaseNumber<R,T extends Comparable> extends PBaseCompareable<R,T> {
|
||||
public abstract class PBaseNumber<R, T extends Comparable> extends PBaseComparable<R, T> {
|
||||
|
||||
/**
|
||||
* Construct with a property name and root instance.
|
||||
@@ -16,7 +16,7 @@ public abstract class PBaseNumber<R,T extends Comparable> extends PBaseCompareab
|
||||
* @param root the root query bean instance
|
||||
*/
|
||||
public PBaseNumber(String name, R root) {
|
||||
super(name , root);
|
||||
super(name, root);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@ package io.ebean.typequery;
|
||||
*
|
||||
* @param <R> the root query bean type
|
||||
*/
|
||||
public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
|
||||
public abstract class PBaseString<R, T> extends PBaseComparable<R, T> {
|
||||
|
||||
/**
|
||||
* Construct with a property name and root instance.
|
||||
@@ -25,22 +25,28 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated migrate to eq().
|
||||
* <p>
|
||||
* Is equal to. The same as <code>eq</code> but uses the strong type as argument rather than String.
|
||||
*
|
||||
* @param value the equal to bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
@Deprecated
|
||||
public final R equalToType(T value) {
|
||||
expr().eq(_name, value);
|
||||
return _root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated migrate to ne().
|
||||
* <p>
|
||||
* Is not equal to. The same as <code>ne</code> but uses the strong type as argument rather than String.
|
||||
*
|
||||
* @param value the equal to bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
@Deprecated
|
||||
public final R notEqualToType(T value) {
|
||||
expr().ne(_name, value);
|
||||
return _root;
|
||||
@@ -49,7 +55,146 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
|
||||
// common string / expressions ------------
|
||||
|
||||
/**
|
||||
* Case insensitive is equal to.
|
||||
* Equal to.
|
||||
*
|
||||
* @param value the bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R eq(String value) {
|
||||
expr().eq(_name, value);
|
||||
return _root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not equal to.
|
||||
*
|
||||
* @param value the bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R ne(String value) {
|
||||
expr().ne(_name, value);
|
||||
return _root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than.
|
||||
*
|
||||
* @param value the bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R gt(String value) {
|
||||
expr().gt(_name, value);
|
||||
return _root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than OR Null.
|
||||
*
|
||||
* @param value the bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R gtOrNull(String value) {
|
||||
expr().gtOrNull(_name, value);
|
||||
return _root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or Equal to.
|
||||
*
|
||||
* @param value the bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R ge(String value) {
|
||||
expr().ge(_name, value);
|
||||
return _root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or Equal to OR Null.
|
||||
*
|
||||
* @param value the bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R geOrNull(String value) {
|
||||
expr().geOrNull(_name, value);
|
||||
return _root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Less than.
|
||||
*
|
||||
* @param value the bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R lt(String value) {
|
||||
expr().lt(_name, value);
|
||||
return _root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Less than OR Null.
|
||||
*
|
||||
* @param value the bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R ltOrNull(String value) {
|
||||
expr().ltOrNull(_name, value);
|
||||
return _root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Less than or Equal to.
|
||||
*
|
||||
* @param value the bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R le(String value) {
|
||||
expr().le(_name, value);
|
||||
return _root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Less than or Equal to OR null.
|
||||
*
|
||||
* @param value the bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R leOrNull(String value) {
|
||||
expr().leOrNull(_name, value);
|
||||
return _root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater or equal to lower value and strictly less than upper value.
|
||||
* <p>
|
||||
* This is generally preferable over Between for date and datetime types
|
||||
* as SQL Between is inclusive on the upper bound ({@code <= }) and generally
|
||||
* we need the upper bound to be exclusive ({@code < }).
|
||||
* </p>
|
||||
*
|
||||
* @param lower the lower bind value ({@code >= })
|
||||
* @param upper the upper bind value ({@code < })
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R inRange(String lower, String upper) {
|
||||
expr().inRange(_name, lower, upper);
|
||||
return _root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Between lower and upper values.
|
||||
*
|
||||
* @param lower the lower bind value
|
||||
* @param upper the upper bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
public final R between(String lower, String upper) {
|
||||
expr().between(_name, lower, upper);
|
||||
return _root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Case-insensitive is equal to.
|
||||
*
|
||||
* @param value the equal to bind value
|
||||
* @return the root query bean instance
|
||||
@@ -60,7 +205,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Case insensitive is equal to.
|
||||
* Case-insensitive is equal to.
|
||||
*
|
||||
* @param value the equal to bind value
|
||||
* @return the root query bean instance
|
||||
@@ -115,7 +260,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Case insensitive like.
|
||||
* Case-insensitive like.
|
||||
*
|
||||
* @param value the equal to bind value
|
||||
* @return the root query bean instance
|
||||
@@ -126,7 +271,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Case insensitive starts with.
|
||||
* Case-insensitive starts with.
|
||||
*
|
||||
* @param value the equal to bind value
|
||||
* @return the root query bean instance
|
||||
@@ -137,7 +282,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Case insensitive ends with.
|
||||
* Case-insensitive ends with.
|
||||
*
|
||||
* @param value the equal to bind value
|
||||
* @return the root query bean instance
|
||||
@@ -148,7 +293,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Case insensitive contains.
|
||||
* Case-insensitive contains.
|
||||
*
|
||||
* @param value the equal to bind value
|
||||
* @return the root query bean instance
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user