mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
58
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b2cdc14aa | ||
|
|
6d712a92a0 | ||
|
|
ea11b0c3b6 | ||
|
|
08e8402d05 | ||
|
|
006ad79379 | ||
|
|
0e063549cd | ||
|
|
4f0d2cabfb | ||
|
|
80b2d9f983 | ||
|
|
287d0c467d | ||
|
|
a8835379e7 | ||
|
|
e4df20b9dc | ||
|
|
261b13ef4b | ||
|
|
7639034d7c | ||
|
|
e6e53e0d93 | ||
|
|
c71971eb5c | ||
|
|
357af58db4 | ||
|
|
0abdb1550a | ||
|
|
c32fc814f6 | ||
|
|
8e035939dc | ||
|
|
edf98ee250 | ||
|
|
5f0a75a130 | ||
|
|
d2f16cbf6a | ||
|
|
04ba81d12f | ||
|
|
f63e7ed5af | ||
|
|
66940c0f14 | ||
|
|
1f48b3a6b3 | ||
|
|
7d368097e9 | ||
|
|
c849e29316 | ||
|
|
c78a3dd6c4 | ||
|
|
a4455ddbf2 | ||
|
|
9787af77e4 | ||
|
|
3786fb09a5 | ||
|
|
f34e7b6003 | ||
|
|
089dd8e364 | ||
|
|
44770382fb | ||
|
|
6645e5b9ec | ||
|
|
2a62d413cc | ||
|
|
0046d983cb | ||
|
|
006e33cb3e | ||
|
|
e80e8e027a | ||
|
|
2e1b52d7d4 | ||
|
|
09d5163396 | ||
|
|
a6a38b9a92 | ||
|
|
bd4521b240 | ||
|
|
8a7379879b | ||
|
|
b78dd6f79a | ||
|
|
4ebb5fd112 | ||
|
|
487368976f | ||
|
|
c6defceec9 | ||
|
|
3576aafffc | ||
|
|
66234249c6 | ||
|
|
8ed3b765ec | ||
|
|
fcbcc53e27 | ||
|
|
b377e1a618 | ||
|
|
a0f612ed71 | ||
|
|
6f64821584 | ||
|
|
47e97a77a8 | ||
|
|
e8d3f50bb4 |
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-clickhouse</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-db2</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-hana</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mariadb</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mysql</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-nuodb</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-oracle</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -47,19 +47,19 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgis-types</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlite</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -42,13 +42,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,7 +41,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-mapper</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -60,13 +60,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-all</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>composites</artifactId>
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean api</name>
|
||||
@@ -39,7 +39,7 @@
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-config</artifactId>
|
||||
<version>3.9</version>
|
||||
<version>3.10</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -266,55 +266,6 @@ public final class DB {
|
||||
getDefault().register(transactionCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated for removal migrate using try-with-resources and commit on the transaction itself.
|
||||
* <p>
|
||||
* Commit the current transaction.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void commitTransaction() {
|
||||
getDefault().commitTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated for removal migrate to using try-with-resources and rollback on the transaction itself.
|
||||
* <p>
|
||||
* Rollback the current transaction.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void rollbackTransaction() {
|
||||
getDefault().rollbackTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the current transaction has already been committed do nothing otherwise
|
||||
* rollback the transaction.
|
||||
* <p>
|
||||
* It is preferable to use <em>try with resources</em> rather than this.
|
||||
* <p>
|
||||
* Useful to put in a finally block to ensure the transaction is ended, rather
|
||||
* than a rollbackTransaction() in each catch block.
|
||||
* <p>
|
||||
* Code example:
|
||||
*
|
||||
* <pre>{@code
|
||||
* DB.beginTransaction();
|
||||
* try {
|
||||
* // do some fetching and or persisting
|
||||
*
|
||||
* // commit at the end
|
||||
* DB.commitTransaction();
|
||||
*
|
||||
* } finally {
|
||||
* // if commit didn't occur then rollback the transaction
|
||||
* DB.endTransaction();
|
||||
* }
|
||||
* }</pre>
|
||||
*/
|
||||
public static void endTransaction() {
|
||||
getDefault().endTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the current transaction as rollback only.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
package io.ebean;
|
||||
|
||||
final class DInsertOptionsBuilder implements InsertOptions.Builder {
|
||||
|
||||
private Boolean getGeneratedKeys;
|
||||
private boolean onConflictUpdate;
|
||||
private boolean onConflictNothing;
|
||||
private String constraint;
|
||||
private String uniqueColumns;
|
||||
private String updateSet;
|
||||
|
||||
@Override
|
||||
public InsertOptions.Builder onConflictNothing() {
|
||||
this.onConflictNothing = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsertOptions.Builder onConflictUpdate() {
|
||||
this.onConflictUpdate = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsertOptions.Builder constraint(String constraint) {
|
||||
this.constraint = constraint;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsertOptions.Builder uniqueColumns(String uniqueColumns) {
|
||||
this.uniqueColumns = uniqueColumns;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsertOptions.Builder updateSet(String updateSet) {
|
||||
this.updateSet = updateSet;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsertOptions.Builder getGeneratedKeys(boolean getGeneratedKeys) {
|
||||
this.getGeneratedKeys = getGeneratedKeys;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsertOptions build() {
|
||||
return new Options(constraint, uniqueColumns, updateSet, onConflictUpdate, onConflictNothing, getGeneratedKeys);
|
||||
}
|
||||
|
||||
static final class Options implements InsertOptions {
|
||||
|
||||
private static final String UPDATE = "U";
|
||||
private static final String NOTHING = "N";
|
||||
private static final String NORMAL = "_";
|
||||
private final String key;
|
||||
private final Boolean getGeneratedKeys;
|
||||
private final String constraint;
|
||||
private final String uniqueColumns;
|
||||
private final String updateSet;
|
||||
|
||||
Options(String constraint, String uniqueColumns, String updateSet, boolean onConflictUpdate, boolean onConflictNothing, Boolean getGeneratedKeys) {
|
||||
this.constraint = constraint;
|
||||
this.uniqueColumns = uniqueColumns;
|
||||
this.updateSet = updateSet;
|
||||
this.getGeneratedKeys = getGeneratedKeys;
|
||||
this.key = (onConflictUpdate ? UPDATE : onConflictNothing ? NOTHING : NORMAL)
|
||||
+ '+' + plus(constraint)
|
||||
+ '+' + plus(uniqueColumns)
|
||||
+ '+' + plus(updateSet);
|
||||
}
|
||||
|
||||
private String plus(String val) {
|
||||
return val == null ? "" : val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String key() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String constraint() {
|
||||
return constraint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uniqueColumns() {
|
||||
return uniqueColumns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String updateSet() {
|
||||
return updateSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getGetGeneratedKeys() {
|
||||
return getGeneratedKeys;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -666,49 +666,6 @@ public interface Database {
|
||||
*/
|
||||
void flush();
|
||||
|
||||
/**
|
||||
* Deprecated for removal migrate using try-with-resources and commit on the transaction itself.
|
||||
* <p>
|
||||
* Commit the current transaction.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
void commitTransaction();
|
||||
|
||||
/**
|
||||
* Deprecated for removal migrate to using try-with-resources and rollback on the transaction itself.
|
||||
* <p>
|
||||
* Rollback the current transaction.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
void rollbackTransaction();
|
||||
|
||||
/**
|
||||
* If the current transaction has already been committed do nothing otherwise
|
||||
* rollback the transaction.
|
||||
* <p>
|
||||
* Useful to put in a finally block to ensure the transaction is ended, rather
|
||||
* than a rollbackTransaction() in each catch block.
|
||||
* <p>
|
||||
* Code example:
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* database.beginTransaction();
|
||||
* try {
|
||||
* // do some fetching and or persisting ...
|
||||
*
|
||||
* // commit at the end
|
||||
* database.commitTransaction();
|
||||
*
|
||||
* } finally {
|
||||
* // if commit didn't occur then rollback the transaction
|
||||
* database.endTransaction();
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
void endTransaction();
|
||||
|
||||
/**
|
||||
* Refresh the values of a bean.
|
||||
* <p>
|
||||
@@ -1227,22 +1184,53 @@ public interface Database {
|
||||
*/
|
||||
void insert(Object bean);
|
||||
|
||||
/**
|
||||
* Insert the bean with options (ON CONFLICT DO UPDATE | DO NOTHING).
|
||||
* <p>
|
||||
* Currently, this is limited to use with Postgres only,
|
||||
* <p>
|
||||
* When using this ebean will look to determine the unique columns by looking at
|
||||
* the mapping like {@code @Column(unique=true} and {@code @Index(unique=true}.
|
||||
*/
|
||||
void insert(Object bean, InsertOptions insertOptions);
|
||||
|
||||
/**
|
||||
* Insert the bean with a transaction.
|
||||
*/
|
||||
void insert(Object bean, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Insert the beans with options (ON CONFLICT DO UPDATE | DO NOTHING) and transaction.
|
||||
* <p>
|
||||
* Currently, this is limited to use with Postgres only,
|
||||
*/
|
||||
void insert(Object bean, InsertOptions insertOptions, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Insert a collection of beans. If there is no current transaction one is created and used to
|
||||
* insert all the beans in the collection.
|
||||
*/
|
||||
void insertAll(Collection<?> beans);
|
||||
|
||||
/**
|
||||
* Insert the beans with options - typically ON CONFLICT DO UPDATE | DO NOTHING.
|
||||
* <p>
|
||||
* Currently, this is limited to use with Postgres only,
|
||||
*/
|
||||
void insertAll(Collection<?> beans, InsertOptions options);
|
||||
|
||||
/**
|
||||
* Insert a collection of beans with an explicit transaction.
|
||||
*/
|
||||
void insertAll(Collection<?> beans, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Insert the beans with options (ON CONFLICT DO UPDATE | DO NOTHING) and transaction.
|
||||
* <p>
|
||||
* Currently, this is limited to use with Postgres only,
|
||||
*/
|
||||
void insertAll(Collection<?> beans, InsertOptions options, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute explicitly passing a transaction.
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,8 @@ package io.ebean;
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -206,14 +208,19 @@ public interface DtoQuery<T> extends CancelableQuery {
|
||||
*/
|
||||
DtoQuery<T> usingTransaction(Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query using the given connection.
|
||||
*/
|
||||
DtoQuery<T> usingConnection(Connection connection);
|
||||
|
||||
/**
|
||||
* Ensure that the master DataSource is used if there is a read only data source
|
||||
* being used (that is using a read replica database potentially with replication lag).
|
||||
* <p>
|
||||
* When the database is configured with a read-only DataSource via
|
||||
* say {@link io.ebean.config.DatabaseConfig#setReadOnlyDataSource(DataSource)} then
|
||||
* say {@link io.ebean.DatabaseBuilder#readOnlyDataSource(DataSource)} then
|
||||
* by default when a query is run without an active transaction, it uses the read-only data
|
||||
* source. We we use {@code usingMaster()} to instead ensure that the query is executed
|
||||
* source. We use {@code usingMaster()} to instead ensure that the query is executed
|
||||
* against the master data source.
|
||||
*/
|
||||
DtoQuery<T> usingMaster();
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.avaje.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Options to be used with insert such as ON CONFLICT DO UPDATE | NOTHING.
|
||||
*/
|
||||
public interface InsertOptions {
|
||||
|
||||
/**
|
||||
* Use ON CONFLICT UPDATE with automatic determination of the unique columns to conflict on.
|
||||
* <p>
|
||||
* Uses mapping to determine the unique columns - {@code @Column(unique=true)} and {@code @Index(unique=true)} .
|
||||
*/
|
||||
InsertOptions ON_CONFLICT_UPDATE = InsertOptions.builder()
|
||||
.onConflictUpdate()
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Use ON CONFLICT DO NOTHING with automatic determination of the unique columns to conflict on.
|
||||
* <p>
|
||||
* Uses mapping to determine the unique columns - {@code @Column(unique=true)} and {@code @Index(unique=true)} .
|
||||
*/
|
||||
InsertOptions ON_CONFLICT_NOTHING = InsertOptions.builder()
|
||||
.onConflictNothing()
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Return a builder for InsertOptions.
|
||||
*/
|
||||
static Builder builder() {
|
||||
return new DInsertOptionsBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the constraint name that is used for ON CONFLICT.
|
||||
*/
|
||||
@Nullable
|
||||
String constraint();
|
||||
|
||||
/**
|
||||
* Return the unique columns that is used for ON CONFLICT.
|
||||
* <p>
|
||||
* When not explicitly set will use mapping like {@code @Column(unique=true)} to determine the
|
||||
* non-unique columns.
|
||||
*/
|
||||
@Nullable
|
||||
String uniqueColumns();
|
||||
|
||||
/**
|
||||
* Return the ON CONFLICT UPDATE SET clause.
|
||||
* <p>
|
||||
* When not set will use the non-unique columns.
|
||||
*/
|
||||
@Nullable
|
||||
String updateSet();
|
||||
|
||||
/**
|
||||
* Return if GetGeneratedKeys should be used to fetch the generated keys after insert.
|
||||
*/
|
||||
@Nullable
|
||||
Boolean getGetGeneratedKeys();
|
||||
|
||||
/**
|
||||
* Return the key for these build options.
|
||||
*/
|
||||
String key();
|
||||
|
||||
/**
|
||||
* The builder for InsertOptions.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
/**
|
||||
* Use a ON CONFLICT UPDATE automatically determining the unique columns.
|
||||
*/
|
||||
Builder onConflictUpdate();
|
||||
|
||||
/**
|
||||
* Use a ON CONFLICT DO NOTHING automatically determining the unique columns.
|
||||
*/
|
||||
Builder onConflictNothing();
|
||||
|
||||
/**
|
||||
* Specify an explicit conflict constraint name.
|
||||
* <p>
|
||||
* When this is used then unique columns will not be used.
|
||||
*/
|
||||
Builder constraint(String constraint);
|
||||
|
||||
/**
|
||||
* Specify the unique columns for the conflict target.
|
||||
* <p>
|
||||
* When not specified and constraint is also not specified then
|
||||
* it will automatically determine the unique columns
|
||||
* based on mapping like {@code @Column(unique=true)} and
|
||||
* {@code @Index(unique=true)} .
|
||||
*/
|
||||
Builder uniqueColumns(String uniqueColumns);
|
||||
|
||||
/**
|
||||
* Specify the ON CONFLICT DO UPDATE SET clause.
|
||||
* <p>
|
||||
* When not specified ebean will include all the non-unique columns.
|
||||
*/
|
||||
Builder updateSet(String updateSet);
|
||||
|
||||
/**
|
||||
* Specify if GetGeneratedKeys should be used to return generated keys.
|
||||
*/
|
||||
Builder getGeneratedKeys(boolean getGeneratedKeys);
|
||||
|
||||
/**
|
||||
* Build and return the insert options.
|
||||
*/
|
||||
InsertOptions build();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -702,9 +702,9 @@ public interface Query<T> extends CancelableQuery {
|
||||
* being used (that is using a read replica database potentially with replication lag).
|
||||
* <p>
|
||||
* When the database is configured with a read-only DataSource via
|
||||
* say {@link io.ebean.config.DatabaseConfig#setReadOnlyDataSource(DataSource)} then
|
||||
* say {@link io.ebean.DatabaseBuilder#readOnlyDataSource(DataSource)} then
|
||||
* by default when a query is run without an active transaction, it uses the read-only data
|
||||
* source. We we use {@code usingMaster()} to instead ensure that the query is executed
|
||||
* source. We use {@code usingMaster()} to instead ensure that the query is executed
|
||||
* against the master data source.
|
||||
*/
|
||||
Query<T> usingMaster();
|
||||
@@ -970,6 +970,25 @@ public interface Query<T> extends CancelableQuery {
|
||||
@Nullable
|
||||
<A> A findSingleAttribute();
|
||||
|
||||
/**
|
||||
* Execute the query returning a single optional attribute value.
|
||||
* <p>
|
||||
* <h3>Example</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* Optional<String> maybeName =
|
||||
* new QCustomer()
|
||||
* .select(name)
|
||||
* .id.eq(42)
|
||||
* .status.eq(NEW)
|
||||
* .findSingleAttributeOrEmpty();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @return an optional value for the selected property
|
||||
*/
|
||||
<A> Optional<A> findSingleAttributeOrEmpty();
|
||||
|
||||
/**
|
||||
* Return true if this is countDistinct query.
|
||||
*/
|
||||
|
||||
@@ -3,7 +3,9 @@ package io.ebean;
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.Serializable;
|
||||
import java.sql.Connection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
@@ -45,14 +47,19 @@ public interface SqlQuery extends Serializable, CancelableQuery {
|
||||
*/
|
||||
SqlQuery usingTransaction(Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query using the given connection.
|
||||
*/
|
||||
SqlQuery usingConnection(Connection connection);
|
||||
|
||||
/**
|
||||
* Ensure that the master DataSource is used if there is a read only data source
|
||||
* being used (that is using a read replica database potentially with replication lag).
|
||||
* <p>
|
||||
* When the database is configured with a read-only DataSource via
|
||||
* say {@link io.ebean.config.DatabaseConfig#setReadOnlyDataSource(DataSource)} then
|
||||
* say {@link io.ebean.DatabaseBuilder#readOnlyDataSource(DataSource)}then
|
||||
* by default when a query is run without an active transaction, it uses the read-only data
|
||||
* source. We we use {@code usingMaster()} to instead ensure that the query is executed
|
||||
* source. We use {@code usingMaster()} to instead ensure that the query is executed
|
||||
* against the master data source.
|
||||
*/
|
||||
SqlQuery usingMaster();
|
||||
|
||||
@@ -236,7 +236,7 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
|
||||
*/
|
||||
private PersistBatch persistBatchOnCascade = PersistBatch.INHERIT;
|
||||
|
||||
private int persistBatchSize = 20;
|
||||
private int persistBatchSize = 100;
|
||||
|
||||
private EnumType defaultEnumType = EnumType.ORDINAL;
|
||||
|
||||
|
||||
+26
-26
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean bom</name>
|
||||
@@ -89,25 +89,25 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -125,13 +125,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-mapper</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -155,37 +155,37 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>querybean-generator</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>kotlin-querybean-generator</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-redis</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-spring-txn</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- platforms -->
|
||||
@@ -193,79 +193,79 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-clickhouse</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-db2</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-h2</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-hana</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-mariadb</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-mysql</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-nuodb</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-oracle</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgres</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgis</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgis-types</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-sqlite</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-sqlserver</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
@@ -16,7 +16,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
+6
-6
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core</artifactId>
|
||||
@@ -22,7 +22,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -46,7 +46,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -159,21 +159,21 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ package io.ebeaninternal.api;
|
||||
import io.ebean.TxScope;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Used internally to handle the scoping of transactions for methods.
|
||||
@@ -47,6 +49,11 @@ public final class ScopeTrans {
|
||||
private boolean nestedCommit;
|
||||
private boolean nestedUseSavepoint;
|
||||
|
||||
/**
|
||||
* The UserObjects when using in nested transactions.
|
||||
*/
|
||||
private Map<String, Object> userObjects;
|
||||
|
||||
public ScopeTrans(boolean rollbackOnChecked, boolean created, SpiTransaction transaction, TxScope txScope) {
|
||||
this.rollbackOnChecked = rollbackOnChecked;
|
||||
this.created = created;
|
||||
@@ -218,4 +225,17 @@ public final class ScopeTrans {
|
||||
return e instanceof RuntimeException || rollbackOnChecked;
|
||||
}
|
||||
|
||||
public void putUserObject(String name, Object value) {
|
||||
if (userObjects == null) {
|
||||
userObjects = new HashMap<>();
|
||||
}
|
||||
userObjects.put(name, value);
|
||||
}
|
||||
|
||||
public Object getUserObject(String name) {
|
||||
if (userObjects == null) {
|
||||
return null;
|
||||
}
|
||||
return userObjects.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package io.ebeaninternal.api;
|
||||
|
||||
import io.ebeaninternal.server.transaction.TransactionScopeManager;
|
||||
import io.ebeaninternal.server.util.ArrayStack;
|
||||
|
||||
import jakarta.persistence.PersistenceException;
|
||||
|
||||
/**
|
||||
@@ -173,4 +172,31 @@ public final class ScopedTransaction extends SpiTransactionProxy {
|
||||
return current.caughtThrowable(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* New user objects are always written to the current ScopeTrans.
|
||||
*/
|
||||
@Override
|
||||
public void putUserObject(String name, Object value) {
|
||||
current.putUserObject(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the userObject in the stack, Herew we search
|
||||
* the stack and return the first found userObject
|
||||
*/
|
||||
@Override
|
||||
public Object getUserObject(String name) {
|
||||
Object obj = current.getUserObject(name);
|
||||
if (obj != null) {
|
||||
return obj;
|
||||
}
|
||||
for (ScopeTrans trans : stack) {
|
||||
obj = trans.getUserObject(name);
|
||||
if (obj != null) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return transaction.getUserObject(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -86,6 +86,11 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectio
|
||||
*/
|
||||
SpiTransactionManager transactionManager();
|
||||
|
||||
/**
|
||||
* End the current transaction if it is active.
|
||||
*/
|
||||
void endTransaction();
|
||||
|
||||
/**
|
||||
* Return all the descriptors.
|
||||
*/
|
||||
|
||||
@@ -654,6 +654,16 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
*/
|
||||
ObjectGraphNode parentNode();
|
||||
|
||||
/**
|
||||
* Set that this is a future query that will execute in the background.
|
||||
*/
|
||||
void usingFuture();
|
||||
|
||||
/**
|
||||
* Return true if this is a future query.
|
||||
*/
|
||||
boolean isUsingFuture();
|
||||
|
||||
/**
|
||||
* Return false when this is a lazy load or refresh query for a bean.
|
||||
* <p>
|
||||
|
||||
@@ -756,16 +756,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
currentTransaction().flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commitTransaction() {
|
||||
currentTransaction().commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollbackTransaction() {
|
||||
currentTransaction().rollback();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endTransaction() {
|
||||
Transaction transaction = transactionManager.inScope();
|
||||
@@ -1273,6 +1263,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
@Override
|
||||
public <T> FutureRowCount<T> findFutureCount(SpiQuery<T> query) {
|
||||
SpiQuery<T> copy = query.copy();
|
||||
copy.usingFuture();
|
||||
boolean createdTransaction = false;
|
||||
SpiTransaction transaction = query.transaction();
|
||||
if (transaction == null) {
|
||||
@@ -1291,6 +1282,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
@Override
|
||||
public <T> FutureIds<T> findFutureIds(SpiQuery<T> query) {
|
||||
SpiQuery<T> copy = query.copy();
|
||||
copy.usingFuture();
|
||||
boolean createdTransaction = false;
|
||||
SpiTransaction transaction = query.transaction();
|
||||
if (transaction == null) {
|
||||
@@ -1309,6 +1301,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
@Override
|
||||
public <T> FutureList<T> findFutureList(SpiQuery<T> query) {
|
||||
SpiQuery<T> spiQuery = query.copy();
|
||||
spiQuery.usingFuture();
|
||||
// FutureList query always run in it's own persistence content
|
||||
spiQuery.setPersistenceContext(new DefaultPersistenceContext());
|
||||
if (!spiQuery.isDisableReadAudit()) {
|
||||
@@ -1651,41 +1644,50 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert the bean.
|
||||
*/
|
||||
@Override
|
||||
public void insert(Object bean) {
|
||||
insert(bean, null);
|
||||
persister.insert(checkEntityBean(bean), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(Object bean, @Nullable InsertOptions insertOptions) {
|
||||
persister.insert(checkEntityBean(bean), insertOptions, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert the bean with a transaction.
|
||||
*/
|
||||
@Override
|
||||
public void insert(Object bean, @Nullable Transaction transaction) {
|
||||
persister.insert(checkEntityBean(bean), transaction);
|
||||
persister.insert(checkEntityBean(bean), null, transaction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(Object bean, InsertOptions insertOptions, Transaction transaction) {
|
||||
persister.insert(checkEntityBean(bean), insertOptions, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert all beans in the collection.
|
||||
*/
|
||||
@Override
|
||||
public void insertAll(Collection<?> beans) {
|
||||
insertAll(beans, null);
|
||||
insertAll(beans, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertAll(Collection<?> beans, InsertOptions options) {
|
||||
insertAll(beans, options, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert all beans in the collection with a transaction.
|
||||
*/
|
||||
@Override
|
||||
public void insertAll(@Nullable Collection<?> beans, @Nullable Transaction transaction) {
|
||||
insertAll(beans, null, transaction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertAll(@Nullable Collection<?> beans, InsertOptions options, @Nullable Transaction transaction) {
|
||||
if (beans == null || beans.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
executeInTrans((txn) -> {
|
||||
txn.checkBatchEscalationOnCollection();
|
||||
for (Object bean : beans) {
|
||||
persister.insert(checkEntityBean(bean), txn);
|
||||
persister.insert(checkEntityBean(bean), options, txn);
|
||||
}
|
||||
return 0;
|
||||
}, transaction);
|
||||
|
||||
@@ -35,7 +35,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
private final OrmQueryEngine queryEngine;
|
||||
private final SpiQuery<T> query;
|
||||
private final BeanFindController finder;
|
||||
private final Boolean readOnly;
|
||||
private LoadContext loadContext;
|
||||
private PersistenceContext persistenceContext;
|
||||
private HashQuery cacheKey;
|
||||
@@ -52,7 +51,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
this.finder = beanDescriptor.beanFinder();
|
||||
this.queryEngine = queryEngine;
|
||||
this.query = query;
|
||||
this.readOnly = query.isReadOnly();
|
||||
this.persistenceContext = query.persistenceContext();
|
||||
}
|
||||
|
||||
@@ -135,13 +133,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
return loadContext.secondaryQueriesMinBatchSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Normal, sharedInstance, ReadOnly state of this query.
|
||||
*/
|
||||
public Boolean isReadOnly() {
|
||||
return readOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the BeanDescriptor for the associated bean.
|
||||
*/
|
||||
@@ -782,4 +773,10 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
public int forwardOnlyFetchSize() {
|
||||
return queryEngine.forwardOnlyFetchSize();
|
||||
}
|
||||
|
||||
public void clearContext() {
|
||||
if (!transaction.isAutoPersistUpdates()) {
|
||||
beanDescriptor.contextClear(transaction.persistenceContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.ebeaninternal.server.core;
|
||||
|
||||
import io.ebean.InsertOptions;
|
||||
import io.ebean.ValuePair;
|
||||
import io.ebean.annotation.DocStoreMode;
|
||||
import io.ebean.bean.EntityBean;
|
||||
@@ -124,6 +125,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
* Many-to-many intersection table changes that are held for later batch processing.
|
||||
*/
|
||||
private List<SaveMany> saveMany;
|
||||
private InsertOptions insertOptions;
|
||||
|
||||
public PersistRequestBean(SpiEbeanServer server, T bean, Object parentBean, BeanManager<T> mgr, SpiTransaction t,
|
||||
PersistExecute persistExecute, PersistRequest.Type type, int flags) {
|
||||
@@ -380,6 +382,14 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
return intercept.dirtyPropertyNames();
|
||||
}
|
||||
|
||||
public boolean isChangedProperty(int propertyIndex) {
|
||||
if (dirtyProperties == null) {
|
||||
return intercept.isChangedProperty(propertyIndex);
|
||||
} else {
|
||||
return dirtyProperties[propertyIndex];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the dirty properties on this request.
|
||||
*/
|
||||
@@ -865,8 +875,8 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
}
|
||||
setNotifyCache();
|
||||
boolean isChangeLog = beanDescriptor.isChangeLog();
|
||||
if (type == Type.UPDATE && (isChangeLog || notifyCache || docStoreMode == DocStoreMode.UPDATE)) {
|
||||
// get the dirty properties for update notification to the doc store
|
||||
if (type == Type.UPDATE) {
|
||||
// get the dirty properties for notify cache & orphanRemoval of vanilla collection detection
|
||||
dirtyProperties = intercept.dirtyProperties();
|
||||
}
|
||||
if (isChangeLog) {
|
||||
@@ -1408,4 +1418,12 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
private void setGeneratedId() {
|
||||
beanDescriptor.setGeneratedId(entityBean, transaction);
|
||||
}
|
||||
|
||||
public void setInsertOptions(InsertOptions insertOptions) {
|
||||
this.insertOptions = insertOptions;
|
||||
}
|
||||
|
||||
public InsertOptions insertOptions() {
|
||||
return insertOptions;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,10 +77,13 @@ public final class PersistRequestOrmUpdate extends PersistRequest {
|
||||
*/
|
||||
@Override
|
||||
public void postExecute() {
|
||||
OrmUpdateType ormUpdateType = ormUpdate.ormUpdateType();
|
||||
if (OrmUpdateType.INSERT != ormUpdateType && !transaction.isAutoPersistUpdates()) {
|
||||
beanDescriptor.contextClear(transaction.persistenceContext());
|
||||
}
|
||||
if (startNanos > 0) {
|
||||
persistExecute.collectOrmUpdate(label, startNanos);
|
||||
}
|
||||
OrmUpdateType ormUpdateType = ormUpdate.ormUpdateType();
|
||||
String tableName = ormUpdate.baseTable();
|
||||
if (transaction.isLogSummary()) {
|
||||
transaction.logSummary("{0} table[{1}] rows[{2}] bind[{3}]", ormUpdateType, tableName, rowCount, bindLog);
|
||||
|
||||
@@ -3,10 +3,13 @@ package io.ebeaninternal.server.core;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiSqlUpdate;
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.persist.BatchControl;
|
||||
import io.ebeaninternal.server.persist.PersistExecute;
|
||||
import io.ebeaninternal.server.persist.TrimLogSql;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Persist request specifically for CallableSql.
|
||||
*/
|
||||
@@ -156,6 +159,14 @@ public final class PersistRequestUpdateSql extends PersistRequest {
|
||||
*/
|
||||
@Override
|
||||
public void postExecute() {
|
||||
if (sqlType != SqlType.SQL_INSERT && !transaction.isAutoPersistUpdates()) {
|
||||
List<BeanDescriptor<?>> descriptors = server.descriptors(tableName);
|
||||
if (descriptors != null) {
|
||||
for (BeanDescriptor<?> descriptor : descriptors) {
|
||||
descriptor.contextClear(transaction.persistenceContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (startNanos > 0) {
|
||||
persistExecute.collectSqlUpdate(label, startNanos);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
package io.ebeaninternal.server.core;
|
||||
|
||||
import io.ebean.CallableSql;
|
||||
import io.ebean.MergeOptions;
|
||||
import io.ebean.Query;
|
||||
import io.ebean.SqlUpdate;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.Update;
|
||||
import io.avaje.lang.Nullable;
|
||||
import io.ebean.*;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.meta.MetricVisitor;
|
||||
import io.ebeaninternal.api.SpiSqlUpdate;
|
||||
@@ -31,9 +27,9 @@ public interface Persister {
|
||||
void update(EntityBean entityBean, Transaction t);
|
||||
|
||||
/**
|
||||
* Force an Insert using the given bean.
|
||||
* Perform an Insert using the given bean.
|
||||
*/
|
||||
void insert(EntityBean entityBean, Transaction t);
|
||||
void insert(EntityBean entityBean, @Nullable InsertOptions insertOptions, @Nullable Transaction t);
|
||||
|
||||
/**
|
||||
* Insert or update the bean depending on its state.
|
||||
@@ -44,7 +40,6 @@ public interface Persister {
|
||||
* Delete a bean given it's type and id value.
|
||||
* <p>
|
||||
* This will also cascade delete one level of children.
|
||||
* </p>
|
||||
*/
|
||||
int delete(Class<?> beanType, Object id, Transaction transaction, boolean permanent);
|
||||
|
||||
|
||||
@@ -2056,6 +2056,13 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
pc.clear(rootBeanType, idValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear a bean from the persistence context.
|
||||
*/
|
||||
public void contextClear(PersistenceContext pc) {
|
||||
pc.clear(rootBeanType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a bean from the persistence context (such that we don't fetch it in the same transaction).
|
||||
*/
|
||||
|
||||
@@ -399,7 +399,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
||||
* Return the BeanDescriptors mapped to the table.
|
||||
*/
|
||||
public List<BeanDescriptor<?>> descriptors(String tableName) {
|
||||
return tableToDescMap.get(tableName.toLowerCase());
|
||||
return tableName == null ? Collections.emptyList() : tableToDescMap.get(tableName.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -411,7 +411,7 @@ public final class DefaultPersister implements Persister {
|
||||
if (bean._ebean_getIntercept().isUpdate()) {
|
||||
update(bean, t);
|
||||
} else {
|
||||
insert(bean, t);
|
||||
insert(bean, null, t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,12 +419,15 @@ public final class DefaultPersister implements Persister {
|
||||
* Insert this bean.
|
||||
*/
|
||||
@Override
|
||||
public void insert(EntityBean bean, Transaction t) {
|
||||
public void insert(EntityBean bean, InsertOptions insertOptions, Transaction t) {
|
||||
PersistRequestBean<?> req = createRequest(bean, t, PersistRequest.Type.INSERT);
|
||||
if (req.isSkipReference()) {
|
||||
// skip insert on reference bean
|
||||
return;
|
||||
}
|
||||
if (insertOptions != null) {
|
||||
req.setInsertOptions(insertOptions);
|
||||
}
|
||||
try {
|
||||
req.initTransIfRequiredWithBatchCascade();
|
||||
insert(req);
|
||||
|
||||
@@ -328,7 +328,7 @@ final class SaveManyBeans extends SaveManyBase {
|
||||
}
|
||||
|
||||
private boolean isChangedProperty() {
|
||||
return parentBean._ebean_getIntercept().isChangedProperty(many.propertyIndex());
|
||||
return request.isChangedProperty(many.propertyIndex());
|
||||
}
|
||||
|
||||
private void removeAssocManyOrphans() {
|
||||
|
||||
+9
-1
@@ -1,11 +1,15 @@
|
||||
package io.ebeaninternal.server.persist.dml;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Helper to support the generation of DML statements.
|
||||
*/
|
||||
public final class GenerateDmlRequest {
|
||||
|
||||
private final StringBuilder sb = new StringBuilder(100);
|
||||
private final List<String> columns = new ArrayList<>();
|
||||
private StringBuilder insertBindBuffer;
|
||||
private String prefix;
|
||||
private String prefix2;
|
||||
@@ -26,7 +30,7 @@ public final class GenerateDmlRequest {
|
||||
++bindColumnCount;
|
||||
sb.append(prefix);
|
||||
sb.append(column);
|
||||
//sb.append(expr);
|
||||
columns.add(column);
|
||||
if (insertMode > 0) {
|
||||
if (insertMode++ > 1) {
|
||||
insertBindBuffer.append(',');
|
||||
@@ -75,4 +79,8 @@ public final class GenerateDmlRequest {
|
||||
public boolean isUpdate() {
|
||||
return insertMode == 0;
|
||||
}
|
||||
|
||||
public List<String> columns() {
|
||||
return columns;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public final class InsertHandler extends DmlHandler {
|
||||
|
||||
SpiTransaction t = persistRequest.transaction();
|
||||
// get the appropriate sql
|
||||
sql = meta.getSql(withId, persistRequest.isPublish());
|
||||
sql = meta.sql(withId, persistRequest.isPublish(), persistRequest.insertOptions());
|
||||
PreparedStatement pstmt;
|
||||
if (persistRequest.isBatched()) {
|
||||
pstmt = pstmtBatch(t, sql, persistRequest, useGeneratedKeys);
|
||||
@@ -134,7 +134,8 @@ public final class InsertHandler extends DmlHandler {
|
||||
if (idValue != null) {
|
||||
persistRequest.setGeneratedKey(idValue);
|
||||
}
|
||||
} else {
|
||||
} else if (persistRequest.insertOptions() == null) {
|
||||
// insert on conflict do nothing can not return generated key
|
||||
throw new PersistenceException("Autoincrement getGeneratedKeys() returned no rows?");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.ebeaninternal.server.persist.dml;
|
||||
|
||||
import io.ebean.InsertOptions;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
@@ -36,9 +37,11 @@ final class InsertMeta {
|
||||
private final Bindable shadowFKey;
|
||||
private final String[] identityDbColumns;
|
||||
private final Platform platform;
|
||||
private final InsertMetaOptions options;
|
||||
|
||||
InsertMeta(DatabasePlatform dbPlatform, BeanDescriptor<?> desc, Bindable shadowFKey, BindableId id, BindableList all) {
|
||||
this.platform = dbPlatform.platform();
|
||||
this.options = InsertMetaPlatform.create(platform, desc, this);
|
||||
this.discriminator = discriminator(desc);
|
||||
this.id = id;
|
||||
this.all = all;
|
||||
@@ -47,8 +50,8 @@ final class InsertMeta {
|
||||
|
||||
String tableName = desc.baseTable();
|
||||
String draftTableName = desc.draftTable();
|
||||
this.sqlWithId = genSql(false, tableName, false);
|
||||
this.sqlDraftWithId = desc.isDraftable() ? genSql(false, draftTableName, true) : sqlWithId;
|
||||
this.sqlWithId = sql(false, tableName, false);
|
||||
this.sqlDraftWithId = desc.isDraftable() ? sql(false, draftTableName, true) : sqlWithId;
|
||||
|
||||
// only available for single Id property
|
||||
if (id.isConcatenated()) {
|
||||
@@ -72,8 +75,8 @@ final class InsertMeta {
|
||||
this.supportsGetGeneratedKeys = dbPlatform.dbIdentity().isSupportsGetGeneratedKeys();
|
||||
this.supportsSelectLastInsertedId = desc.supportsSelectLastInsertedId();
|
||||
}
|
||||
this.sqlNullId = genSql(true, tableName, false);
|
||||
this.sqlDraftNullId = desc.isDraftable() ? genSql(true, draftTableName, true) : sqlNullId;
|
||||
this.sqlNullId = sql(true, tableName, false);
|
||||
this.sqlDraftNullId = desc.isDraftable() ? sql(true, draftTableName, true) : sqlNullId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,9 +140,20 @@ final class InsertMeta {
|
||||
}
|
||||
|
||||
/**
|
||||
* get the sql based whether the id value(s) are null.
|
||||
* Return the sql for the given options.
|
||||
*/
|
||||
public String getSql(boolean withId, boolean publish) {
|
||||
public String sql(boolean withId, boolean publish, InsertOptions insertOptions) {
|
||||
if (insertOptions == null) {
|
||||
return sql(withId, publish);
|
||||
}
|
||||
return options.sql(withId, insertOptions);
|
||||
}
|
||||
|
||||
String sqlFor(boolean withId) {
|
||||
return withId ? sqlWithId : sqlNullId;
|
||||
}
|
||||
|
||||
private String sql(boolean withId, boolean publish) {
|
||||
if (withId) {
|
||||
return publish ? sqlWithId : sqlDraftWithId;
|
||||
} else {
|
||||
@@ -147,12 +161,18 @@ final class InsertMeta {
|
||||
}
|
||||
}
|
||||
|
||||
private String genSql(boolean nullId, String table, boolean draftTable) {
|
||||
private String sql(boolean nullId, String table, boolean draftTable) {
|
||||
GenerateDmlRequest request = new GenerateDmlRequest();
|
||||
sql(request, nullId, table, draftTable);
|
||||
return request.toString();
|
||||
}
|
||||
|
||||
void sql(GenerateDmlRequest request, boolean nullId, String table, boolean draftTable) {
|
||||
request.setInsertSetMode();
|
||||
request.append("insert into ").append(table);
|
||||
if (nullId && noColumnsForInsert(draftTable)) {
|
||||
return request.append(defaultValues()).toString();
|
||||
request.append(defaultValues());
|
||||
return;
|
||||
}
|
||||
request.append(" (");
|
||||
if (!nullId) {
|
||||
@@ -172,7 +192,6 @@ final class InsertMeta {
|
||||
request.append(") values (");
|
||||
request.append(request.insertBindBuffer());
|
||||
request.append(")");
|
||||
return request.toString();
|
||||
}
|
||||
|
||||
private String defaultValues() {
|
||||
@@ -196,5 +215,4 @@ final class InsertMeta {
|
||||
&& discriminator == null
|
||||
&& (draftTable ? all.isEmpty() : allExcludeDraftOnly.isEmpty());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.ebeaninternal.server.persist.dml;
|
||||
|
||||
import io.ebean.InsertOptions;
|
||||
|
||||
/**
|
||||
* Generator for insert SQL with options.
|
||||
*/
|
||||
interface InsertMetaOptions {
|
||||
|
||||
/**
|
||||
* Generate the SQL for the given insert options.
|
||||
*/
|
||||
String sql(boolean withId, InsertOptions insertOptions);
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
package io.ebeaninternal.server.persist.dml;
|
||||
|
||||
import io.ebean.InsertOptions;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Postgres specific generation of insert on conflict.
|
||||
*/
|
||||
final class InsertMetaOptionsPostgres implements InsertMetaOptions {
|
||||
|
||||
private final InsertMeta meta;
|
||||
private final BeanDescriptor<?> desc;
|
||||
private final String baseTable;
|
||||
private final Map<String, String> sqlCache = new ConcurrentHashMap<>();
|
||||
|
||||
InsertMetaOptionsPostgres(InsertMeta meta, BeanDescriptor<?> desc) {
|
||||
this.meta = meta;
|
||||
this.desc = desc;
|
||||
this.baseTable = desc.baseTable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sql(boolean withId, InsertOptions options) {
|
||||
String key = withId + options.key();
|
||||
return sqlCache.computeIfAbsent(key, k -> generate(withId, options));
|
||||
}
|
||||
|
||||
private String generate(boolean withId, InsertOptions options) {
|
||||
char type = options.key().charAt(0);
|
||||
switch (type) {
|
||||
case 'U':
|
||||
return generate(withId, false, options);
|
||||
case 'N':
|
||||
return generate(withId, true, options);
|
||||
default:
|
||||
return meta.sqlFor(withId);
|
||||
}
|
||||
}
|
||||
|
||||
private String generate(boolean withId, boolean doNothing, InsertOptions options) {
|
||||
GenerateDmlRequest request = new GenerateDmlRequest();
|
||||
meta.sql(request, !withId, baseTable, false);
|
||||
request.append(" on conflict ");
|
||||
|
||||
List<String> uniqueColumns = desc.uniqueProps().stream()
|
||||
.flatMap(Arrays::stream)
|
||||
.map(BeanProperty::dbColumn)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
String constraintName = options.constraint();
|
||||
if (constraintName != null) {
|
||||
request.append("on constraint ").append(constraintName);
|
||||
} else {
|
||||
request.append("(");
|
||||
String cols = options.uniqueColumns();
|
||||
if (cols != null) {
|
||||
request.append(cols);
|
||||
} else {
|
||||
appendUniqueColumns(uniqueColumns, request);
|
||||
}
|
||||
request.append(")");
|
||||
}
|
||||
if (doNothing) {
|
||||
request.append(" do nothing");
|
||||
return request.toString();
|
||||
}
|
||||
request.append(" do update set ");
|
||||
String updateSet = options.updateSet();
|
||||
if (updateSet != null) {
|
||||
request.append(updateSet);
|
||||
} else {
|
||||
setColumns(withId, request, uniqueColumns);
|
||||
}
|
||||
return request.toString();
|
||||
}
|
||||
|
||||
private void setColumns(boolean withId, GenerateDmlRequest request, List<String> uniqueColumns) {
|
||||
List<String> columns = request.columns();
|
||||
columns.removeAll(uniqueColumns);
|
||||
if (withId) {
|
||||
BeanProperty idProperty = desc.idProperty();
|
||||
if (idProperty != null && !idProperty.isEmbedded()) {
|
||||
columns.remove(idProperty.dbColumn());
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
if (i > 0) {
|
||||
request.append(", ");
|
||||
}
|
||||
String col = columns.get(i);
|
||||
request.append(col).append("=excluded.").append(col);
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendUniqueColumns(List<String> uniqueColumns, GenerateDmlRequest request) {
|
||||
if (uniqueColumns.isEmpty()) {
|
||||
throw new IllegalStateException("Unable to identify unique columns for INSERT ON CONFLICT - Add mapping like @Column(unique=true) or @Index(unique=true)");
|
||||
}
|
||||
for (int i = 0; i < uniqueColumns.size(); i++) {
|
||||
if (i > 0) {
|
||||
request.append(", ");
|
||||
}
|
||||
request.append(uniqueColumns.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package io.ebeaninternal.server.persist.dml;
|
||||
|
||||
import io.ebean.InsertOptions;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
|
||||
final class InsertMetaPlatform {
|
||||
|
||||
private static final NotSupported NOT_SUPPORTED = new NotSupported();
|
||||
|
||||
static InsertMetaOptions create(Platform platform, BeanDescriptor<?> desc, InsertMeta meta) {
|
||||
switch (platform.base()) {
|
||||
case POSTGRES:
|
||||
case YUGABYTE:
|
||||
case COCKROACH:
|
||||
return new InsertMetaOptionsPostgres(meta, desc);
|
||||
default:
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
static final class NotSupported implements InsertMetaOptions {
|
||||
@Override
|
||||
public String sql(boolean withId, InsertOptions insertOptions) {
|
||||
throw new UnsupportedOperationException("InsertOptions not supported on this database platform");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -186,7 +186,7 @@ public final class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfi
|
||||
this.queryMode = query.mode();
|
||||
this.loadContextBean = queryMode.isLoadContextBean() || query.getForUpdateLockType() != null;
|
||||
this.lazyLoadManyProperty = query.lazyLoadMany();
|
||||
this.readOnly = request.isReadOnly();
|
||||
this.readOnly = query.isReadOnly();
|
||||
this.disableLazyLoading = query.isDisableLazyLoading();
|
||||
this.objectGraphNode = query.parentNode();
|
||||
this.profilingListener = query.profilingListener();
|
||||
|
||||
@@ -74,6 +74,9 @@ public final class CQueryEngine {
|
||||
if (request.logSql()) {
|
||||
request.logSql("{0}; --bind({1}) --micros({2}) --rows({3})", query.generatedSql(), query.bindLog(), query.micros(), rows);
|
||||
}
|
||||
if (rows > 0) {
|
||||
request.clearContext();
|
||||
}
|
||||
return rows;
|
||||
} catch (SQLException e) {
|
||||
throw translate(request, query.bindLog(), query.generatedSql(), e);
|
||||
|
||||
@@ -61,6 +61,7 @@ final class CQueryUpdate implements SpiProfileTransactionEvent, CancelableQuery
|
||||
/**
|
||||
* Execute the update or delete statement returning the row count.
|
||||
*/
|
||||
@SuppressWarnings("resource")
|
||||
public int execute() throws SQLException {
|
||||
long startNano = System.nanoTime();
|
||||
try {
|
||||
@@ -109,6 +110,7 @@ final class CQueryUpdate implements SpiProfileTransactionEvent, CancelableQuery
|
||||
pstmt = null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@Override
|
||||
public void profile() {
|
||||
transaction()
|
||||
|
||||
@@ -305,6 +305,11 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A> Optional<A> findSingleAttributeOrEmpty() {
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCountDistinct() {
|
||||
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
|
||||
|
||||
@@ -51,6 +51,10 @@ public final class DefaultOrmQueryEngine implements OrmQueryEngine {
|
||||
* Flushes the jdbc batch by default unless explicitly turned off on the transaction.
|
||||
*/
|
||||
private <T> void flushJdbcBatchOnQuery(OrmQueryRequest<T> request) {
|
||||
if (request.query().isUsingFuture()) {
|
||||
// future queries never invoke a flush
|
||||
return;
|
||||
}
|
||||
SpiTransaction t = request.transaction();
|
||||
if (t.isFlushOnQuery()) {
|
||||
// before we perform a query, we need to flush any
|
||||
|
||||
@@ -9,8 +9,10 @@ import io.ebeaninternal.api.*;
|
||||
import io.ebeaninternal.server.dto.DtoBeanDescriptor;
|
||||
import io.ebeaninternal.server.dto.DtoMappingRequest;
|
||||
import io.ebeaninternal.server.dto.DtoQueryPlan;
|
||||
import io.ebeaninternal.server.transaction.ExternalJdbcTransaction;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.sql.Connection;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -86,6 +88,12 @@ public final class DefaultDtoQuery<T> extends AbstractQuery implements SpiDtoQue
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DtoQuery<T> usingConnection(Connection connection) {
|
||||
this.transaction = new ExternalJdbcTransaction(connection);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DtoQuery<T> usingMaster() {
|
||||
this.useMaster = true;
|
||||
|
||||
@@ -58,6 +58,7 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
private Type type;
|
||||
private String label;
|
||||
private Mode mode = Mode.NORMAL;
|
||||
private boolean usingFuture;
|
||||
private Object tenantId;
|
||||
/**
|
||||
* Holds query in structured form.
|
||||
@@ -971,6 +972,16 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void usingFuture() {
|
||||
this.usingFuture = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isUsingFuture() {
|
||||
return usingFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isUsageProfiling() {
|
||||
return usageProfiling;
|
||||
@@ -1161,7 +1172,7 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
// add the rawSql statement - if any
|
||||
if (orderByIsEmpty()) {
|
||||
if (rawSql != null && rawSql.getSql() != null) {
|
||||
order(rawSql.getSql().getOrderBy());
|
||||
orderBy(rawSql.getSql().getOrderBy());
|
||||
}
|
||||
}
|
||||
if (checkPagingOrderBy()) {
|
||||
@@ -1517,7 +1528,6 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public final <A> List<A> findSingleAttributeList() {
|
||||
return server.findSingleAttributeList(this);
|
||||
}
|
||||
@@ -1533,6 +1543,11 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
|
||||
return !list.isEmpty() ? list.get(0) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <A> Optional<A> findSingleAttributeOrEmpty() {
|
||||
return Optional.ofNullable(findSingleAttribute());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final T findOne() {
|
||||
return server.findOne(this);
|
||||
|
||||
@@ -7,7 +7,9 @@ import io.ebeaninternal.api.BindParams;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiSqlQuery;
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
import io.ebeaninternal.server.transaction.ExternalJdbcTransaction;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
@@ -50,6 +52,12 @@ public final class DefaultRelationalQuery extends AbstractQuery implements SpiSq
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlQuery usingConnection(Connection connection) {
|
||||
this.transaction = new ExternalJdbcTransaction(connection);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlQuery usingMaster() {
|
||||
this.useMaster = true;
|
||||
|
||||
@@ -2,12 +2,13 @@ package io.ebeaninternal.server.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EmptyStackException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Stack based on ArrayList.
|
||||
*/
|
||||
public class ArrayStack<E> {
|
||||
public class ArrayStack<E> implements Iterable<E> {
|
||||
|
||||
private final List<E> list;
|
||||
|
||||
@@ -89,4 +90,9 @@ public class ArrayStack<E> {
|
||||
public boolean contains(E o) {
|
||||
return list.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return list.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean ddl generation</name>
|
||||
@@ -28,14 +28,14 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-all</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean postgis types</name>
|
||||
<artifactId>ebean-postgis-types</artifactId>
|
||||
|
||||
<properties>
|
||||
<postgis.jdbc.version>2021.1.0</postgis.jdbc.version>
|
||||
<postgis.jdbc.version>2.5.1</postgis.jdbc.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -19,14 +19,14 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- provided scope -->
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ package io.ebean.postgis;
|
||||
|
||||
import io.ebean.core.type.DataBinder;
|
||||
import io.ebeaninternal.server.type.GeoTypeBinder;
|
||||
import net.postgis.jdbc.PGgeometryLW;
|
||||
import net.postgis.jdbc.geometry.Geometry;
|
||||
import org.geolatte.geom.codec.Wkt;
|
||||
import org.postgis.Geometry;
|
||||
import org.postgis.PGgeometryLW;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
@@ -18,15 +18,15 @@ class PostgisGeoTypeBinder implements GeoTypeBinder {
|
||||
|
||||
@Override
|
||||
public void bind(DataBinder binder, int dataType, Object data) throws SQLException {
|
||||
if (data instanceof Geometry) {
|
||||
binder.setObject(new PGgeometryLW((Geometry) data));
|
||||
} else if (withGeolatte) {
|
||||
binder.setObject(new PGgeometryLW(toWktString(data)));
|
||||
}
|
||||
if (data instanceof Geometry) {
|
||||
binder.setObject(new PGgeometryLW((Geometry) data));
|
||||
} else if (withGeolatte) {
|
||||
binder.setObject(new PGgeometryLW(toWktString(data)));
|
||||
}
|
||||
}
|
||||
|
||||
private String toWktString(Object data) {
|
||||
org.geolatte.geom.Geometry<?> geoLatte = (org.geolatte.geom.Geometry<?>) data;
|
||||
org.geolatte.geom.Geometry<?> geoLatte = (org.geolatte.geom.Geometry<?>)data;
|
||||
return Wkt.newEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geoLatte);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ import io.ebean.core.type.DataBinder;
|
||||
import io.ebean.core.type.DataReader;
|
||||
import io.ebean.core.type.DocPropertyType;
|
||||
import io.ebean.core.type.ScalarType;
|
||||
import net.postgis.jdbc.geometry.Geometry;
|
||||
import net.postgis.jdbc.geometry.GeometryBuilder;
|
||||
import net.postgis.jdbc.geometry.binary.BinaryParser;
|
||||
import net.postgis.jdbc.PGgeometry;
|
||||
import net.postgis.jdbc.PGgeometryLW;
|
||||
import org.postgis.Geometry;
|
||||
import org.postgis.GeometryBuilder;
|
||||
import org.postgis.PGgeometry;
|
||||
import org.postgis.PGgeometryLW;
|
||||
import org.postgis.binary.BinaryParser;
|
||||
import org.postgresql.util.PGobject;
|
||||
|
||||
import java.io.DataInput;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.ebean.postgis;
|
||||
|
||||
import io.ebean.config.dbplatform.ExtraDbTypes;
|
||||
import net.postgis.jdbc.geometry.LineString;
|
||||
import org.postgis.LineString;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package io.ebean.postgis;
|
||||
|
||||
import io.ebean.config.dbplatform.ExtraDbTypes;
|
||||
import net.postgis.jdbc.geometry.MultiLineString;
|
||||
import org.postgis.MultiLineString;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.ebean.postgis;
|
||||
|
||||
import io.ebean.config.dbplatform.ExtraDbTypes;
|
||||
import net.postgis.jdbc.geometry.MultiPoint;
|
||||
import org.postgis.MultiPoint;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.ebean.postgis;
|
||||
|
||||
import io.ebean.config.dbplatform.ExtraDbTypes;
|
||||
import net.postgis.jdbc.geometry.MultiPolygon;
|
||||
import org.postgis.MultiPolygon;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.ebean.postgis;
|
||||
|
||||
import io.ebean.config.dbplatform.ExtraDbTypes;
|
||||
import net.postgis.jdbc.geometry.Point;
|
||||
import org.postgis.Point;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.ebean.postgis;
|
||||
|
||||
import io.ebean.config.dbplatform.ExtraDbTypes;
|
||||
import net.postgis.jdbc.geometry.Polygon;
|
||||
import org.postgis.Polygon;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
+3
-3
@@ -8,8 +8,8 @@ import io.ebean.core.type.DocPropertyType;
|
||||
import io.ebean.core.type.ScalarType;
|
||||
import org.geolatte.geom.Geometry;
|
||||
import org.geolatte.geom.codec.Wkt;
|
||||
import net.postgis.jdbc.PGgeometry;
|
||||
import net.postgis.jdbc.PGgeometryLW;
|
||||
import org.postgis.PGgeometry;
|
||||
import org.postgis.PGgeometryLW;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
@@ -61,7 +61,7 @@ abstract class ScalarTypeGeoLatteBase<T extends Geometry> implements ScalarType<
|
||||
return null;
|
||||
}
|
||||
if (object instanceof PGgeometry) {
|
||||
net.postgis.jdbc.geometry.Geometry geometry = ((PGgeometry) object).getGeometry();
|
||||
org.postgis.Geometry geometry = ((PGgeometry) object).getGeometry();
|
||||
return (T) Wkt.newDecoder(Wkt.Dialect.POSTGIS_EWKT_1).decode(geometry.toString());
|
||||
}
|
||||
throw new IllegalStateException("Received object of type " + object.getClass().getCanonicalName());
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.example.domain;
|
||||
|
||||
import io.ebean.annotation.Cache;
|
||||
import net.postgis.jdbc.geometry.Point;
|
||||
import net.postgis.jdbc.geometry.Polygon;
|
||||
import org.postgis.Point;
|
||||
import org.postgis.Polygon;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package org.example.domain;
|
||||
|
||||
import net.postgis.jdbc.geometry.LineString;
|
||||
import net.postgis.jdbc.geometry.MultiLineString;
|
||||
import net.postgis.jdbc.geometry.MultiPoint;
|
||||
import net.postgis.jdbc.geometry.MultiPolygon;
|
||||
import net.postgis.jdbc.geometry.Point;
|
||||
import net.postgis.jdbc.geometry.Polygon;
|
||||
import org.postgis.LineString;
|
||||
import org.postgis.MultiLineString;
|
||||
import org.postgis.MultiPoint;
|
||||
import org.postgis.MultiPolygon;
|
||||
import org.postgis.Point;
|
||||
import org.postgis.Polygon;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
|
||||
@@ -2,8 +2,8 @@ package org.example.domain;
|
||||
|
||||
import io.ebean.DB;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import net.postgis.jdbc.geometry.Point;
|
||||
import net.postgis.jdbc.geometry.Polygon;
|
||||
import org.postgis.Point;
|
||||
import org.postgis.Polygon;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@ package org.example.domain;
|
||||
|
||||
import io.ebean.DB;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import net.postgis.jdbc.geometry.LineString;
|
||||
import net.postgis.jdbc.geometry.MultiLineString;
|
||||
import net.postgis.jdbc.geometry.MultiPoint;
|
||||
import net.postgis.jdbc.geometry.MultiPolygon;
|
||||
import net.postgis.jdbc.geometry.Point;
|
||||
import net.postgis.jdbc.geometry.Polygon;
|
||||
import org.postgis.LineString;
|
||||
import org.postgis.MultiLineString;
|
||||
import org.postgis.MultiPoint;
|
||||
import org.postgis.MultiPolygon;
|
||||
import org.postgis.Point;
|
||||
import org.postgis.Polygon;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
@@ -181,7 +181,7 @@ public class TestQuery {
|
||||
.find(MyBean.class)
|
||||
.where()
|
||||
.raw("st_distance(wgs84Point, ?) < 0.011", toWkt(geolatteClosePoint))
|
||||
.raw("st_distance(wgs84Point, ?) < 0.011", new net.postgis.jdbc.geometry.Point(toWkt(geolatteClosePoint)))
|
||||
.raw("st_distance(wgs84Point, ?) < 0.011", new org.postgis.Point(toWkt(geolatteClosePoint)))
|
||||
.findOne()
|
||||
);
|
||||
|
||||
@@ -190,7 +190,7 @@ public class TestQuery {
|
||||
.find(MyBean.class)
|
||||
.where()
|
||||
.raw("st_distance(wgs84Point, ?) < 0.009", toWkt(geolatteClosePoint))
|
||||
.raw("st_distance(wgs84Point, ?) < 0.009", new net.postgis.jdbc.geometry.Point(toWkt(geolatteClosePoint)))
|
||||
.raw("st_distance(wgs84Point, ?) < 0.009", new org.postgis.Point(toWkt(geolatteClosePoint)))
|
||||
.findOne()
|
||||
);
|
||||
|
||||
@@ -199,7 +199,7 @@ public class TestQuery {
|
||||
.find(MyBean.class)
|
||||
.where()
|
||||
.raw("ST_Within(wgs84Point, ST_GeomFromText(?))", toWkt(enclosingPolygon))
|
||||
.raw("ST_Within(wgs84Point, ?)", new net.postgis.jdbc.geometry.Polygon(toWkt(enclosingPolygon)))
|
||||
.raw("ST_Within(wgs84Point, ?)", new org.postgis.Polygon(toWkt(enclosingPolygon)))
|
||||
.findOne()
|
||||
);
|
||||
|
||||
@@ -207,7 +207,7 @@ public class TestQuery {
|
||||
DB.find(MyBean.class)
|
||||
.where()
|
||||
.raw("wgs84Point = ST_PointN(ST_GeomFromText(?), 2)", toWkt(lineString))
|
||||
.raw("wgs84Point = ST_PointN(?, 2)", new net.postgis.jdbc.geometry.LineString(toWkt(lineString)))
|
||||
.raw("wgs84Point = ST_PointN(?, 2)", new org.postgis.LineString(toWkt(lineString)))
|
||||
.findOne()
|
||||
);
|
||||
|
||||
@@ -215,7 +215,7 @@ public class TestQuery {
|
||||
DB.find(OtherBeanGeoLatte.class)
|
||||
.where()
|
||||
.raw("wgs84Point = ST_PointN(ST_LineFromMultiPoint(ST_GeomFromText(?)), 2)", toWkt(multiPoint))
|
||||
.raw("wgs84Point = ST_PointN(ST_LineFromMultiPoint(?), 2)", new net.postgis.jdbc.geometry.MultiPoint(toWkt(multiPoint)))
|
||||
.raw("wgs84Point = ST_PointN(ST_LineFromMultiPoint(?), 2)", new org.postgis.MultiPoint(toWkt(multiPoint)))
|
||||
.findOne()
|
||||
);
|
||||
|
||||
@@ -223,7 +223,7 @@ public class TestQuery {
|
||||
DB.find(OtherBeanGeoLatte.class)
|
||||
.where()
|
||||
.raw("wgs84Point = ST_PointN(ST_LineFromMultiPoint(ST_GeomFromText(?)), 2)", toWkt(multiPoint))
|
||||
.raw("wgs84Point = ST_PointN(ST_LineFromMultiPoint(?), 2)", new net.postgis.jdbc.geometry.MultiPoint(toWkt(multiPoint)))
|
||||
.raw("wgs84Point = ST_PointN(ST_LineFromMultiPoint(?), 2)", new org.postgis.MultiPoint(toWkt(multiPoint)))
|
||||
.findOne()
|
||||
);
|
||||
|
||||
@@ -232,7 +232,7 @@ public class TestQuery {
|
||||
.find(MyBean.class)
|
||||
.where()
|
||||
.raw("ST_Within(wgs84Point, ST_GeomFromText(?))", toWkt(multiPolygon))
|
||||
.raw("ST_Within(wgs84Point, ?)", new net.postgis.jdbc.geometry.MultiPolygon(toWkt(multiPolygon)))
|
||||
.raw("ST_Within(wgs84Point, ?)", new org.postgis.MultiPolygon(toWkt(multiPolygon)))
|
||||
.findOne()
|
||||
);
|
||||
|
||||
@@ -240,7 +240,7 @@ public class TestQuery {
|
||||
DB.find(OtherBeanGeoLatte.class)
|
||||
.where()
|
||||
.raw("ST_Intersects(wgs84Point, ST_GeomFromText(?))", toWkt(multiLineString))
|
||||
.raw("ST_Intersects(wgs84Point, ?)", new net.postgis.jdbc.geometry.MultiLineString(toWkt(multiLineString)))
|
||||
.raw("ST_Intersects(wgs84Point, ?)", new org.postgis.MultiLineString(toWkt(multiLineString)))
|
||||
.findOne()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,4 +15,4 @@ ebean:
|
||||
image: ghcr.io/baosystems/postgis:15
|
||||
# extensions: postgis
|
||||
# url: jdbc:postgresql_lwgis://localhost:6432/mygisapp
|
||||
driver: net.postgis.jdbc.DriverWrapperLW
|
||||
# driver: org.postgis.DriverWrapperLW
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean querybean</name>
|
||||
@@ -17,7 +17,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -63,14 +63,14 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>querybean-generator</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ public abstract class PBaseString<R, T> extends PBaseComparable<R, T> {
|
||||
* @param value the equal to bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated(forRemoval = true)
|
||||
public final R equalToType(T value) {
|
||||
expr().eq(_name, value);
|
||||
return _root;
|
||||
@@ -46,7 +46,7 @@ public abstract class PBaseString<R, T> extends PBaseComparable<R, T> {
|
||||
* @param value the equal to bind value
|
||||
* @return the root query bean instance
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated(forRemoval = true)
|
||||
public final R notEqualToType(T value) {
|
||||
expr().ne(_name, value);
|
||||
return _root;
|
||||
|
||||
@@ -745,7 +745,7 @@ public abstract class TQRootBean<T, R> {
|
||||
* Add EXISTS sub-query predicate.
|
||||
*/
|
||||
public R exists(Query<?> subQuery) {
|
||||
query.where().exists(subQuery);
|
||||
peekExprList().exists(subQuery);
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -753,7 +753,7 @@ public abstract class TQRootBean<T, R> {
|
||||
* Add NOT EXISTS sub-query predicate.
|
||||
*/
|
||||
public R notExists(Query<?> subQuery) {
|
||||
query.where().notExists(subQuery);
|
||||
peekExprList().notExists(subQuery);
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -764,7 +764,7 @@ public abstract class TQRootBean<T, R> {
|
||||
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
|
||||
*/
|
||||
public final R exists(String sqlSubQuery, Object... bindValues) {
|
||||
query().where().exists(sqlSubQuery, bindValues);
|
||||
peekExprList().exists(sqlSubQuery, bindValues);
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -775,7 +775,7 @@ public abstract class TQRootBean<T, R> {
|
||||
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
|
||||
*/
|
||||
public final R notExists(String sqlSubQuery, Object... bindValues) {
|
||||
query().where().notExists(sqlSubQuery, bindValues);
|
||||
peekExprList().notExists(sqlSubQuery, bindValues);
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -1275,7 +1275,7 @@ public abstract class TQRootBean<T, R> {
|
||||
/**
|
||||
* @deprecated migrate to {@link #orderBy()}.
|
||||
*/
|
||||
@Deprecated(since = "13.19")
|
||||
@Deprecated(since = "13.19", forRemoval = true)
|
||||
public R order() {
|
||||
return root;
|
||||
}
|
||||
@@ -1295,7 +1295,7 @@ public abstract class TQRootBean<T, R> {
|
||||
/**
|
||||
* @deprecated migrate to {@link #orderBy(String)}
|
||||
*/
|
||||
@Deprecated(since = "13.19")
|
||||
@Deprecated(since = "13.19", forRemoval = true)
|
||||
public R order(String orderByClause) {
|
||||
return orderBy(orderByClause);
|
||||
}
|
||||
@@ -1867,6 +1867,28 @@ public abstract class TQRootBean<T, R> {
|
||||
return query.findSingleAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query returning a single optional attribute value.
|
||||
* <p>
|
||||
* <h3>Example</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* Optional<String> maybeName =
|
||||
* new QCustomer()
|
||||
* .select(name)
|
||||
* .id.eq(42)
|
||||
* .status.eq(NEW)
|
||||
* .findSingleAttributeOrEmpty();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @return an optional value for the selected property
|
||||
*/
|
||||
@Nullable
|
||||
public <A> Optional<A> findSingleAttributeOrEmpty() {
|
||||
return query.findSingleAttributeOrEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query processing the beans one at a time.
|
||||
* <p>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package org.example.domain;
|
||||
|
||||
import io.ebean.annotation.DbArray;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import org.example.domain.finder.ContactFinder;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.time.ZonedDateTime;
|
||||
@@ -17,6 +18,11 @@ import java.util.Map;
|
||||
@Table(name = "be_contact")
|
||||
public class Contact extends BaseModel {
|
||||
|
||||
/**
|
||||
* Convenience Finder for 'active record' style.
|
||||
*/
|
||||
public static final ContactFinder find = new ContactFinder();
|
||||
|
||||
@DbArray
|
||||
List<@Size(max=20) String> phoneNumbers = new ArrayList<>();
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.example.domain.finder;
|
||||
|
||||
import io.ebean.Finder;
|
||||
import org.example.domain.Contact;
|
||||
import org.example.domain.query.QContact;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ContactFinder extends Finder<Long, Contact> {
|
||||
|
||||
public ContactFinder() {
|
||||
super(Contact.class);
|
||||
}
|
||||
|
||||
public QContact typed() {
|
||||
return new QContact();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.querytest;
|
||||
|
||||
import org.example.domain.Contact;
|
||||
import org.example.domain.Customer;
|
||||
import org.example.domain.query.QCustomer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDate;
|
||||
@@ -9,6 +11,8 @@ import java.time.ZoneId;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class QCustomerAndOrTest {
|
||||
|
||||
@Test
|
||||
@@ -55,6 +59,30 @@ public class QCustomerAndOrTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrWithExists() {
|
||||
QCustomer query = Customer.find.typed()
|
||||
.alias("_cust")
|
||||
.or()
|
||||
.name.eq("Superman")
|
||||
.exists(Contact.find.typed()
|
||||
.alias("contact")
|
||||
.firstName.eq("Superman")
|
||||
.raw("contact.customer_id = _cust.id")
|
||||
.query()
|
||||
)
|
||||
.endOr()
|
||||
.select(QCustomer.alias().id);
|
||||
|
||||
query.findList();
|
||||
|
||||
assertThat(query.getGeneratedSql()).isEqualTo(
|
||||
"select _cust.id from be_customer _cust where (" +
|
||||
"_cust.name = ? or exists (select 1 from be_contact contact where " +
|
||||
"contact.first_name = ? and contact.customer_id = _cust.id))"
|
||||
);
|
||||
}
|
||||
|
||||
private Date fiveDaysAgo() {
|
||||
LocalDateTime fiveDaysAgo = LocalDate.now().atStartOfDay().minusDays(5);
|
||||
return new Date(fiveDaysAgo.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
|
||||
|
||||
@@ -63,6 +63,25 @@ public class QCustomerTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void copy() {
|
||||
var origin = new QCustomer()
|
||||
.setDistinct(true)
|
||||
.status.equalTo(Customer.Status.BAD);
|
||||
|
||||
var copy1 = origin.copy().name.isNotNull();
|
||||
var q1 = copy1.query();
|
||||
copy1.findList();
|
||||
|
||||
assertThat(q1.getGeneratedSql()).contains("from be_customer t0 where t0.status = ? and t0.name is not null");
|
||||
|
||||
var copy2 = origin.copy().version.ge(1L);
|
||||
var q2 = copy2.query();
|
||||
copy2.findList();
|
||||
|
||||
assertThat(q2.getGeneratedSql()).contains("from be_customer t0 where t0.status = ? and t0.version >= ?");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findSingleAttribute() {
|
||||
|
||||
@@ -1050,6 +1069,32 @@ public class QCustomerTest {
|
||||
assertThat(maxDate).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findSingleAttributeOrEmpty() {
|
||||
|
||||
Customer cust = new Customer();
|
||||
cust.setName("MaybeIExist yeah");
|
||||
cust.setStatus(Customer.Status.GOOD);
|
||||
cust.setRegistered(new Date());
|
||||
cust.save();
|
||||
|
||||
Optional<String> customerName = new QCustomer()
|
||||
.select(name)
|
||||
.status.eq(Customer.Status.GOOD)
|
||||
.name.startsWith("MaybeIExist")
|
||||
.findSingleAttributeOrEmpty();
|
||||
|
||||
assertThat(customerName).isPresent();
|
||||
|
||||
Optional<String> customerName2 = new QCustomer()
|
||||
.select(name)
|
||||
.status.eq(Customer.Status.GOOD)
|
||||
.name.eq("NahIDoNotExist")
|
||||
.findSingleAttributeOrEmpty();
|
||||
|
||||
assertThat(customerName2).isEmpty();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFetchByScalarValue() {
|
||||
|
||||
+6
-6
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-redis</artifactId>
|
||||
@@ -22,28 +22,28 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>querybean-generator</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-spring-txn</artifactId>
|
||||
@@ -28,7 +28,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
+6
-6
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean test</name>
|
||||
@@ -33,20 +33,20 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -149,14 +149,14 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-jackson-mapper</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-all</artifactId>
|
||||
<version>13.25.1-jakarta</version>
|
||||
<version>14.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.ebean.xtest.base;
|
||||
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.xtest.BaseTestCase;
|
||||
import io.ebean.DB;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
@@ -18,15 +19,17 @@ import org.tests.model.basic.ResetBasicData;
|
||||
*/
|
||||
public abstract class TransactionalTestCase extends BaseTestCase {
|
||||
|
||||
private Transaction transaction;
|
||||
|
||||
@BeforeEach
|
||||
public void startTransaction() {
|
||||
ResetBasicData.reset();
|
||||
DB.beginTransaction();
|
||||
transaction = DB.beginTransaction();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void endTransaction() {
|
||||
DB.rollbackTransaction();
|
||||
DB.endTransaction();
|
||||
transaction.rollback();
|
||||
transaction.end();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.ebean.xtest.common;
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.common.BeanList;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.tests.model.basic.Product;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
@@ -13,22 +14,22 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class BeanListTest {
|
||||
|
||||
private final Object object1 = new Object();
|
||||
private final Object object2 = new Object();
|
||||
private final Object object3 = new Object();
|
||||
private final Product object1 = new Product(1);
|
||||
private final Product object2 = new Product(2);
|
||||
private final Product object3 = new Product(3);
|
||||
|
||||
private List<Object> all() {
|
||||
List<Object> all = new ArrayList<>();
|
||||
all.add(object1);
|
||||
all.add(object2);
|
||||
all.add(object3);
|
||||
all.add(new Product(1));
|
||||
all.add(new Product(2));
|
||||
all.add(new Product(3));
|
||||
return all;
|
||||
}
|
||||
|
||||
private List<Object> some() {
|
||||
List<Object> some = new ArrayList<>();
|
||||
some.add(object2);
|
||||
some.add(object3);
|
||||
some.add(new Product(2));
|
||||
some.add(new Product(3));
|
||||
return some;
|
||||
}
|
||||
|
||||
@@ -163,14 +164,15 @@ public class BeanListTest {
|
||||
@Test
|
||||
public void testRemove_given_beansInAdditions() {
|
||||
|
||||
List<Object> all = all();
|
||||
BeanList<Object> list = new BeanList<>();
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
list.addAll(all());
|
||||
list.addAll(all);
|
||||
assertThat(list.modifyAdditions()).containsOnly(object1, object2, object3);
|
||||
|
||||
// act
|
||||
list.remove(object2);
|
||||
list.remove(object3);
|
||||
list.remove(all.get(1));
|
||||
list.remove(all.get(2));
|
||||
|
||||
assertThat(list.modifyAdditions()).containsOnly(object1);
|
||||
assertThat(list.modifyRemovals()).isEmpty();
|
||||
@@ -179,13 +181,14 @@ public class BeanListTest {
|
||||
@Test
|
||||
public void testRemoveAll_given_beansInAdditions() {
|
||||
|
||||
List<Object> all = all();
|
||||
BeanList<Object> list = new BeanList<>();
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
list.addAll(all());
|
||||
list.addAll(all);
|
||||
assertThat(list.modifyAdditions()).containsOnly(object1, object2, object3);
|
||||
|
||||
// act
|
||||
list.removeAll(some());
|
||||
list.removeAll(List.of(all.get(1), all.get(2)));
|
||||
|
||||
assertThat(list.modifyAdditions()).containsOnly(object1);
|
||||
assertThat(list.modifyRemovals()).isEmpty();
|
||||
|
||||
@@ -3,7 +3,7 @@ package io.ebean.xtest.common;
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.common.BeanMap;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.tests.model.basic.EBasic;
|
||||
import org.tests.model.basic.Product;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -14,24 +14,24 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class BeanMapTest {
|
||||
|
||||
private final EBasic object1 = new EBasic("o1");
|
||||
private final EBasic object2 = new EBasic("o2");
|
||||
private final EBasic object3 = new EBasic("o3");
|
||||
private final EBasic object4 = new EBasic("o4");
|
||||
private final EBasic object5 = new EBasic("o5");
|
||||
private final Product object1 = new Product(1);
|
||||
private final Product object2 = new Product(2);
|
||||
private final Product object3 = new Product(3);
|
||||
private final Product object4 = new Product(4);
|
||||
private final Product object5 = new Product(5);
|
||||
|
||||
private Map<String, Object> all() {
|
||||
Map<String, Object> all = new LinkedHashMap<>();
|
||||
all.put("1", object1);
|
||||
all.put("2", object2);
|
||||
all.put("3", object3);
|
||||
all.put("1", new Product(1));
|
||||
all.put("2", new Product(2));
|
||||
all.put("3", new Product(3));
|
||||
return all;
|
||||
}
|
||||
|
||||
private Map<String, Object> some() {
|
||||
Map<String, Object> all = new LinkedHashMap<>();
|
||||
all.put("2", object2);
|
||||
all.put("3", object3);
|
||||
all.put("2", new Product(2));
|
||||
all.put("3", new Product(3));
|
||||
return all;
|
||||
}
|
||||
|
||||
@@ -73,8 +73,8 @@ public class BeanMapTest {
|
||||
|
||||
@Test
|
||||
public void testAdd_given_someAlreadyIn() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>(some());
|
||||
Map<String, Object> some = new LinkedHashMap<>(Map.of("2", object2, "3", object3));
|
||||
BeanMap<String, Object> map = new BeanMap<>(some);
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
|
||||
// act
|
||||
@@ -90,11 +90,13 @@ public class BeanMapTest {
|
||||
@Test
|
||||
public void testAddSome_given_someAlreadyIn() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>(some());
|
||||
Map<String, Object> some = new LinkedHashMap<>(Map.of("2", object2, "3", object3));
|
||||
BeanMap<String, Object> map = new BeanMap<>(some);
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
|
||||
// act
|
||||
map.putAll(all());
|
||||
Map<String, Object> all = Map.of("1", object1, "2", object2, "3", object3);
|
||||
map.putAll(all);
|
||||
|
||||
assertThat(map.modifyAdditions()).containsOnly(object1);
|
||||
assertThat(map.modifyRemovals()).isEmpty();
|
||||
@@ -179,7 +181,7 @@ public class BeanMapTest {
|
||||
@Test
|
||||
public void testClear_given_someBeansInAdditions() {
|
||||
|
||||
BeanMap<String, EBasic> map = newModifyListeningMap();
|
||||
BeanMap<String, Product> map = newModifyListeningMap();
|
||||
map.put("2", object2);
|
||||
map.put("3", object3);
|
||||
|
||||
@@ -193,7 +195,7 @@ public class BeanMapTest {
|
||||
|
||||
@Test
|
||||
public void keySet_add_whenModifyListening() {
|
||||
BeanMap<String, EBasic> map = newModifyListeningMap();
|
||||
BeanMap<String, Product> map = newModifyListeningMap();
|
||||
assertThrows(UnsupportedOperationException.class, () -> map.keySet().add("3"));
|
||||
}
|
||||
|
||||
@@ -205,7 +207,7 @@ public class BeanMapTest {
|
||||
|
||||
@Test
|
||||
public void keySet_addAll_whenModifyListening() {
|
||||
BeanMap<String, EBasic> map = newModifyListeningMap();
|
||||
BeanMap<String, Product> map = newModifyListeningMap();
|
||||
assertThrows(UnsupportedOperationException.class, () -> map.keySet().addAll(asList("3", "4")));
|
||||
}
|
||||
|
||||
@@ -317,13 +319,13 @@ public class BeanMapTest {
|
||||
|
||||
@Test
|
||||
public void values_add() {
|
||||
BeanMap<String, EBasic> map = new BeanMap<>();
|
||||
BeanMap<String, Product> map = new BeanMap<>();
|
||||
assertThrows(UnsupportedOperationException.class, () -> map.values().add(object3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void values_addAll() {
|
||||
BeanMap<String, EBasic> map = new BeanMap<>();
|
||||
BeanMap<String, Product> map = new BeanMap<>();
|
||||
assertThrows(UnsupportedOperationException.class, () -> map.values().addAll(asList(object3, object5)));
|
||||
}
|
||||
|
||||
@@ -337,8 +339,8 @@ public class BeanMapTest {
|
||||
|
||||
@Test
|
||||
public void entrySet_clear() {
|
||||
final BeanMap<String, EBasic> map = newModifyListeningMap();
|
||||
final Set<Map.Entry<String, EBasic>> entries = map.entrySet();
|
||||
final BeanMap<String, Product> map = newModifyListeningMap();
|
||||
final Set<Map.Entry<String, Product>> entries = map.entrySet();
|
||||
entries.clear();
|
||||
|
||||
assertThat(entries).isEmpty();
|
||||
@@ -348,8 +350,8 @@ public class BeanMapTest {
|
||||
|
||||
@Test
|
||||
public void entrySet_remove() {
|
||||
final BeanMap<String, EBasic> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, EBasic>> entries = map.entrySet();
|
||||
final BeanMap<String, Product> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, Product>> entries = map.entrySet();
|
||||
|
||||
assertThat(map).hasSize(5);
|
||||
|
||||
@@ -365,8 +367,8 @@ public class BeanMapTest {
|
||||
|
||||
@Test
|
||||
public void entrySet_remove_whenNotEqualValue() {
|
||||
final BeanMap<String, EBasic> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, EBasic>> entries = map.entrySet();
|
||||
final BeanMap<String, Product> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, Product>> entries = map.entrySet();
|
||||
|
||||
assertThat(map).hasSize(5);
|
||||
|
||||
@@ -379,11 +381,11 @@ public class BeanMapTest {
|
||||
|
||||
@Test
|
||||
public void entrySet_iterator_remove() {
|
||||
final BeanMap<String, EBasic> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, EBasic>> entries = map.entrySet();
|
||||
final Iterator<Map.Entry<String, EBasic>> iterator = entries.iterator();
|
||||
final BeanMap<String, Product> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, Product>> entries = map.entrySet();
|
||||
final Iterator<Map.Entry<String, Product>> iterator = entries.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final Map.Entry<String, EBasic> entry = iterator.next();
|
||||
final Map.Entry<String, Product> entry = iterator.next();
|
||||
if (entry.getKey().equals("2") || entry.getKey().equals("5")) {
|
||||
iterator.remove();
|
||||
}
|
||||
@@ -395,8 +397,8 @@ public class BeanMapTest {
|
||||
|
||||
@Test
|
||||
public void entrySet_removeAll() {
|
||||
final BeanMap<String, EBasic> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, EBasic>> entries = map.entrySet();
|
||||
final BeanMap<String, Product> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, Product>> entries = map.entrySet();
|
||||
|
||||
entries.removeAll(asList(new AbstractMap.SimpleEntry<>("1", object1), new AbstractMap.SimpleEntry<>("3", object4), new AbstractMap.SimpleEntry<>("4", object4)));
|
||||
assertThat(map).hasSize(3);
|
||||
@@ -406,8 +408,8 @@ public class BeanMapTest {
|
||||
|
||||
@Test
|
||||
public void entrySet_retainAll() {
|
||||
final BeanMap<String, EBasic> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, EBasic>> entries = map.entrySet();
|
||||
final BeanMap<String, Product> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, Product>> entries = map.entrySet();
|
||||
|
||||
entries.retainAll(asList(new AbstractMap.SimpleEntry<>("1", object1), new AbstractMap.SimpleEntry<>("3", object4), new AbstractMap.SimpleEntry<>("4", object4)));
|
||||
assertThat(map).hasSize(2);
|
||||
@@ -415,15 +417,15 @@ public class BeanMapTest {
|
||||
assertThat(map.modifyRemovals()).containsOnly(object2, object3, object5);
|
||||
}
|
||||
|
||||
private BeanMap<String, EBasic> newModifyListeningMap() {
|
||||
BeanMap<String, EBasic> map = new BeanMap<>();
|
||||
private BeanMap<String, Product> newModifyListeningMap() {
|
||||
BeanMap<String, Product> map = new BeanMap<>();
|
||||
map.put("1", object1);
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
return map;
|
||||
}
|
||||
|
||||
private BeanMap<String, EBasic> newModifyListeningMap5() {
|
||||
BeanMap<String, EBasic> map = new BeanMap<>();
|
||||
private BeanMap<String, Product> newModifyListeningMap5() {
|
||||
BeanMap<String, Product> map = new BeanMap<>();
|
||||
map.put("1", object1);
|
||||
map.put("2", object2);
|
||||
map.put("3", object3);
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.ebean.xtest.common;
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.common.BeanSet;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.tests.model.basic.Product;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
@@ -12,22 +13,22 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class BeanSetTest {
|
||||
|
||||
Object object1 = new Object();
|
||||
Object object2 = new Object();
|
||||
Object object3 = new Object();
|
||||
Product object1 = new Product(1);
|
||||
Product object2 = new Product(2);
|
||||
Product object3 = new Product(3);
|
||||
|
||||
private Set<Object> all() {
|
||||
Set<Object> all = new LinkedHashSet<>();
|
||||
all.add(object1);
|
||||
all.add(object2);
|
||||
all.add(object3);
|
||||
all.add(new Product(1));
|
||||
all.add(new Product(2));
|
||||
all.add(new Product(3));
|
||||
return all;
|
||||
}
|
||||
|
||||
private Set<Object> some() {
|
||||
Set<Object> some = new LinkedHashSet<>();
|
||||
some.add(object2);
|
||||
some.add(object3);
|
||||
some.add(new Product(2));
|
||||
some.add(new Product(3));
|
||||
return some;
|
||||
}
|
||||
|
||||
@@ -99,7 +100,9 @@ public class BeanSetTest {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>();
|
||||
set.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
set.addAll(all());
|
||||
|
||||
Set<Object> all = Set.of(object1, object2, object3);
|
||||
set.addAll(all);
|
||||
assertThat(set.modifyAdditions()).containsOnly(object1, object2, object3);
|
||||
|
||||
// act
|
||||
@@ -115,11 +118,13 @@ public class BeanSetTest {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>();
|
||||
set.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
set.addAll(all());
|
||||
|
||||
Set<Object> all = Set.of(object1, object2, object3);
|
||||
set.addAll(all);
|
||||
assertThat(set.modifyAdditions()).containsOnly(object1, object2, object3);
|
||||
|
||||
// act
|
||||
set.removeAll(some());
|
||||
set.removeAll(Set.of(object2, object3));
|
||||
|
||||
assertThat(set.modifyAdditions()).containsOnly(object1);
|
||||
assertThat(set.modifyRemovals()).isEmpty();
|
||||
|
||||
@@ -578,14 +578,6 @@ public class TDSpiEbeanServer extends TDSpiServer implements SpiEbeanServer {
|
||||
public void flush() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commitTransaction() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollbackTransaction() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endTransaction() {
|
||||
}
|
||||
|
||||
@@ -222,21 +222,6 @@ public class TDSpiServer implements SpiServer {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commitTransaction() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollbackTransaction() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endTransaction() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(Object bean) {
|
||||
|
||||
@@ -453,21 +438,41 @@ public class TDSpiServer implements SpiServer {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(Object bean, InsertOptions insertOptions) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(Object bean, Transaction transaction) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(Object bean, InsertOptions insertOptions, Transaction transaction) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertAll(Collection<?> beans) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertAll(Collection<?> beans, InsertOptions options) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertAll(Collection<?> beans, Transaction transaction) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertAll(Collection<?> beans, InsertOptions options, Transaction transaction) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int execute(SqlUpdate updSql, Transaction transaction) {
|
||||
return 0;
|
||||
|
||||
-2
@@ -79,9 +79,7 @@ public class DefaultTransactionThreadLocalTest extends BaseTestCase {
|
||||
@ForPlatform({Platform.H2})
|
||||
@Test
|
||||
public void end_withoutActiveTransaction_isFine() {
|
||||
|
||||
assertNull(DB.currentTransaction());
|
||||
DB.endTransaction();
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.H2})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.tests.basic;
|
||||
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.xtest.BaseTestCase;
|
||||
import io.ebean.BeanState;
|
||||
import io.ebean.DB;
|
||||
@@ -36,13 +37,11 @@ public class TestDynamicUpdate extends BaseTestCase {
|
||||
|
||||
server.save(b2);
|
||||
|
||||
server.beginTransaction();
|
||||
try {
|
||||
try (Transaction txn = server.beginTransaction()) {
|
||||
EMain b3 = server.find(EMain.class, b.getId());
|
||||
assertEquals("ABC", b3.getEmbeddable().getDescription());
|
||||
} finally {
|
||||
server.endTransaction();
|
||||
}
|
||||
|
||||
EMain b4 = server.find(EMain.class, b.getId());
|
||||
b4.setName("bbb");
|
||||
b4.getEmbeddable().setDescription("123");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.tests.basic;
|
||||
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.xtest.BaseTestCase;
|
||||
import io.ebean.DB;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -17,8 +18,7 @@ public class TestInheritRef extends BaseTestCase {
|
||||
@Test
|
||||
public void testAssocOne() {
|
||||
|
||||
DB.beginTransaction();
|
||||
try {
|
||||
try (Transaction txn = DB.beginTransaction()) {
|
||||
DB.createUpdate(Vehicle.class, "delete from vehicle");
|
||||
|
||||
Car c = new Car();
|
||||
@@ -52,9 +52,6 @@ public class TestInheritRef extends BaseTestCase {
|
||||
|
||||
assertEquals(1, found);
|
||||
assertTrue(foundTruck.getCapacity() == 20D);
|
||||
|
||||
} finally {
|
||||
DB.rollbackTransaction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,10 +47,9 @@ public class TestPersistenceContext extends BaseTestCase {
|
||||
// implicit transaction with its own persistence context
|
||||
Order oBefore = DB.find(Order.class, 1);
|
||||
// start a persistence context
|
||||
DB.beginTransaction();
|
||||
|
||||
Order order;
|
||||
try {
|
||||
try (Transaction txn = DB.beginTransaction()) {
|
||||
order = DB.find(Order.class, 1);
|
||||
// not the same instance ...as a different persistence context
|
||||
assertNotSame(order, oBefore);
|
||||
@@ -63,9 +62,6 @@ public class TestPersistenceContext extends BaseTestCase {
|
||||
// all the same instance
|
||||
assertSame(order, o2);
|
||||
assertSame(order, o3);
|
||||
|
||||
} finally {
|
||||
DB.endTransaction();
|
||||
}
|
||||
|
||||
// implicit transaction with its own persistence context
|
||||
@@ -74,8 +70,7 @@ public class TestPersistenceContext extends BaseTestCase {
|
||||
assertNotSame(oAfter, order);
|
||||
|
||||
// start a persistence context
|
||||
DB.beginTransaction();
|
||||
try {
|
||||
try (Transaction txn = DB.beginTransaction()) {
|
||||
Order testOrder = ResetBasicData.createOrderCustAndOrder("testPC");
|
||||
Integer id = testOrder.getCustomer().getId();
|
||||
Integer orderId = testOrder.getId();
|
||||
@@ -94,9 +89,6 @@ public class TestPersistenceContext extends BaseTestCase {
|
||||
|
||||
assertEquals(customer.getId(), customer2.getId());
|
||||
assertSame(customer, customer2);
|
||||
|
||||
} finally {
|
||||
DB.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,14 +27,14 @@ public class TestQueryForUpdate extends BaseTestCase {
|
||||
try (final Transaction transaction = DB.beginTransaction()) {
|
||||
query = DB.find(Customer.class)
|
||||
.forUpdate()
|
||||
.order().desc("id");
|
||||
.orderBy().desc("id");
|
||||
|
||||
query.findList();
|
||||
}
|
||||
|
||||
if (isSqlServer()) {
|
||||
assertThat(sqlOf(query)).contains("with (updlock)");
|
||||
} else if (!isDb2()){
|
||||
} else {
|
||||
assertThat(sqlOf(query)).contains("for update");
|
||||
}
|
||||
}
|
||||
@@ -48,21 +48,21 @@ public class TestQueryForUpdate extends BaseTestCase {
|
||||
query = DB.find(Customer.class)
|
||||
.forUpdate()
|
||||
.setMaxRows(3)
|
||||
.order().desc("id");
|
||||
.orderBy().desc("id");
|
||||
|
||||
query.findList();
|
||||
}
|
||||
|
||||
if (isSqlServer()) {
|
||||
assertThat(sqlOf(query)).contains("with (updlock)");
|
||||
} else if (!isOracle() && !isDb2()) {
|
||||
} else if (!isOracle()) {
|
||||
// Oracle does not support FOR UPDATE with FETCH
|
||||
assertThat(sqlOf(query)).contains("for update");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ForPlatform({Platform.H2, Platform.ORACLE, Platform.POSTGRES, Platform.SQLSERVER, Platform.MYSQL, Platform.MARIADB})
|
||||
@ForPlatform({Platform.H2, Platform.ORACLE, Platform.POSTGRES, Platform.SQLSERVER, Platform.MYSQL, Platform.MARIADB, Platform.DB2})
|
||||
public void testForUpdate_when_alreadyInPCAsReference() {
|
||||
ResetBasicData.reset();
|
||||
Order o0 = DB.find(Order.class).orderBy("id").setMaxRows(1).findOne();
|
||||
@@ -96,7 +96,7 @@ public class TestQueryForUpdate extends BaseTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
@ForPlatform({Platform.H2, Platform.ORACLE, Platform.POSTGRES, Platform.SQLSERVER, Platform.MYSQL, Platform.MARIADB})
|
||||
@ForPlatform({Platform.H2, Platform.ORACLE, Platform.POSTGRES, Platform.SQLSERVER, Platform.MYSQL, Platform.MARIADB, Platform.DB2})
|
||||
public void testForUpdate_when_alreadyInPCAsReference_usingLock() {
|
||||
ResetBasicData.reset();
|
||||
Order o0 = DB.find(Order.class).orderBy("id").setMaxRows(1).findOne();
|
||||
@@ -131,7 +131,7 @@ public class TestQueryForUpdate extends BaseTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
@ForPlatform({Platform.H2, Platform.ORACLE, Platform.POSTGRES, Platform.SQLSERVER, Platform.MYSQL, Platform.MARIADB})
|
||||
@ForPlatform({Platform.H2, Platform.ORACLE, Platform.POSTGRES, Platform.SQLSERVER, Platform.MYSQL, Platform.MARIADB, Platform.DB2})
|
||||
public void testForUpdate_when_alreadyInPC() {
|
||||
|
||||
EBasic basic = new EBasic("initialValue");
|
||||
@@ -193,7 +193,7 @@ public class TestQueryForUpdate extends BaseTestCase {
|
||||
|
||||
Query<Customer> query = DB.find(Customer.class)
|
||||
.forUpdateNoWait()
|
||||
.order().desc("id");
|
||||
.orderBy().desc("id");
|
||||
|
||||
query.findList();
|
||||
if (isOracle()) {
|
||||
@@ -219,7 +219,7 @@ public class TestQueryForUpdate extends BaseTestCase {
|
||||
Query<Customer> query = DB.find(Customer.class)
|
||||
.forUpdateNoWait()
|
||||
.setMaxRows(1)
|
||||
.order().desc("id");
|
||||
.orderBy().desc("id");
|
||||
|
||||
List<Customer> list = query.findList();
|
||||
Customer first = list.get(0);
|
||||
|
||||
@@ -73,9 +73,26 @@ public class TestQueryUsingConnection extends BaseTestCase {
|
||||
assertThat(count).isEqualTo(otherCount + 1);
|
||||
assertThat(otherCount).isEqualTo(masterCount);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@IgnorePlatform({Platform.SQLSERVER, Platform.COCKROACH})
|
||||
@Test
|
||||
public void dtoQueryUsingConnection() {
|
||||
ResetBasicData.reset();
|
||||
|
||||
try (Transaction transaction = DB.createTransaction()) {
|
||||
final CountryDto dto = DB.findDto(CountryDto.class, "select code, name from o_country where code=?")
|
||||
.usingConnection(transaction.connection())
|
||||
.setParameter("NZ")
|
||||
.findOne();
|
||||
|
||||
assertThat(dto).isNotNull();
|
||||
assertEquals("NZ", dto.code);
|
||||
transaction.rollback();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class CountryDto {
|
||||
final String code;
|
||||
final String name;
|
||||
|
||||
+2
-5
@@ -1,5 +1,6 @@
|
||||
package org.tests.cache;
|
||||
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.xtest.BaseTestCase;
|
||||
import io.ebean.DB;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -26,8 +27,7 @@ public class TestCacheInterceptSaveWhenLazyLoaded extends BaseTestCase {
|
||||
order.setCustomer(customer);
|
||||
DB.save(order);
|
||||
|
||||
DB.beginTransaction();
|
||||
try {
|
||||
try (Transaction txn = DB.beginTransaction()) {
|
||||
|
||||
Order foundOrder = DB.find(Order.class)
|
||||
.where().eq("id", order.getId())
|
||||
@@ -47,9 +47,6 @@ public class TestCacheInterceptSaveWhenLazyLoaded extends BaseTestCase {
|
||||
|
||||
assertSame(foundOrder, order1);
|
||||
assertTrue(DB.beanState(foundOrder).isDirty());
|
||||
|
||||
} finally {
|
||||
DB.endTransaction();
|
||||
}
|
||||
|
||||
// cleanup
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.tests.genkey;
|
||||
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Transaction;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.tests.model.basic.TOne;
|
||||
|
||||
@@ -19,12 +20,10 @@ public class TestGeneratedKeys {
|
||||
c1.setName("Two");
|
||||
c1.setDescription("Test Gen Key Two");
|
||||
|
||||
DB.beginTransaction();
|
||||
try {
|
||||
try (Transaction txn = DB.beginTransaction()) {
|
||||
DB.save(c);
|
||||
DB.save(c1);
|
||||
} finally {
|
||||
DB.commitTransaction();
|
||||
txn.commit();
|
||||
}
|
||||
Integer id = c.getId();
|
||||
assertNotNull(id);
|
||||
|
||||
@@ -0,0 +1,411 @@
|
||||
package org.tests.insert;
|
||||
|
||||
import io.ebean.*;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.test.LoggedSql;
|
||||
import io.ebean.xtest.BaseTestCase;
|
||||
import io.ebean.xtest.ForPlatform;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.tests.update.EPersonOnline;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import static io.ebean.InsertOptions.ON_CONFLICT_NOTHING;
|
||||
import static io.ebean.InsertOptions.ON_CONFLICT_UPDATE;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class TestInsertOnConflict extends BaseTestCase {
|
||||
|
||||
InsertOptions onConflictDoUpdateAndGetGeneratedKeys = InsertOptions.builder()
|
||||
.onConflictUpdate()
|
||||
.getGeneratedKeys(true)
|
||||
.build();
|
||||
|
||||
@ForPlatform({Platform.POSTGRES, Platform.YUGABYTE})
|
||||
@Test
|
||||
void insertOnConflictUpdateExplicitTransaction() {
|
||||
Database db = DB.getDefault();
|
||||
db.truncate(EPersonOnline.class);
|
||||
LoggedSql.start();
|
||||
|
||||
var bean = newBean("a@b.com");
|
||||
|
||||
try (Transaction txn = DB.createTransaction()) {
|
||||
db.insert(bean, ON_CONFLICT_UPDATE, txn);
|
||||
txn.commit();
|
||||
}
|
||||
assertThat(bean.getId()).isNotNull();
|
||||
|
||||
var bean2 = newBean("a@b.com");
|
||||
bean2.setOnlineStatus(false);
|
||||
try (Transaction txn = DB.createTransaction()) {
|
||||
db.insert(bean2, ON_CONFLICT_UPDATE, txn);
|
||||
txn.commit();
|
||||
}
|
||||
assertThat(bean2.getId()).isEqualTo(bean.getId());
|
||||
|
||||
var sql = LoggedSql.stop();
|
||||
assertThat(sql).hasSize(2);
|
||||
assertThat(sql.get(0)).contains("insert into e_person_online (email, online_status, when_updated) values (?,?,?) on conflict (email) do update set online_status=excluded.online_status, when_updated=excluded.when_updated");
|
||||
assertThat(sql.get(1)).contains("insert into e_person_online (email, online_status, when_updated) values (?,?,?) on conflict (email) do update set online_status=excluded.online_status, when_updated=excluded.when_updated");
|
||||
|
||||
List<EPersonOnline> list = db.find(EPersonOnline.class).findList();
|
||||
assertThat(list).hasSize(1);
|
||||
assertThat(list.get(0).getWhenUpdated()).isEqualTo(bean2.getWhenUpdated());
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.POSTGRES, Platform.YUGABYTE})
|
||||
@Test
|
||||
void insertOnConflictUpdate_when_noIdValue() {
|
||||
Database db = DB.getDefault();
|
||||
db.truncate(EPersonOnline.class);
|
||||
LoggedSql.start();
|
||||
|
||||
var bean = newBean("a@b.com");
|
||||
db.insert(bean, onConflictDoUpdateAndGetGeneratedKeys);
|
||||
assertThat(bean.getId()).isNotNull();
|
||||
|
||||
var bean2 = newBean("a@b.com");
|
||||
bean2.setOnlineStatus(false);
|
||||
db.insert(bean2, onConflictDoUpdateAndGetGeneratedKeys);
|
||||
assertThat(bean2.getId()).isEqualTo(bean.getId());
|
||||
|
||||
var sql = LoggedSql.stop();
|
||||
assertThat(sql).hasSize(2);
|
||||
assertThat(sql.get(0)).contains("insert into e_person_online (email, online_status, when_updated) values (?,?,?) on conflict (email) do update set online_status=excluded.online_status, when_updated=excluded.when_updated");
|
||||
assertThat(sql.get(1)).contains("insert into e_person_online (email, online_status, when_updated) values (?,?,?) on conflict (email) do update set online_status=excluded.online_status, when_updated=excluded.when_updated");
|
||||
|
||||
List<EPersonOnline> list = db.find(EPersonOnline.class).findList();
|
||||
|
||||
assertThat(list).hasSize(1);
|
||||
assertThat(list.get(0).getWhenUpdated()).isEqualTo(bean2.getWhenUpdated());
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.POSTGRES, Platform.YUGABYTE})
|
||||
@Test
|
||||
void insertOnConflictUpdate_when_idValueSupplied() {
|
||||
Database db = DB.getDefault();
|
||||
db.truncate(EPersonOnline.class);
|
||||
LoggedSql.start();
|
||||
|
||||
var bean = newBean("a@b.com");
|
||||
bean.setId(40_042L);
|
||||
db.insert(bean, ON_CONFLICT_UPDATE);
|
||||
assertThat(bean.getId()).isNotNull();
|
||||
|
||||
var bean2 = newBean("a@b.com");
|
||||
bean2.setId(40_043L); // not expected but can be different
|
||||
bean2.setOnlineStatus(false);
|
||||
|
||||
db.insert(bean2, onConflictDoUpdateAndGetGeneratedKeys);
|
||||
|
||||
var sql = LoggedSql.stop();
|
||||
assertThat(sql).hasSize(2);
|
||||
assertThat(sql.get(0)).contains("insert into e_person_online (id, email, online_status, when_updated) values (?,?,?,?) on conflict (email) do update set online_status=excluded.online_status, when_updated=excluded.when_updated");
|
||||
assertThat(sql.get(1)).contains("insert into e_person_online (id, email, online_status, when_updated) values (?,?,?,?) on conflict (email) do update set online_status=excluded.online_status, when_updated=excluded.when_updated");
|
||||
|
||||
List<EPersonOnline> list = db.find(EPersonOnline.class).findList();
|
||||
|
||||
assertThat(list).hasSize(1);
|
||||
assertThat(list.get(0).getWhenUpdated()).isEqualTo(bean2.getWhenUpdated());
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.POSTGRES, Platform.YUGABYTE})
|
||||
@Test
|
||||
void insertAll_onConflictUpdate_when_noIdValue() {
|
||||
Database db = DB.getDefault();
|
||||
db.truncate(EPersonOnline.class);
|
||||
LoggedSql.start();
|
||||
|
||||
var bean = newBean("a1@b.com");
|
||||
var bean2 = newBean("a2@b.com");
|
||||
var bean3 = newBean("a3@b.com");
|
||||
db.insertAll(List.of(bean, bean2, bean3), ON_CONFLICT_UPDATE);
|
||||
|
||||
var sql = LoggedSql.stop();
|
||||
assertThat(sql).hasSize(5);
|
||||
assertThat(sql.get(0)).contains("insert into e_person_online (email, online_status, when_updated) values (?,?,?) on conflict (email) do update set online_status=excluded.online_status, when_updated=excluded.when_updated");
|
||||
assertThat(sql.get(1)).contains(" -- bind");
|
||||
assertThat(sql.get(2)).contains(" -- bind");
|
||||
assertThat(sql.get(3)).contains(" -- bind");
|
||||
assertThat(sql.get(4)).contains(" -- executeBatch()");
|
||||
|
||||
var bean4 = newBean("a1@b.com");
|
||||
var bean5 = newBean("a5@b.com");
|
||||
db.insertAll(List.of(bean4, bean5), ON_CONFLICT_UPDATE);
|
||||
|
||||
List<EPersonOnline> list = db.find(EPersonOnline.class).orderBy("id").findList();
|
||||
assertThat(list).hasSize(4);
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.POSTGRES, Platform.YUGABYTE})
|
||||
@Test
|
||||
void insertAll_onConflictUpdate_explicitTransaction() {
|
||||
Database db = DB.getDefault();
|
||||
db.truncate(EPersonOnline.class);
|
||||
LoggedSql.start();
|
||||
|
||||
try (Transaction txn = DB.createTransaction()) {
|
||||
txn.setBatchSize(3);
|
||||
var bean = newBean("a1@b.com");
|
||||
var bean2 = newBean("a2@b.com");
|
||||
var bean3 = newBean("a3@b.com");
|
||||
var bean4 = newBean("a4@b.com");
|
||||
db.insertAll(List.of(bean, bean2, bean3, bean4), ON_CONFLICT_UPDATE, txn);
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
var sql = LoggedSql.stop();
|
||||
assertThat(sql).hasSize(8);
|
||||
assertThat(sql.get(0)).contains("insert into e_person_online (email, online_status, when_updated) values (?,?,?) on conflict (email) do update set online_status=excluded.online_status, when_updated=excluded.when_updated");
|
||||
assertThat(sql.get(1)).contains(" -- bind");
|
||||
assertThat(sql.get(2)).contains(" -- bind");
|
||||
assertThat(sql.get(3)).contains(" -- bind");
|
||||
assertThat(sql.get(4)).contains(" -- executeBatch()");
|
||||
assertThat(sql.get(5)).contains("insert into e_person_online (email, online_status, when_updated) values (?,?,?) on conflict (email) do update set online_status=excluded.online_status, when_updated=excluded.when_updated");
|
||||
assertThat(sql.get(6)).contains(" -- bind");
|
||||
assertThat(sql.get(7)).contains(" -- executeBatch()");
|
||||
|
||||
List<EPersonOnline> list = db.find(EPersonOnline.class).orderBy("id").findList();
|
||||
assertThat(list).hasSize(4);
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.POSTGRES, Platform.YUGABYTE})
|
||||
@Test
|
||||
void explicitConstraint() {
|
||||
Database db = DB.getDefault();
|
||||
db.truncate(EPersonOnline.class);
|
||||
LoggedSql.start();
|
||||
|
||||
var bean = newBean("a1@b.com");
|
||||
var bean2 = newBean("a2@b.com");
|
||||
var bean3 = newBean("a3@b.com");
|
||||
|
||||
var ON_CONFLICT_ = InsertOptions.builder()
|
||||
.onConflictUpdate()
|
||||
.constraint("uq_e_person_online_email")
|
||||
.build();
|
||||
|
||||
db.insertAll(List.of(bean, bean2, bean3), ON_CONFLICT_);
|
||||
|
||||
var sql = LoggedSql.stop();
|
||||
assertThat(sql).hasSize(5);
|
||||
assertThat(sql.get(0)).contains("insert into e_person_online (email, online_status, when_updated) values (?,?,?) on conflict on constraint uq_e_person_online_email do update set online_status=excluded.online_status, when_updated=excluded.when_updated");
|
||||
assertThat(sql.get(1)).contains(" -- bind");
|
||||
assertThat(sql.get(2)).contains(" -- bind");
|
||||
assertThat(sql.get(3)).contains(" -- bind");
|
||||
assertThat(sql.get(4)).contains(" -- executeBatch()");
|
||||
|
||||
List<EPersonOnline> list = db.find(EPersonOnline.class).orderBy("id").findList();
|
||||
assertThat(list).hasSize(3);
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.POSTGRES, Platform.YUGABYTE})
|
||||
@Test
|
||||
void explicitUniqueColumns() {
|
||||
Database db = DB.getDefault();
|
||||
db.truncate(EPersonOnline.class);
|
||||
LoggedSql.start();
|
||||
|
||||
var bean = newBean("a1@b.com");
|
||||
var bean2 = newBean("a2@b.com");
|
||||
var bean3 = newBean("a3@b.com");
|
||||
|
||||
var ON_CONFLICT_ = InsertOptions.builder()
|
||||
.onConflictUpdate()
|
||||
.uniqueColumns(" email ")
|
||||
.build();
|
||||
|
||||
db.insertAll(List.of(bean, bean2, bean3), ON_CONFLICT_);
|
||||
|
||||
var sql = LoggedSql.stop();
|
||||
assertThat(sql).hasSize(5);
|
||||
assertThat(sql.get(0)).contains("insert into e_person_online (email, online_status, when_updated) values (?,?,?) on conflict ( email ) do update set online_status=excluded.online_status, when_updated=excluded.when_updated");
|
||||
assertThat(sql.get(1)).contains(" -- bind");
|
||||
assertThat(sql.get(2)).contains(" -- bind");
|
||||
assertThat(sql.get(3)).contains(" -- bind");
|
||||
assertThat(sql.get(4)).contains(" -- executeBatch()");
|
||||
|
||||
List<EPersonOnline> list = db.find(EPersonOnline.class).orderBy("id").findList();
|
||||
assertThat(list).hasSize(3);
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.POSTGRES, Platform.YUGABYTE})
|
||||
@Test
|
||||
void explicitUpdateSet() {
|
||||
Database db = DB.getDefault();
|
||||
db.truncate(EPersonOnline.class);
|
||||
LoggedSql.start();
|
||||
|
||||
var bean = newBean("a1@b.com");
|
||||
var bean2 = newBean("a2@b.com");
|
||||
|
||||
var ON_CONFLICT_ = InsertOptions.builder()
|
||||
.onConflictUpdate()
|
||||
.updateSet("when_updated=excluded.when_updated, online_status=true")
|
||||
.build();
|
||||
|
||||
db.insertAll(List.of(bean, bean2), ON_CONFLICT_);
|
||||
|
||||
var sql = LoggedSql.stop();
|
||||
assertThat(sql).hasSize(4);
|
||||
assertThat(sql.get(0)).contains("insert into e_person_online (email, online_status, when_updated) values (?,?,?) on conflict (email) do update set when_updated=excluded.when_updated, online_status=true");
|
||||
assertThat(sql.get(1)).contains(" -- bind");
|
||||
assertThat(sql.get(2)).contains(" -- bind");
|
||||
assertThat(sql.get(3)).contains(" -- executeBatch()");
|
||||
|
||||
List<EPersonOnline> list = db.find(EPersonOnline.class).orderBy("id").findList();
|
||||
assertThat(list).hasSize(2);
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.POSTGRES, Platform.YUGABYTE})
|
||||
@Test
|
||||
void insertOnConflictNothing_when_noIdValue() {
|
||||
Database db = DB.getDefault();
|
||||
db.truncate(EPersonOnline.class);
|
||||
LoggedSql.start();
|
||||
|
||||
var bean = newBean("a@b.com");
|
||||
db.insert(bean, ON_CONFLICT_NOTHING);
|
||||
assertThat(bean.getId()).isNotNull();
|
||||
|
||||
var bean2 = newBean("a@b.com");
|
||||
bean2.setOnlineStatus(false);
|
||||
db.insert(bean2, ON_CONFLICT_NOTHING);
|
||||
assertThat(bean2.getId()).isNull();
|
||||
|
||||
var sql = LoggedSql.stop();
|
||||
assertThat(sql).hasSize(2);
|
||||
assertThat(sql.get(0)).contains("insert into e_person_online (email, online_status, when_updated) values (?,?,?) on conflict (email) do nothing");
|
||||
assertThat(sql.get(1)).contains("insert into e_person_online (email, online_status, when_updated) values (?,?,?) on conflict (email) do nothing");
|
||||
|
||||
List<EPersonOnline> list = db.find(EPersonOnline.class).findList();
|
||||
|
||||
assertThat(list).hasSize(1);
|
||||
assertThat(list.get(0).getWhenUpdated()).isEqualTo(bean.getWhenUpdated());
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.POSTGRES, Platform.YUGABYTE})
|
||||
@Test
|
||||
void updateQueryReturning() throws SQLException {
|
||||
Database db = DB.getDefault();
|
||||
db.truncate(EPersonOnline.class);
|
||||
|
||||
var bean1 = newBean("a1@bee.com");
|
||||
var bean2 = newBean("a2@cee.com");
|
||||
var bean3 = newBean("a3@bee.com");
|
||||
db.saveAll(bean1, bean2, bean3);
|
||||
|
||||
String sql = "update e_person_online set email = concat('x',email) where email like ? returning id, email, online_status";
|
||||
|
||||
try (Transaction txn = db.createTransaction()) {
|
||||
Connection connection = txn.connection();
|
||||
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
|
||||
pstmt.setString(1, "%bee.com");
|
||||
try (ResultSet resultSet = pstmt.executeQuery()) {
|
||||
while (resultSet.next()) {
|
||||
long id = resultSet.getLong(1);
|
||||
String email = resultSet.getString(2);
|
||||
boolean status = resultSet.getBoolean(3);
|
||||
// do something with the id, email and status
|
||||
assertThat(id).isGreaterThan(0);
|
||||
assertThat(email).startsWith("x");
|
||||
assertThat(status).isTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
try (Transaction txn = db.beginTransaction()) {
|
||||
List<SqlRow> sqlRowList = DB.sqlQuery(sql)
|
||||
.setParameter("%bee.com")
|
||||
.findList();
|
||||
|
||||
assertThat(sqlRowList).hasSize(2);
|
||||
assertThat(sqlRowList.get(0).getString("email")).startsWith("xx");
|
||||
|
||||
txn.addModification("e_person_online", false, true, false);
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
try (Transaction txn = db.beginTransaction()) {
|
||||
List<ReturnDto> dtoList = db.findDto(ReturnDto.class, sql)
|
||||
.setParameter("%bee.com")
|
||||
.findList();
|
||||
|
||||
assertThat(dtoList).hasSize(2);
|
||||
assertThat(dtoList.get(0).email).startsWith("xxx");
|
||||
|
||||
txn.addModification("e_person_online", false, true, false);
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
try (Transaction txn = db.beginTransaction()) {
|
||||
List<ReturnDto2> dtoList2 = db.findDto(ReturnDto2.class, sql)
|
||||
.setParameter("%bee.com")
|
||||
.findList();
|
||||
|
||||
assertThat(dtoList2).hasSize(2);
|
||||
assertThat(dtoList2.get(0).email).startsWith("xxxx");
|
||||
assertThat(dtoList2.get(0).id).isGreaterThan(0);
|
||||
txn.addModification("e_person_online", false, true, false);
|
||||
txn.commit();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ReturnDto {
|
||||
|
||||
private final long id;
|
||||
private final String email;
|
||||
private final boolean onlineStatus;
|
||||
|
||||
public ReturnDto(long id, String email, boolean onlineStatus) {
|
||||
this.id = id;
|
||||
this.email = email;
|
||||
this.onlineStatus = onlineStatus;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ReturnDto2 {
|
||||
|
||||
private long id;
|
||||
private String email;
|
||||
private boolean onlineStatus;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public boolean isOnlineStatus() {
|
||||
return onlineStatus;
|
||||
}
|
||||
|
||||
public void setOnlineStatus(boolean onlineStatus) {
|
||||
this.onlineStatus = onlineStatus;
|
||||
}
|
||||
}
|
||||
|
||||
private static EPersonOnline newBean(String email) {
|
||||
EPersonOnline bean = new EPersonOnline();
|
||||
bean.setEmail(email);
|
||||
bean.setOnlineStatus(true);
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user