mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e51d9ba2ab | ||
|
|
1b1dce90ed | ||
|
|
405834fa45 | ||
|
|
7720229af9 | ||
|
|
89a294414e | ||
|
|
7bbfc00b86 | ||
|
|
d6c76de0a2 | ||
|
|
36f3986689 | ||
|
|
f0f4f13ec6 | ||
|
|
08466d42e9 | ||
|
|
1f841982a5 | ||
|
|
b34704a1fa | ||
|
|
0128d64841 | ||
|
|
68b313f778 | ||
|
|
fad32c58d8 | ||
|
|
8f1ebdb89a | ||
|
|
f7703efde2 | ||
|
|
c5ffccb649 | ||
|
|
3e65705bf9 | ||
|
|
7469a38bbc | ||
|
|
7ea4311662 | ||
|
|
f556e04f58 | ||
|
|
d9c75a60a5 | ||
|
|
225bec7b28 | ||
|
|
da44f7e604 | ||
|
|
e0eda4f8be | ||
|
|
e4e780588c | ||
|
|
7c8f235550 | ||
|
|
9a77ec1567 | ||
|
|
ff426319f5 | ||
|
|
7f56aff9dd | ||
|
|
cdbdd98d36 | ||
|
|
7bf030f59c | ||
|
|
16dca28831 | ||
|
|
678b43693d | ||
|
|
7ab93a0cdf | ||
|
|
951f942c73 | ||
|
|
cf2ec4b81d | ||
|
|
7d1745ba53 | ||
|
|
7adbdbf532 | ||
|
|
40d9c88e34 | ||
|
|
ab45ad34e0 | ||
|
|
24b514f851 | ||
|
|
582fec7ce4 | ||
|
|
0b11c541c8 | ||
|
|
540ceab96f | ||
|
|
8b858a073a | ||
|
|
02dafc9838 | ||
|
|
0816810d3b | ||
|
|
1f6e2ee844 | ||
|
|
dc00765a98 | ||
|
|
a48b2f4ebe | ||
|
|
837563544f | ||
|
|
fd199f406b | ||
|
|
a48e96c7e9 | ||
|
|
7ba6e5f67d | ||
|
|
6ce42b1ca3 | ||
|
|
89617cefbe | ||
|
|
dd377621a4 | ||
|
|
d844855462 | ||
|
|
f68c25d5f3 | ||
|
|
61cfc7a979 | ||
|
|
3c98ee7f1b | ||
|
|
0738316f15 | ||
|
|
ceb83befa3 | ||
|
|
a0b04cceda | ||
|
|
03edfb5454 | ||
|
|
62015451df | ||
|
|
ed9113efe6 | ||
|
|
334793667e | ||
|
|
351a1c4739 | ||
|
|
b2de333dcc | ||
|
|
6091f7b683 | ||
|
|
43fb84cbc0 | ||
|
|
52a4e9e19b | ||
|
|
a2cdea24ed | ||
|
|
cd780208e5 | ||
|
|
9ce0e923d7 | ||
|
|
9e461e4708 | ||
|
|
5fa09a6f90 | ||
|
|
6babb2e6f5 | ||
|
|
26abe27e42 | ||
|
|
9b18d46b78 | ||
|
|
eed487ad26 | ||
|
|
c10865dfaf | ||
|
|
2352df309c | ||
|
|
feb2bd1e15 | ||
|
|
11c9bdfc6f | ||
|
|
4a6fc98395 | ||
|
|
7322030e90 | ||
|
|
77634fc3eb | ||
|
|
ed8d4b5fc4 | ||
|
|
187cc0903d | ||
|
|
1d7a14c8f4 | ||
|
|
c58b7d3da3 | ||
|
|
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 | ||
|
|
716cfaf938 | ||
|
|
7cd9e5ee03 | ||
|
|
f9c9bea623 | ||
|
|
720832122c | ||
|
|
7b635acf56 | ||
|
|
6b7efe65d7 | ||
|
|
03cd4000f0 | ||
|
|
dfd6434b59 | ||
|
|
4e7480237b | ||
|
|
9bfcf07486 | ||
|
|
b1f1344057 | ||
|
|
07201c1519 | ||
|
|
455a9fdffc | ||
|
|
3f67425727 | ||
|
|
3fd9ae06db | ||
|
|
a8ce726e47 | ||
|
|
29cd1a143d | ||
|
|
6a19c6a0ce | ||
|
|
eaec515cc1 | ||
|
|
97709d3493 | ||
|
|
87ad874621 | ||
|
|
dfe95f6fc0 | ||
|
|
05feccfeb6 | ||
|
|
196cb09c66 | ||
|
|
589e198301 | ||
|
|
b2b81677e8 | ||
|
|
f032aad22e | ||
|
|
c48e5428c5 | ||
|
|
cbca940611 | ||
|
|
0da3772ae9 | ||
|
|
496ef36b11 | ||
|
|
a4a2aba56f | ||
|
|
803f1d8642 | ||
|
|
ff1c73e20d | ||
|
|
7afd37cd98 | ||
|
|
24bb364d40 | ||
|
|
5d54a238bd | ||
|
|
b50ce5fc3f | ||
|
|
624e92840c | ||
|
|
b03adc412c | ||
|
|
e794f5e916 | ||
|
|
a2551ce718 | ||
|
|
5b0a3607f6 | ||
|
|
bcf7bd17be | ||
|
|
102d8d5979 | ||
|
|
3edc232003 | ||
|
|
043dc5c51f | ||
|
|
e2d666df35 | ||
|
|
314e0a14b8 | ||
|
|
1f9cf1e4b7 | ||
|
|
12029ed06e | ||
|
|
89741b9312 | ||
|
|
ae962c2e08 | ||
|
|
4e3501972a | ||
|
|
a65ba41850 | ||
|
|
3b11c1cb6b | ||
|
|
41185eeb5c | ||
|
|
e97ff54ab2 | ||
|
|
97fae09c52 | ||
|
|
8b0f58b3c2 | ||
|
|
70eb557929 | ||
|
|
fdb3a3759b | ||
|
|
7a5e8d0e17 | ||
|
|
a0748f8139 | ||
|
|
9f65673f54 | ||
|
|
8f6a3c59d1 | ||
|
|
05210ec411 | ||
|
|
faffda8318 | ||
|
|
af3901ce01 | ||
|
|
acd538207f | ||
|
|
84f0ef9fce | ||
|
|
7ab447b21c | ||
|
|
6f8805a6b3 | ||
|
|
0171c1afef | ||
|
|
31c106f604 | ||
|
|
20d2838be4 | ||
|
|
4238a951ca | ||
|
|
b5d4bed615 | ||
|
|
3ef715ef64 | ||
|
|
aea39528ab | ||
|
|
dd498409e0 | ||
|
|
bae33101df | ||
|
|
e1972ac544 | ||
|
|
c7241ba3dc | ||
|
|
73416ed65a | ||
|
|
cd70c178f1 | ||
|
|
aa298235f3 | ||
|
|
8733fed14b | ||
|
|
169d170247 | ||
|
|
d0ee42e0de | ||
|
|
91ecc074a7 | ||
|
|
c2b381af1e | ||
|
|
eeb0a15617 | ||
|
|
6abed0dd73 | ||
|
|
1318cd706f | ||
|
|
1e8c609dec | ||
|
|
4506596379 |
@@ -1,7 +1,10 @@
|
|||||||
|
|
||||||
name: Build
|
name: Build
|
||||||
|
|
||||||
on: [push, pull_request]
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches: master
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ jobs:
|
|||||||
path:
|
path:
|
||||||
~/.m2
|
~/.m2
|
||||||
key: build-${{ env.cache-name }}
|
key: build-${{ env.cache-name }}
|
||||||
|
- name: Maven version
|
||||||
|
run: mvn --version
|
||||||
- name: Build with Maven
|
- name: Build with Maven
|
||||||
run: mvn package
|
run: mvn package
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-clickhouse</artifactId>
|
<artifactId>ebean-platform-clickhouse</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-postgres</artifactId>
|
<artifactId>ebean-platform-postgres</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-db2</artifactId>
|
<artifactId>ebean-platform-db2</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-h2</artifactId>
|
<artifactId>ebean-platform-h2</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-hana</artifactId>
|
<artifactId>ebean-platform-hana</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-mariadb</artifactId>
|
<artifactId>ebean-platform-mariadb</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-mysql</artifactId>
|
<artifactId>ebean-platform-mysql</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-nuodb</artifactId>
|
<artifactId>ebean-platform-nuodb</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-oracle</artifactId>
|
<artifactId>ebean-platform-oracle</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<postgis.jdbc.version>2.5.1</postgis.jdbc.version>
|
<postgis.jdbc.version>2.5.1</postgis.jdbc.version>
|
||||||
<postgres.jdbc.version>42.6.0</postgres.jdbc.version>
|
<postgres.jdbc.version>42.7.2</postgres.jdbc.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -22,13 +22,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -47,13 +47,19 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-postgres</artifactId>
|
<artifactId>ebean-platform-postgres</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.ebean</groupId>
|
||||||
|
<artifactId>ebean-postgis-types</artifactId>
|
||||||
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-postgres</artifactId>
|
<artifactId>ebean-platform-postgres</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-sqlite</artifactId>
|
<artifactId>ebean-platform-sqlite</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-postgres</artifactId>
|
<artifactId>ebean-platform-postgres</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -17,31 +17,31 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-joda-time</artifactId>
|
<artifactId>ebean-joda-time</artifactId>
|
||||||
<version>13.18.0</version>
|
<version>14.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-jackson-jsonnode</artifactId>
|
<artifactId>ebean-jackson-jsonnode</artifactId>
|
||||||
<version>13.18.0</version>
|
<version>14.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-jackson-mapper</artifactId>
|
<artifactId>ebean-jackson-mapper</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -60,13 +60,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-all</artifactId>
|
<artifactId>ebean-platform-all</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>composites</artifactId>
|
<artifactId>composites</artifactId>
|
||||||
|
|||||||
+2
-9
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<name>ebean api</name>
|
<name>ebean api</name>
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.avaje</groupId>
|
<groupId>io.avaje</groupId>
|
||||||
<artifactId>avaje-config</artifactId>
|
<artifactId>avaje-config</artifactId>
|
||||||
<version>3.8</version>
|
<version>3.12</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -107,13 +107,6 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<!-- JAKARTA-DEPENDENCY-END -->
|
<!-- JAKARTA-DEPENDENCY-END -->
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.avaje</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>1.1</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -266,55 +266,6 @@ public final class DB {
|
|||||||
getDefault().register(transactionCallback);
|
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.
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ package io.ebean;
|
|||||||
import jakarta.persistence.PersistenceException;
|
import jakarta.persistence.PersistenceException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown when a foreign key constraint is enforced.
|
* Thrown when a foreign key constraint is enforced or a field is too large.
|
||||||
*/
|
*/
|
||||||
public class DataIntegrityException extends PersistenceException {
|
public class DataIntegrityException extends PersistenceException {
|
||||||
private static final long serialVersionUID = -6740171949170180970L;
|
private static final long serialVersionUID = -6740171949170180970L;
|
||||||
@@ -14,4 +14,11 @@ public class DataIntegrityException extends PersistenceException {
|
|||||||
public DataIntegrityException(String message, Throwable cause) {
|
public DataIntegrityException(String message, Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create with message only.
|
||||||
|
*/
|
||||||
|
public DataIntegrityException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ import java.util.concurrent.Callable;
|
|||||||
* <h5>Constructing a Database</h5>
|
* <h5>Constructing a Database</h5>
|
||||||
* <p>
|
* <p>
|
||||||
* Databases are constructed by the DatabaseFactory. They can be created
|
* Databases are constructed by the DatabaseFactory. They can be created
|
||||||
* programmatically via {@link DatabaseFactory#create(DatabaseConfig)} or they
|
* programmatically via {@link DatabaseFactory#create(DatabaseBuilder)} or they
|
||||||
* can be automatically constructed on demand using configuration information in
|
* can be automatically constructed on demand using configuration information in
|
||||||
* the application.properties file.
|
* the application.properties file.
|
||||||
*
|
*
|
||||||
@@ -86,6 +86,23 @@ import java.util.concurrent.Callable;
|
|||||||
@NonNullApi
|
@NonNullApi
|
||||||
public interface Database {
|
public interface Database {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a new database builder.
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* // build the 'default' database using configuration
|
||||||
|
* // from application.properties / application.yaml
|
||||||
|
*
|
||||||
|
* Database db = Database.builder()
|
||||||
|
* .loadFromProperties()
|
||||||
|
* .build();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*/
|
||||||
|
static DatabaseBuilder builder() {
|
||||||
|
return new DatabaseConfig();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shutdown the Database instance.
|
* Shutdown the Database instance.
|
||||||
*/
|
*/
|
||||||
@@ -649,49 +666,6 @@ public interface Database {
|
|||||||
*/
|
*/
|
||||||
void flush();
|
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.
|
* Refresh the values of a bean.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -1210,22 +1184,53 @@ public interface Database {
|
|||||||
*/
|
*/
|
||||||
void insert(Object bean);
|
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.
|
* Insert the bean with a transaction.
|
||||||
*/
|
*/
|
||||||
void insert(Object bean, Transaction 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 a collection of beans. If there is no current transaction one is created and used to
|
||||||
* insert all the beans in the collection.
|
* insert all the beans in the collection.
|
||||||
*/
|
*/
|
||||||
void insertAll(Collection<?> beans);
|
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.
|
* Insert a collection of beans with an explicit transaction.
|
||||||
*/
|
*/
|
||||||
void insertAll(Collection<?> beans, Transaction 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.
|
* Execute explicitly passing a transaction.
|
||||||
*/
|
*/
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,11 @@
|
|||||||
package io.ebean;
|
package io.ebean;
|
||||||
|
|
||||||
import io.ebean.config.ContainerConfig;
|
import io.ebean.config.ContainerConfig;
|
||||||
import io.ebean.config.DatabaseConfig;
|
|
||||||
import io.ebean.service.SpiContainer;
|
import io.ebean.service.SpiContainer;
|
||||||
import io.ebean.service.SpiContainerFactory;
|
import io.ebean.service.SpiContainerFactory;
|
||||||
|
|
||||||
import jakarta.persistence.PersistenceException;
|
import jakarta.persistence.PersistenceException;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
@@ -76,9 +74,10 @@ public final class DatabaseFactory {
|
|||||||
*
|
*
|
||||||
* }</pre>
|
* }</pre>
|
||||||
*/
|
*/
|
||||||
public static Database create(DatabaseConfig config) {
|
public static Database create(DatabaseBuilder builder) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
|
var config = builder.settings();
|
||||||
if (config.getName() == null) {
|
if (config.getName() == null) {
|
||||||
throw new PersistenceException("The name is null (it is required)");
|
throw new PersistenceException("The name is null (it is required)");
|
||||||
}
|
}
|
||||||
@@ -102,7 +101,7 @@ public final class DatabaseFactory {
|
|||||||
/**
|
/**
|
||||||
* Create using the DatabaseConfig additionally specifying a classLoader to use as the context class loader.
|
* Create using the DatabaseConfig additionally specifying a classLoader to use as the context class loader.
|
||||||
*/
|
*/
|
||||||
public static Database createWithContextClassLoader(DatabaseConfig config, ClassLoader classLoader) {
|
public static Database createWithContextClassLoader(DatabaseBuilder config, ClassLoader classLoader) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
ClassLoader currentContextLoader = Thread.currentThread().getContextClassLoader();
|
ClassLoader currentContextLoader = Thread.currentThread().getContextClassLoader();
|
||||||
@@ -132,7 +131,7 @@ public final class DatabaseFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Database createInternal(DatabaseConfig config) {
|
private static Database createInternal(DatabaseBuilder.Settings config) {
|
||||||
return container(config.getContainerConfig()).createServer(config);
|
return container(config.getContainerConfig()).createServer(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,12 +145,9 @@ public final class DatabaseFactory {
|
|||||||
if (container != null) {
|
if (container != null) {
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (containerConfig == null) {
|
if (containerConfig == null) {
|
||||||
// effectively load configuration from ebean.properties
|
// effectively load configuration from ebean.properties
|
||||||
Properties properties = DbPrimary.getProperties();
|
|
||||||
containerConfig = new ContainerConfig();
|
containerConfig = new ContainerConfig();
|
||||||
containerConfig.loadFromProperties(properties);
|
|
||||||
}
|
}
|
||||||
container = createContainer(containerConfig);
|
container = createContainer(containerConfig);
|
||||||
return container;
|
return container;
|
||||||
@@ -160,7 +156,7 @@ public final class DatabaseFactory {
|
|||||||
/**
|
/**
|
||||||
* Create the container instance using the configuration.
|
* Create the container instance using the configuration.
|
||||||
*/
|
*/
|
||||||
protected static SpiContainer createContainer(ContainerConfig containerConfig) {
|
private static SpiContainer createContainer(ContainerConfig containerConfig) {
|
||||||
Iterator<SpiContainerFactory> factories = ServiceLoader.load(SpiContainerFactory.class).iterator();
|
Iterator<SpiContainerFactory> factories = ServiceLoader.load(SpiContainerFactory.class).iterator();
|
||||||
if (factories.hasNext()) {
|
if (factories.hasNext()) {
|
||||||
return factories.next().create(containerConfig);
|
return factories.next().create(containerConfig);
|
||||||
|
|||||||
@@ -44,25 +44,12 @@ final class DbPrimary {
|
|||||||
* Return the default database name.
|
* Return the default database name.
|
||||||
*/
|
*/
|
||||||
static String getDefaultServerName() {
|
static String getDefaultServerName() {
|
||||||
lock.lock();
|
|
||||||
try {
|
|
||||||
getProperties();
|
|
||||||
return defaultServerName;
|
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the default configuration Properties.
|
|
||||||
*/
|
|
||||||
static Properties getProperties() {
|
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
if (defaultServerName == null) {
|
if (defaultServerName == null) {
|
||||||
defaultServerName = determineDefaultServerName();
|
defaultServerName = determineDefaultServerName();
|
||||||
}
|
}
|
||||||
return Config.asProperties();
|
return defaultServerName;
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package io.ebean;
|
|||||||
import io.avaje.lang.NonNullApi;
|
import io.avaje.lang.NonNullApi;
|
||||||
import io.avaje.lang.Nullable;
|
import io.avaje.lang.Nullable;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -206,14 +208,19 @@ public interface DtoQuery<T> extends CancelableQuery {
|
|||||||
*/
|
*/
|
||||||
DtoQuery<T> usingTransaction(Transaction transaction);
|
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
|
* 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).
|
* being used (that is using a read replica database potentially with replication lag).
|
||||||
* <p>
|
* <p>
|
||||||
* When the database is configured with a read-only DataSource via
|
* 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
|
* 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.
|
* against the master data source.
|
||||||
*/
|
*/
|
||||||
DtoQuery<T> usingMaster();
|
DtoQuery<T> usingMaster();
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public interface ExpressionList<T> {
|
|||||||
Query<T> orderById(boolean orderById);
|
Query<T> orderById(boolean orderById);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecated migrate to {@link #orderBy(String)}
|
* @deprecated migrate to {@link #orderBy(String)}
|
||||||
*/
|
*/
|
||||||
@Deprecated(since = "13.19", forRemoval = true)
|
@Deprecated(since = "13.19", forRemoval = true)
|
||||||
default ExpressionList<T> order(String orderByClause) {
|
default ExpressionList<T> order(String orderByClause) {
|
||||||
@@ -72,7 +72,7 @@ public interface ExpressionList<T> {
|
|||||||
ExpressionList<T> orderBy(String orderBy);
|
ExpressionList<T> orderBy(String orderBy);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecated migrate to orderBy().
|
* @deprecated migrate to {@link #orderBy()}.
|
||||||
*/
|
*/
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
default OrderBy<T> order() {
|
default OrderBy<T> order() {
|
||||||
@@ -222,6 +222,8 @@ public interface ExpressionList<T> {
|
|||||||
int delete();
|
int delete();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @deprecated migrate to {@link #usingTransaction(Transaction)} then delete().
|
||||||
|
* <p>
|
||||||
* Execute as a delete query deleting the 'root level' beans that match the predicates
|
* Execute as a delete query deleting the 'root level' beans that match the predicates
|
||||||
* in the query.
|
* in the query.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -231,6 +233,7 @@ public interface ExpressionList<T> {
|
|||||||
*
|
*
|
||||||
* @return the number of rows that were deleted.
|
* @return the number of rows that were deleted.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "13.1.0")
|
||||||
int delete(Transaction transaction);
|
int delete(Transaction transaction);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -242,11 +245,14 @@ public interface ExpressionList<T> {
|
|||||||
int update();
|
int update();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @deprecated migrate to {@link #usingTransaction(Transaction)} then update().
|
||||||
|
* <p>
|
||||||
* Execute as a update query with the given transaction.
|
* Execute as a update query with the given transaction.
|
||||||
*
|
*
|
||||||
* @return the number of rows that were updated.
|
* @return the number of rows that were updated.
|
||||||
* @see UpdateQuery
|
* @see UpdateQuery
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "13.1.0")
|
||||||
int update(Transaction transaction);
|
int update(Transaction transaction);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -508,7 +514,7 @@ public interface ExpressionList<T> {
|
|||||||
ExpressionList<T> filterMany(String manyProperty);
|
ExpressionList<T> filterMany(String manyProperty);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecated for removal - migrate to filterManyRaw()
|
* @deprecated for removal - migrate to {@link #filterManyRaw(String, String, Object...)}.
|
||||||
* <p>
|
* <p>
|
||||||
* Add filter expressions to the many property.
|
* Add filter expressions to the many property.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,975 @@
|
|||||||
|
package io.ebean;
|
||||||
|
|
||||||
|
import io.avaje.lang.Nullable;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build and execute an ORM query.
|
||||||
|
*
|
||||||
|
* @param <SELF> The type of the builder
|
||||||
|
* @param <T> The entity bean type
|
||||||
|
*/
|
||||||
|
public interface QueryBuilder<SELF, T> extends QueryBuilderProjection<SELF, T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set root table alias.
|
||||||
|
*/
|
||||||
|
SELF alias(String alias);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply changes to the query conditional on the supplied predicate.
|
||||||
|
* <p>
|
||||||
|
* Typically, the changes are extra predicates etc.
|
||||||
|
*
|
||||||
|
* @param predicate The predicate which when true the changes are applied
|
||||||
|
* @param apply The changes to apply to the query
|
||||||
|
*/
|
||||||
|
SELF alsoIf(BooleanSupplier predicate, Consumer<SELF> apply);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an 'As of' query using history tables to return the object graph
|
||||||
|
* as of a time in the past.
|
||||||
|
* <p>
|
||||||
|
* To perform this query the DB must have underlying history tables.
|
||||||
|
*
|
||||||
|
* @param asOf the date time in the past at which you want to view the data
|
||||||
|
*/
|
||||||
|
SELF asOf(Timestamp asOf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query against the draft set of tables.
|
||||||
|
*/
|
||||||
|
SELF asDraft();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the query to a DTO bean query.
|
||||||
|
* <p>
|
||||||
|
* We effectively use the underlying ORM query to build the SQL and then execute
|
||||||
|
* and map it into DTO beans.
|
||||||
|
*/
|
||||||
|
<D> DtoQuery<D> asDto(Class<D> dtoClass);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the query to a UpdateQuery.
|
||||||
|
* <p>
|
||||||
|
* Typically this is used with query beans to covert a query bean
|
||||||
|
* query into an UpdateQuery like the examples below.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* int rowsUpdated = new QCustomer()
|
||||||
|
* .name.startsWith("Rob")
|
||||||
|
* .asUpdate()
|
||||||
|
* .set("active", false)
|
||||||
|
* .update();;
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* int rowsUpdated = new QContact()
|
||||||
|
* .notes.note.startsWith("Make Inactive")
|
||||||
|
* .email.endsWith("@foo.com")
|
||||||
|
* .customer.id.equalTo(42)
|
||||||
|
* .asUpdate()
|
||||||
|
* .set("inactive", true)
|
||||||
|
* .setRaw("email = lower(email)")
|
||||||
|
* .update();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*/
|
||||||
|
UpdateQuery<T> asUpdate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a copy of the query.
|
||||||
|
* <p>
|
||||||
|
* This is so that you can use a Query as a "prototype" for creating other
|
||||||
|
* query instances. You could create a Query with various where expressions
|
||||||
|
* and use that as a "prototype" - using this copy() method to create a new
|
||||||
|
* instance that you can then add other expressions then execute.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
SELF copy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query using the given transaction.
|
||||||
|
*/
|
||||||
|
SELF usingTransaction(Transaction transaction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query using the given connection.
|
||||||
|
*/
|
||||||
|
SELF usingConnection(Connection connection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query using the given database.
|
||||||
|
*/
|
||||||
|
SELF usingDatabase(Database database);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that the master DataSource is used if there is a read only data source
|
||||||
|
* being used (that is using a read replica database potentially with replication lag).
|
||||||
|
* <p>
|
||||||
|
* When the database is configured with a read-only DataSource via
|
||||||
|
* say {@link io.ebean.config.DatabaseConfig#setReadOnlyDataSource(DataSource)} then
|
||||||
|
* by default when a query is run without an active transaction, it uses the read-only data
|
||||||
|
* source. We we use {@code usingMaster()} to instead ensure that the query is executed
|
||||||
|
* against the master data source.
|
||||||
|
*/
|
||||||
|
SELF usingMaster();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the base table to use for this query.
|
||||||
|
* <p>
|
||||||
|
* Typically this is used when a table has partitioning and we wish to specify a specific
|
||||||
|
* partition/table to query against.
|
||||||
|
* </p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* QOrder()
|
||||||
|
* .setBaseTable("order_2019_05")
|
||||||
|
* .status.equalTo(Status.NEW)
|
||||||
|
* .findList();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*/
|
||||||
|
SELF setBaseTable(String baseTable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the PersistenceContextScope to use for this query.
|
||||||
|
* <p>
|
||||||
|
* When this is not set the 'default' configured on {@link io.ebean.config.DatabaseConfig#setPersistenceContextScope(PersistenceContextScope)}
|
||||||
|
* is used - this value defaults to {@link PersistenceContextScope#TRANSACTION}.
|
||||||
|
* <p>
|
||||||
|
* Note that the same persistence Context is used for subsequent lazy loading and query join queries.
|
||||||
|
* <p>
|
||||||
|
* Note that #findEach uses a 'per object graph' PersistenceContext so this scope is ignored for
|
||||||
|
* queries executed as #findIterate, #findEach, #findEachWhile.
|
||||||
|
*
|
||||||
|
* @param scope The scope to use for this query and subsequent lazy loading.
|
||||||
|
*/
|
||||||
|
SELF setPersistenceContextScope(PersistenceContextScope scope);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Explicitly specify whether to use AutoTune for this query.
|
||||||
|
* <p>
|
||||||
|
* If you do not call this method on a query the "Implicit AutoTune mode" is
|
||||||
|
* used to determine if AutoTune should be used for a given query.
|
||||||
|
* <p>
|
||||||
|
* AutoTune can add additional fetch paths to the query and specify which
|
||||||
|
* properties are included for each path. If you have explicitly defined some
|
||||||
|
* fetch paths AutoTune will not remove them.
|
||||||
|
*/
|
||||||
|
SELF setAutoTune(boolean autoTune);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query allowing properties with invalid JSON to be collected and not fail the query.
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* // fetch a bean with JSON content
|
||||||
|
* EBasicJsonList bean= DB.find(EBasicJsonList.class)
|
||||||
|
* .setId(42)
|
||||||
|
* .setAllowLoadErrors() // collect errors into bean state if we have invalid JSON
|
||||||
|
* .findOne();
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* // get the invalid JSON errors from the bean state
|
||||||
|
* Map<String, Exception> errors = server().getBeanState(bean).getLoadErrors();
|
||||||
|
*
|
||||||
|
* // If this map is not empty tell we have invalid JSON
|
||||||
|
* // and should try and fix the JSON content or inform the user
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*/
|
||||||
|
SELF setAllowLoadErrors();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the default lazy loading batch size to use.
|
||||||
|
* <p>
|
||||||
|
* When lazy loading is invoked on beans loaded by this query then this sets the
|
||||||
|
* batch size used to load those beans.
|
||||||
|
*
|
||||||
|
* @param lazyLoadBatchSize the number of beans to lazy load in a single batch
|
||||||
|
*/
|
||||||
|
SELF setLazyLoadBatchSize(int lazyLoadBatchSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a label on the query.
|
||||||
|
* <p>
|
||||||
|
* This label can be used to help identify query performance metrics but we can also use
|
||||||
|
* profile location enhancement on Finders so for some that would be a better option.
|
||||||
|
*/
|
||||||
|
SELF setLabel(String label);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a SQL query hint.
|
||||||
|
* <p>
|
||||||
|
* This results in an inline comment that immediately follows
|
||||||
|
* after the select keyword in the form: {@code /*+ hint *\/ }
|
||||||
|
*/
|
||||||
|
SELF setHint(String hint);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the index(es) to search for a document store which uses partitions.
|
||||||
|
* <p>
|
||||||
|
* For example, when executing a query against ElasticSearch with daily indexes we can
|
||||||
|
* explicitly specify the indexes to search against.
|
||||||
|
* </p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* // explicitly specify the indexes to search
|
||||||
|
* query.setDocIndexName("logstash-2016.11.5,logstash-2016.11.6")
|
||||||
|
*
|
||||||
|
* // search today's index
|
||||||
|
* query.setDocIndexName("$today")
|
||||||
|
*
|
||||||
|
* // search the last 3 days
|
||||||
|
* query.setDocIndexName("$last-3")
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
* <p>
|
||||||
|
* If the indexName is specified with ${daily} e.g. "logstash-${daily}" ... then we can use
|
||||||
|
* $today and $last-x as the search docIndexName like the examples below.
|
||||||
|
* </p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* // search today's index
|
||||||
|
* query.setDocIndexName("$today")
|
||||||
|
*
|
||||||
|
* // search the last 3 days
|
||||||
|
* query.setDocIndexName("$last-3")
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @param indexName The index or indexes to search against
|
||||||
|
* @return This query
|
||||||
|
*/
|
||||||
|
SELF setDocIndexName(String indexName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query including soft deleted rows.
|
||||||
|
* <p>
|
||||||
|
* This means that Ebean will not add any predicates to the query for filtering out
|
||||||
|
* soft deleted rows. You can still add your own predicates for the deleted properties
|
||||||
|
* and effectively you have full control over the query to include or exclude soft deleted
|
||||||
|
* rows as needed for a given use case.
|
||||||
|
*/
|
||||||
|
SELF setIncludeSoftDeletes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable read auditing for this query.
|
||||||
|
* <p>
|
||||||
|
* This is intended to be used when the query is not a user initiated query and instead
|
||||||
|
* part of the internal processing in an application to load a cache or document store etc.
|
||||||
|
* In these cases we don't want the query to be part of read auditing.
|
||||||
|
*/
|
||||||
|
SELF setDisableReadAuditing();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set true if you want to disable lazy loading.
|
||||||
|
* <p>
|
||||||
|
* That is, once the object graph is returned further lazy loading is disabled.
|
||||||
|
*/
|
||||||
|
SELF setDisableLazyLoading(boolean disableLazyLoading);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether this query uses DISTINCT.
|
||||||
|
*/
|
||||||
|
SELF setDistinct(boolean distinct);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restrict the query to only return subtypes of the given inherit type.
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* List<Animal> animals =
|
||||||
|
* new QAnimal()
|
||||||
|
* .name.startsWith("Fluffy")
|
||||||
|
* .setInheritType(Cat.class)
|
||||||
|
* .findList();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*/
|
||||||
|
SELF setInheritType(Class<? extends T> type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the first row to return for this query.
|
||||||
|
*
|
||||||
|
* @param firstRow the first row to include in the query result.
|
||||||
|
*/
|
||||||
|
SELF setFirstRow(int firstRow);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the maximum number of rows to return in the query.
|
||||||
|
*
|
||||||
|
* @param maxRows the maximum number of rows to return in the query.
|
||||||
|
*/
|
||||||
|
SELF setMaxRows(int maxRows);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set RawSql to use for this query.
|
||||||
|
*/
|
||||||
|
SELF setRawSql(RawSql rawSql);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extended version for setDistinct in conjunction with "findSingleAttributeList";
|
||||||
|
*
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* List<CountedValue<Order.Status>> orderStatusCount =
|
||||||
|
*
|
||||||
|
* DB.find(Order.class)
|
||||||
|
* .select("status")
|
||||||
|
* .where()
|
||||||
|
* .gt("orderDate", LocalDate.now().minusMonths(3))
|
||||||
|
*
|
||||||
|
* // fetch as single attribute with a COUNT
|
||||||
|
* .setCountDistinct(CountDistinctOrder.COUNT_DESC_ATTR_ASC)
|
||||||
|
* .findSingleAttributeList();
|
||||||
|
*
|
||||||
|
* for (CountedValue<Order.Status> entry : orderStatusCount) {
|
||||||
|
* System.out.println(" count:" + entry.getCount()+" orderStatus:" + entry.getValue() );
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // produces
|
||||||
|
*
|
||||||
|
* count:3 orderStatus:NEW
|
||||||
|
* count:1 orderStatus:SHIPPED
|
||||||
|
* count:1 orderStatus:COMPLETE
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*/
|
||||||
|
SELF setCountDistinct(CountDistinctOrder orderBy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the property to use as keys for a map.
|
||||||
|
* <p>
|
||||||
|
* If no property is set then the id property is used.
|
||||||
|
* </p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* // Assuming sku is unique for products...
|
||||||
|
*
|
||||||
|
* Map<String,Product> productMap = DB.find(Product.class)
|
||||||
|
* .setMapKey("sku") // sku map keys...
|
||||||
|
* .findMap();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @param mapKey the property to use as keys for a map.
|
||||||
|
*/
|
||||||
|
SELF setMapKey(String mapKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to true if this query should execute against the doc store.
|
||||||
|
* <p>
|
||||||
|
* When setting this you may also consider disabling lazy loading.
|
||||||
|
*/
|
||||||
|
SELF setUseDocStore(boolean useDocStore);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When set to true when you want the returned beans to be read only.
|
||||||
|
*/
|
||||||
|
SELF setReadOnly(boolean readOnly);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a timeout on this query.
|
||||||
|
* <p>
|
||||||
|
* This will typically result in a call to setQueryTimeout() on a
|
||||||
|
* preparedStatement. If the timeout occurs an exception will be thrown - this
|
||||||
|
* will be a SQLException wrapped up in a PersistenceException.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param secs the query timeout limit in seconds. Zero means there is no limit.
|
||||||
|
*/
|
||||||
|
SELF setTimeout(int secs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A hint which for JDBC translates to the Statement.fetchSize().
|
||||||
|
* <p>
|
||||||
|
* Gives the JDBC driver a hint as to the number of rows that should be
|
||||||
|
* fetched from the database when more rows are needed for ResultSet.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Note that internally findEach and findEachWhile will set the fetch size
|
||||||
|
* if it has not already as these queries expect to process a lot of rows.
|
||||||
|
* If we didn't then Postgres and MySql for example would eagerly pull back
|
||||||
|
* all the row data and potentially consume a lot of memory in the process.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* As findEach and findEachWhile automatically set the fetch size we don't have
|
||||||
|
* to do so generally but we might still wish to for tuning a specific use case.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
SELF setBufferFetchSizeHint(int fetchSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the mode to use the bean cache when executing this query.
|
||||||
|
* <p>
|
||||||
|
* By default, "find by id" and "find by natural key" will use the bean cache
|
||||||
|
* when bean caching is enabled. Setting this to false means that the query
|
||||||
|
* will not use the bean cache and instead hit the database.
|
||||||
|
* <p>
|
||||||
|
* By default, findList() with natural keys will not use the bean cache. In that
|
||||||
|
* case we need to explicitly use the bean cache.
|
||||||
|
*/
|
||||||
|
SELF setBeanCacheMode(CacheMode beanCacheMode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the {@link CacheMode} to use the query for executing this query.
|
||||||
|
*/
|
||||||
|
SELF setUseQueryCache(CacheMode cacheMode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this to false to not use the bean cache.
|
||||||
|
* <p>
|
||||||
|
* This method is now superseded by {@link #setBeanCacheMode(CacheMode)}
|
||||||
|
* which provides more explicit options controlled bean cache use.
|
||||||
|
* <p>
|
||||||
|
* This method is likely to be deprecated in the future with migration
|
||||||
|
* over to setUseBeanCache().
|
||||||
|
*/
|
||||||
|
default SELF setUseCache(boolean useCache) {
|
||||||
|
return setBeanCacheMode(useCache ? CacheMode.ON : CacheMode.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@link #setUseQueryCache(CacheMode)} with <code>ON</code> or <code>OFF</code>.
|
||||||
|
*/
|
||||||
|
default SELF setUseQueryCache(boolean enabled) {
|
||||||
|
return setUseQueryCache(enabled ? CacheMode.ON : CacheMode.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the order by clause replacing the existing order by clause if there is
|
||||||
|
* one.
|
||||||
|
* <p>
|
||||||
|
* This follows SQL syntax using commas between each property with the
|
||||||
|
* optional asc and desc keywords representing ascending and descending order
|
||||||
|
* respectively.
|
||||||
|
*/
|
||||||
|
SELF orderBy(String orderByClause);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an OrderBy object to replace any existing OrderBy clause.
|
||||||
|
*/
|
||||||
|
SELF setOrderBy(OrderBy<T> orderBy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls, if paginated queries should always append an 'order by id' statement at the end to
|
||||||
|
* guarantee a deterministic sort result. This may affect performance.
|
||||||
|
* If this is not enabled, and an orderBy is set on the query, it's up to the programmer that
|
||||||
|
* this query provides a deterministic result.
|
||||||
|
*/
|
||||||
|
SELF orderById(boolean orderById);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query with the given lock type and WAIT.
|
||||||
|
* <p>
|
||||||
|
* Note that <code>forUpdate()</code> is the same as
|
||||||
|
* <code>withLock(LockType.UPDATE)</code>.
|
||||||
|
* <p>
|
||||||
|
* Provides us with the ability to explicitly use Postgres
|
||||||
|
* SHARE, KEY SHARE, NO KEY UPDATE and UPDATE row locks.
|
||||||
|
*/
|
||||||
|
SELF withLock(Query.LockType lockType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query with the given lock type and lock wait.
|
||||||
|
* <p>
|
||||||
|
* Note that <code>forUpdateNoWait()</code> is the same as
|
||||||
|
* <code>withLock(LockType.UPDATE, LockWait.NOWAIT)</code>.
|
||||||
|
* <p>
|
||||||
|
* Provides us with the ability to explicitly use Postgres
|
||||||
|
* SHARE, KEY SHARE, NO KEY UPDATE and UPDATE row locks.
|
||||||
|
*/
|
||||||
|
SELF withLock(Query.LockType lockType, Query.LockWait lockWait);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute using "for update" clause which results in the DB locking the record.
|
||||||
|
* <p>
|
||||||
|
* The same as <code>withLock(LockType.UPDATE, LockWait.WAIT)</code>.
|
||||||
|
*/
|
||||||
|
SELF forUpdate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute using "for update" clause with "no wait" option.
|
||||||
|
* <p>
|
||||||
|
* This is typically a Postgres and Oracle only option at this stage.
|
||||||
|
* <p>
|
||||||
|
* The same as <code>withLock(LockType.UPDATE, LockWait.NOWAIT)</code>.
|
||||||
|
*/
|
||||||
|
SELF forUpdateNoWait();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute using "for update" clause with "skip locked" option.
|
||||||
|
* <p>
|
||||||
|
* This is typically a Postgres and Oracle only option at this stage.
|
||||||
|
* <p>
|
||||||
|
* The same as <code>withLock(LockType.UPDATE, LockWait.SKIPLOCKED)</code>.
|
||||||
|
*/
|
||||||
|
SELF forUpdateSkipLocked();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set of properties or paths that are unknown (do not map to known properties or paths).
|
||||||
|
* <p>
|
||||||
|
* Validate the query checking the where and orderBy expression paths to confirm if
|
||||||
|
* they represent valid properties or paths for the given bean type.
|
||||||
|
*/
|
||||||
|
Set<String> validate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the sql that was generated for executing this query.
|
||||||
|
* <p>
|
||||||
|
* This is only available after the query has been executed and provided only
|
||||||
|
* for informational purposes.
|
||||||
|
*/
|
||||||
|
String getGeneratedSql();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the type of beans being queried.
|
||||||
|
*/
|
||||||
|
Class<T> getBeanType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute as a delete query deleting the 'root level' beans that match the predicates
|
||||||
|
* in the query.
|
||||||
|
* <p>
|
||||||
|
* Note that if the query includes joins then the generated delete statement may not be
|
||||||
|
* optimal depending on the database platform.
|
||||||
|
*
|
||||||
|
* @return the number of beans/rows that were deleted.
|
||||||
|
*/
|
||||||
|
int delete();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query returning true if a row is found.
|
||||||
|
* <p>
|
||||||
|
* The query is executed using max rows of 1 and will only select the id property.
|
||||||
|
* This method is really just a convenient way to optimise a query to perform a
|
||||||
|
* 'does a row exist in the db' check.
|
||||||
|
*
|
||||||
|
* <h2>Example using a query bean:</h2>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* boolean userExists =
|
||||||
|
* new QContact()
|
||||||
|
* .email.equalTo("rob@foo.com")
|
||||||
|
* .exists();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* <h2>Example:</h2>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* boolean userExists = query()
|
||||||
|
* .where().eq("email", "rob@foo.com")
|
||||||
|
* .exists();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @return True if the query finds a matching row in the database
|
||||||
|
*/
|
||||||
|
boolean exists();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query returning either a single bean or null (if no matching
|
||||||
|
* bean is found).
|
||||||
|
* <p>
|
||||||
|
* If more than 1 row is found for this query then a PersistenceException is
|
||||||
|
* thrown.
|
||||||
|
* <p>
|
||||||
|
* This is useful when your predicates dictate that your query should only
|
||||||
|
* return 0 or 1 results.
|
||||||
|
* <p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* // assuming the sku of products is unique...
|
||||||
|
* Product product =
|
||||||
|
* new QProduct()
|
||||||
|
* .sku.equalTo("aa113")
|
||||||
|
* .findOne();
|
||||||
|
* ...
|
||||||
|
* }</pre>
|
||||||
|
* <p>
|
||||||
|
* It is also useful with finding objects by their id when you want to specify
|
||||||
|
* further join information to optimise the query.
|
||||||
|
* <p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* // Fetch order 42 and additionally fetch join its order details...
|
||||||
|
* Order order =
|
||||||
|
* new QOrder()
|
||||||
|
* .fetch("details") // eagerly load the order details
|
||||||
|
* .id.equalTo(42)
|
||||||
|
* .findOne();
|
||||||
|
*
|
||||||
|
* // the order details were eagerly loaded
|
||||||
|
* List<OrderDetail> details = order.getDetails();
|
||||||
|
* ...
|
||||||
|
* }</pre>
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
T findOne();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query returning an optional bean.
|
||||||
|
*/
|
||||||
|
Optional<T> findOneOrEmpty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query returning the list of objects.
|
||||||
|
* <p>
|
||||||
|
* This query will execute against the EbeanServer that was used to create it.
|
||||||
|
* <p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* List<Customer> customers =
|
||||||
|
* new QCustomer()
|
||||||
|
* .name.ilike("rob%")
|
||||||
|
* .findList();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @see Query#findList()
|
||||||
|
*/
|
||||||
|
List<T> findList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query returning the result as a Stream.
|
||||||
|
* <p>
|
||||||
|
* Note that this can support very large queries iterating
|
||||||
|
* any number of results. To do so internally it can use
|
||||||
|
* multiple persistence contexts.
|
||||||
|
* </p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* // use try with resources to ensure Stream is closed
|
||||||
|
*
|
||||||
|
* try (Stream<Customer> stream = query.findStream()) {
|
||||||
|
* stream
|
||||||
|
* .map(...)
|
||||||
|
* .collect(...);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*/
|
||||||
|
Stream<T> findStream();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query returning the set of objects.
|
||||||
|
* <p>
|
||||||
|
* This query will execute against the EbeanServer that was used to create it.
|
||||||
|
* <p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* Set<Customer> customers =
|
||||||
|
* new QCustomer()
|
||||||
|
* .name.ilike("rob%")
|
||||||
|
* .findSet();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @see Query#findSet()
|
||||||
|
*/
|
||||||
|
Set<T> findSet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query returning the list of Id's.
|
||||||
|
* <p>
|
||||||
|
* This query will execute against the EbeanServer that was used to create it.
|
||||||
|
*
|
||||||
|
* @see Query#findIds()
|
||||||
|
*/
|
||||||
|
<A> List<A> findIds();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query returning a map of the objects.
|
||||||
|
* <p>
|
||||||
|
* This query will execute against the EbeanServer that was used to create it.
|
||||||
|
* <p>
|
||||||
|
* You can use setMapKey() or asMapKey() to specify the property to be used as keys
|
||||||
|
* on the map. If one is not specified then the id property is used.
|
||||||
|
* <p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* Map<String, Product> map =
|
||||||
|
* new QProduct()
|
||||||
|
* .sku.asMapKey()
|
||||||
|
* .findMap();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @see Query#findMap()
|
||||||
|
*/
|
||||||
|
<K> Map<K, T> findMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query iterating over the results.
|
||||||
|
* <p>
|
||||||
|
* Note that findIterate (and findEach and findEachWhile) uses a "per graph"
|
||||||
|
* persistence context scope and adjusts jdbc fetch buffer size for large
|
||||||
|
* queries. As such it is better to use findList for small queries.
|
||||||
|
* <p>
|
||||||
|
* Remember that with {@link QueryIterator} you must call {@link QueryIterator#close()}
|
||||||
|
* when you have finished iterating the results (typically in a finally block).
|
||||||
|
* <p>
|
||||||
|
* findEach() and findEachWhile() are preferred to findIterate() as they ensure
|
||||||
|
* the jdbc statement and resultSet are closed at the end of the iteration.
|
||||||
|
* <p>
|
||||||
|
* This query will execute against the EbeanServer that was used to create it.
|
||||||
|
* </p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* Query<Customer> query =
|
||||||
|
* new QCustomer()
|
||||||
|
* .status.equalTo(Customer.Status.NEW)
|
||||||
|
* .orderBy()
|
||||||
|
* id.asc()
|
||||||
|
* .query();
|
||||||
|
*
|
||||||
|
* try (QueryIterator<Customer> it = query.findIterate()) {
|
||||||
|
* while (it.hasNext()) {
|
||||||
|
* Customer customer = it.next();
|
||||||
|
* // do something with customer ...
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*/
|
||||||
|
QueryIterator<T> findIterate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query returning a list of values for a single property.
|
||||||
|
* <p>
|
||||||
|
* <h3>Example</h3>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* List<String> names =
|
||||||
|
* new QCustomer()
|
||||||
|
* .setDistinct(true)
|
||||||
|
* .select(name)
|
||||||
|
* .findSingleAttributeList();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @return the list of values for the selected property
|
||||||
|
*/
|
||||||
|
<A> List<A> findSingleAttributeList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query returning a single value or null for a single property.
|
||||||
|
* <p>
|
||||||
|
* <h3>Example</h3>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* LocalDate maxDate =
|
||||||
|
* new QCustomer()
|
||||||
|
* .select("max(startDate)")
|
||||||
|
* .findSingleAttribute();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @return a single value or null for the selected property
|
||||||
|
*/
|
||||||
|
@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();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query returning a hashset of values for a single property.
|
||||||
|
*/
|
||||||
|
<A> Set<A> findSingleAttributeSet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query processing the beans one at a time.
|
||||||
|
* <p>
|
||||||
|
* This method is appropriate to process very large query results as the
|
||||||
|
* beans are consumed one at a time and do not need to be held in memory
|
||||||
|
* (unlike #findList #findSet etc)
|
||||||
|
* <p>
|
||||||
|
* Note that internally Ebean can inform the JDBC driver that it is expecting larger
|
||||||
|
* resultSet and specifically for MySQL this hint is required to stop it's JDBC driver
|
||||||
|
* from buffering the entire resultSet. As such, for smaller resultSets findList() is
|
||||||
|
* generally preferable.
|
||||||
|
* <p>
|
||||||
|
* Compared with #findEachWhile this will always process all the beans where as
|
||||||
|
* #findEachWhile provides a way to stop processing the query result early before
|
||||||
|
* all the beans have been read.
|
||||||
|
* <p>
|
||||||
|
* This method is functionally equivalent to findIterate() but instead of using an
|
||||||
|
* iterator uses the Consumer interface which is better suited to use with closures.
|
||||||
|
*
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* new QCustomer()
|
||||||
|
* .status.equalTo(Status.NEW)
|
||||||
|
* .orderBy().id.asc()
|
||||||
|
* .findEach((Customer customer) -> {
|
||||||
|
*
|
||||||
|
* // do something with customer
|
||||||
|
* System.out.println("-- visit " + customer);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @param consumer the consumer used to process the queried beans.
|
||||||
|
*/
|
||||||
|
void findEach(Consumer<T> consumer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute findEach streaming query batching the results for consuming.
|
||||||
|
* <p>
|
||||||
|
* This query execution will stream the results and is suited to consuming
|
||||||
|
* large numbers of results from the database.
|
||||||
|
* <p>
|
||||||
|
* Typically, we use this batch consumer when we want to do further processing on
|
||||||
|
* the beans and want to do that processing in batch form, for example - 100 at
|
||||||
|
* a time.
|
||||||
|
*
|
||||||
|
* @param batch The number of beans processed in the batch
|
||||||
|
* @param consumer Process the batch of beans
|
||||||
|
*/
|
||||||
|
void findEach(int batch, Consumer<List<T>> consumer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the query using callbacks to a visitor to process the resulting
|
||||||
|
* beans one at a time.
|
||||||
|
* <p>
|
||||||
|
* This method is functionally equivalent to findIterate() but instead of using an
|
||||||
|
* iterator uses the Predicate interface which is better suited to use with closures.
|
||||||
|
*
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* new QCustomer()
|
||||||
|
* .status.equalTo(Status.NEW)
|
||||||
|
* .orderBy().id.asc()
|
||||||
|
* .findEachWhile((Customer customer) -> {
|
||||||
|
*
|
||||||
|
* // do something with customer
|
||||||
|
* System.out.println("-- visit " + customer);
|
||||||
|
*
|
||||||
|
* // return true to continue processing or false to stop
|
||||||
|
* return (customer.getId() < 40);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @param consumer the consumer used to process the queried beans.
|
||||||
|
*/
|
||||||
|
void findEachWhile(Predicate<T> consumer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return versions of a @History entity bean.
|
||||||
|
* <p>
|
||||||
|
* Generally this query is expected to be a find by id or unique predicates query.
|
||||||
|
* It will execute the query against the history returning the versions of the bean.
|
||||||
|
*/
|
||||||
|
List<Version<T>> findVersions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return versions of a @History entity bean between a start and end timestamp.
|
||||||
|
* <p>
|
||||||
|
* Generally this query is expected to be a find by id or unique predicates query.
|
||||||
|
* It will execute the query against the history returning the versions of the bean.
|
||||||
|
*/
|
||||||
|
List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the count of entities this query should return.
|
||||||
|
* <p>
|
||||||
|
* This is the number of 'top level' or 'root level' entities.
|
||||||
|
*/
|
||||||
|
int findCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute find row count query in a background thread.
|
||||||
|
* <p>
|
||||||
|
* This returns a Future object which can be used to cancel, check the
|
||||||
|
* execution status (isDone etc) and get the value (with or without a
|
||||||
|
* timeout).
|
||||||
|
*
|
||||||
|
* @return a Future object for the row count query
|
||||||
|
*/
|
||||||
|
FutureRowCount<T> findFutureCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute find Id's query in a background thread.
|
||||||
|
* <p>
|
||||||
|
* This returns a Future object which can be used to cancel, check the
|
||||||
|
* execution status (isDone etc) and get the value (with or without a
|
||||||
|
* timeout).
|
||||||
|
*
|
||||||
|
* @return a Future object for the list of Id's
|
||||||
|
*/
|
||||||
|
FutureIds<T> findFutureIds();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute find list query in a background thread.
|
||||||
|
* <p>
|
||||||
|
* This query will execute in it's own PersistenceContext and using its own transaction.
|
||||||
|
* What that means is that it will not share any bean instances with other queries.
|
||||||
|
*
|
||||||
|
* @return a Future object for the list result of the query
|
||||||
|
*/
|
||||||
|
FutureList<T> findFutureList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a PagedList for this query using firstRow and maxRows.
|
||||||
|
* <p>
|
||||||
|
* The benefit of using this over findList() is that it provides functionality to get the
|
||||||
|
* total row count etc.
|
||||||
|
* <p>
|
||||||
|
* If maxRows is not set on the query prior to calling findPagedList() then a
|
||||||
|
* PersistenceException is thrown.
|
||||||
|
* <p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* PagedList<Order> pagedList =
|
||||||
|
* new QOrder()
|
||||||
|
* .setFirstRow(50)
|
||||||
|
* .setMaxRows(20)
|
||||||
|
* .findPagedList();
|
||||||
|
*
|
||||||
|
* // fetch the total row count in the background
|
||||||
|
* pagedList.loadRowCount();
|
||||||
|
*
|
||||||
|
* List<Order> orders = pagedList.getList();
|
||||||
|
* int totalRowCount = pagedList.getTotalRowCount();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @return The PagedList
|
||||||
|
*/
|
||||||
|
PagedList<T> findPagedList();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,242 @@
|
|||||||
|
package io.ebean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder for ORM Query projection (the select and fetch part).
|
||||||
|
*
|
||||||
|
* @param <SELF> The builder type
|
||||||
|
* @param <T> The entity bean type
|
||||||
|
*/
|
||||||
|
public interface QueryBuilderProjection<SELF, T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the path properties replacing the select and fetch clauses.
|
||||||
|
* <p>
|
||||||
|
* This is typically used when the FetchPath is applied to both the query and the JSON output.
|
||||||
|
*/
|
||||||
|
SELF apply(FetchPath fetchPath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the properties to fetch on the root level entity bean in comma delimited format.
|
||||||
|
* <p>
|
||||||
|
* The Id property is automatically included in the properties to fetch unless setDistinct(true)
|
||||||
|
* is set on the query.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Use {@link #fetch(String, String)} to specify specific properties to fetch
|
||||||
|
* on other non-root level paths of the object graph.
|
||||||
|
* </p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* List<Customer> customers = DB.find(Customer.class)
|
||||||
|
* // Only fetch the customer id, name and status.
|
||||||
|
* // This is described as a "Partial Object"
|
||||||
|
* .select("name, status")
|
||||||
|
* .where.ilike("name", "rob%")
|
||||||
|
* .findList();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @param fetchProperties the properties to fetch for this bean (* = all properties).
|
||||||
|
*/
|
||||||
|
SELF select(String fetchProperties);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the fetchGroup which defines what part of the object graph to load.
|
||||||
|
*/
|
||||||
|
SELF select(FetchGroup<T> fetchGroup);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify a path to fetch eagerly including specific properties.
|
||||||
|
* <p>
|
||||||
|
* Ebean will endeavour to fetch this path using a SQL join. If Ebean determines that it can
|
||||||
|
* not use a SQL join (due to maxRows or because it would result in a cartesian product) Ebean
|
||||||
|
* will automatically convert this fetch query into a "query join" - i.e. use fetchQuery().
|
||||||
|
* </p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* // query orders...
|
||||||
|
* List<Order> orders = DB.find(Order.class)
|
||||||
|
* // fetch the customer...
|
||||||
|
* // ... getting the customers name and phone number
|
||||||
|
* .fetch("customer", "name, phoneNumber")
|
||||||
|
*
|
||||||
|
* // ... also fetch the customers billing address (* = all properties)
|
||||||
|
* .fetch("customer.billingAddress", "*")
|
||||||
|
* .findList();
|
||||||
|
* }</pre>
|
||||||
|
* <p>
|
||||||
|
* If columns is null or "*" then all columns/properties for that path are fetched.
|
||||||
|
* </p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* // fetch customers (their id, name and status)
|
||||||
|
* List<Customer> customers = DB.find(Customer.class)
|
||||||
|
* .select("name, status")
|
||||||
|
* .fetch("contacts", "firstName,lastName,email")
|
||||||
|
* .findList();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @param path the property path we wish to fetch eagerly.
|
||||||
|
* @param fetchProperties properties of the associated bean that you want to include in the
|
||||||
|
* fetch (* means all properties, null also means all properties).
|
||||||
|
*/
|
||||||
|
SELF fetch(String path, String fetchProperties);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the path and properties using a "query join" (separate SQL query).
|
||||||
|
* <p>
|
||||||
|
* This is the same as:
|
||||||
|
* </p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* fetch(path, fetchProperties, FetchConfig.ofQuery())
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
* <p>
|
||||||
|
* This would be used instead of a fetch() when we use a separate SQL query to fetch this
|
||||||
|
* part of the object graph rather than a SQL join.
|
||||||
|
* <p>
|
||||||
|
* We might typically get a performance benefit when the path to fetch is a OneToMany
|
||||||
|
* or ManyToMany, the 'width' of the 'root bean' is wide and the cardinality of the many
|
||||||
|
* is high.
|
||||||
|
*
|
||||||
|
* @param path the property path we wish to fetch eagerly.
|
||||||
|
* @param fetchProperties properties of the associated bean that you want to include in the
|
||||||
|
* fetch (* means all properties, null also means all properties).
|
||||||
|
*/
|
||||||
|
SELF fetchQuery(String path, String fetchProperties);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the path and properties using L2 bean cache.
|
||||||
|
*
|
||||||
|
* @param path The path of the beans we are fetching from L2 cache.
|
||||||
|
* @param fetchProperties The properties that should be loaded.
|
||||||
|
*/
|
||||||
|
SELF fetchCache(String path, String fetchProperties);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the path and properties lazily (via batch lazy loading).
|
||||||
|
* <p>
|
||||||
|
* This is the same as:
|
||||||
|
*
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* fetch(path, fetchProperties, FetchConfig.ofLazy())
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
* <p>
|
||||||
|
* The reason for using fetchLazy() is to either:
|
||||||
|
* <ul>
|
||||||
|
* <li>Control/tune what is fetched as part of lazy loading</li>
|
||||||
|
* <li>Make use of the L2 cache, build this part of the graph from L2 cache</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param path the property path we wish to fetch lazily.
|
||||||
|
* @param fetchProperties properties of the associated bean that you want to include in the
|
||||||
|
* fetch (* means all properties, null also means all properties).
|
||||||
|
*/
|
||||||
|
SELF fetchLazy(String path, String fetchProperties);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additionally specify a FetchConfig to use a separate query or lazy loading
|
||||||
|
* to load this path.
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* // fetch customers (their id, name and status)
|
||||||
|
* List<Customer> customers = DB.find(Customer.class)
|
||||||
|
* .select("name, status")
|
||||||
|
* .fetch("contacts", "firstName,lastName,email", FetchConfig.ofLazy(10))
|
||||||
|
* .findList();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @param path the property path we wish to fetch eagerly.
|
||||||
|
*/
|
||||||
|
SELF fetch(String path, String fetchProperties, FetchConfig fetchConfig);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify a path to fetch eagerly including all its properties.
|
||||||
|
* <p>
|
||||||
|
* Ebean will endeavour to fetch this path using a SQL join. If Ebean determines that it can
|
||||||
|
* not use a SQL join (due to maxRows or because it would result in a cartesian product) Ebean
|
||||||
|
* will automatically convert this fetch query into a "query join" - i.e. use fetchQuery().
|
||||||
|
* </p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* // fetch customers (their id, name and status)
|
||||||
|
* List<Customer> customers = DB.find(Customer.class)
|
||||||
|
* // eager fetch the contacts
|
||||||
|
* .fetch("contacts")
|
||||||
|
* .findList();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @param path the property path we wish to fetch eagerly.
|
||||||
|
*/
|
||||||
|
SELF fetch(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the path eagerly using a "query join" (separate SQL query).
|
||||||
|
* <p>
|
||||||
|
* This is the same as:
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* fetch(path, FetchConfig.ofQuery())
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
* <p>
|
||||||
|
* This would be used instead of a fetch() when we use a separate SQL query to fetch this
|
||||||
|
* part of the object graph rather than a SQL join.
|
||||||
|
* <p>
|
||||||
|
* We might typically get a performance benefit when the path to fetch is a OneToMany
|
||||||
|
* or ManyToMany, the 'width' of the 'root bean' is wide and the cardinality of the many
|
||||||
|
* is high.
|
||||||
|
*
|
||||||
|
* @param path the property path we wish to fetch eagerly
|
||||||
|
*/
|
||||||
|
SELF fetchQuery(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the path eagerly using L2 cache.
|
||||||
|
*/
|
||||||
|
SELF fetchCache(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the path lazily (via batch lazy loading).
|
||||||
|
* <p>
|
||||||
|
* This is the same as:
|
||||||
|
* </p>
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* fetch(path, FetchConfig.ofLazy())
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
* <p>
|
||||||
|
* The reason for using fetchLazy() is to either:
|
||||||
|
* </p>
|
||||||
|
* <ul>
|
||||||
|
* <li>Control/tune what is fetched as part of lazy loading</li>
|
||||||
|
* <li>Make use of the L2 cache, build this part of the graph from L2 cache</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param path the property path we wish to fetch lazily.
|
||||||
|
*/
|
||||||
|
SELF fetchLazy(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additionally specify a JoinConfig to specify a "query join" and or define
|
||||||
|
* the lazy loading query.
|
||||||
|
* <pre>{@code
|
||||||
|
*
|
||||||
|
* // fetch customers (their id, name and status)
|
||||||
|
* List<Customer> customers = DB.find(Customer.class)
|
||||||
|
* // lazy fetch contacts with a batch size of 100
|
||||||
|
* .fetch("contacts", FetchConfig.ofLazy(100))
|
||||||
|
* .findList();
|
||||||
|
*
|
||||||
|
* }</pre>
|
||||||
|
*/
|
||||||
|
SELF fetch(String path, FetchConfig fetchConfig);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,7 +3,9 @@ package io.ebean;
|
|||||||
import io.avaje.lang.NonNullApi;
|
import io.avaje.lang.NonNullApi;
|
||||||
import io.avaje.lang.Nullable;
|
import io.avaje.lang.Nullable;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.sql.Connection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -45,14 +47,19 @@ public interface SqlQuery extends Serializable, CancelableQuery {
|
|||||||
*/
|
*/
|
||||||
SqlQuery usingTransaction(Transaction transaction);
|
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
|
* 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).
|
* being used (that is using a read replica database potentially with replication lag).
|
||||||
* <p>
|
* <p>
|
||||||
* When the database is configured with a read-only DataSource via
|
* 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
|
* 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.
|
* against the master data source.
|
||||||
*/
|
*/
|
||||||
SqlQuery usingMaster();
|
SqlQuery usingMaster();
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import java.util.Collection;
|
|||||||
* <p>
|
* <p>
|
||||||
* This is currently deemed to be experimental and subject to change.
|
* This is currently deemed to be experimental and subject to change.
|
||||||
*/
|
*/
|
||||||
@Deprecated(since = "experimental")
|
|
||||||
public final class StdOperators {
|
public final class StdOperators {
|
||||||
|
|
||||||
// ---- Functions ---- //
|
// ---- Functions ---- //
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.ebean.cache;
|
package io.ebean.cache;
|
||||||
|
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin that provides a ServerCacheNotify implementation.
|
* Plugin that provides a ServerCacheNotify implementation.
|
||||||
@@ -12,5 +12,5 @@ public interface ServerCacheNotifyPlugin {
|
|||||||
/**
|
/**
|
||||||
* Create a ServerCacheNotify implementation given the server configuration.
|
* Create a ServerCacheNotify implementation given the server configuration.
|
||||||
*/
|
*/
|
||||||
ServerCacheNotify create(DatabaseConfig config);
|
ServerCacheNotify create(DatabaseBuilder config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.ebean.cache;
|
package io.ebean.cache;
|
||||||
|
|
||||||
import io.ebean.BackgroundExecutor;
|
import io.ebean.BackgroundExecutor;
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The plugin interface that creates a ServerCacheFactory.
|
* The plugin interface that creates a ServerCacheFactory.
|
||||||
@@ -11,5 +11,5 @@ public interface ServerCachePlugin {
|
|||||||
/**
|
/**
|
||||||
* Create the ServerCacheFactory given the server config and background executor service.
|
* Create the ServerCacheFactory given the server config and background executor service.
|
||||||
*/
|
*/
|
||||||
ServerCacheFactory create(DatabaseConfig config, BackgroundExecutor executor);
|
ServerCacheFactory create(DatabaseBuilder config, BackgroundExecutor executor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package io.ebean.config;
|
package io.ebean.config;
|
||||||
|
|
||||||
|
import io.ebean.DatabaseBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to provide some automatic configuration early in the creation of a Database.
|
* Used to provide some automatic configuration early in the creation of a Database.
|
||||||
*/
|
*/
|
||||||
@@ -8,11 +10,11 @@ public interface AutoConfigure {
|
|||||||
/**
|
/**
|
||||||
* Perform configuration for the DatabaseConfig prior to properties load.
|
* Perform configuration for the DatabaseConfig prior to properties load.
|
||||||
*/
|
*/
|
||||||
void preConfigure(DatabaseConfig config);
|
void preConfigure(DatabaseBuilder config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide some configuration the DatabaseConfig prior to server creation but after properties have been applied.
|
* Provide some configuration the DatabaseConfig prior to server creation but after properties have been applied.
|
||||||
*/
|
*/
|
||||||
void postConfigure(DatabaseConfig config);
|
void postConfigure(DatabaseBuilder config);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ public class ContainerConfig {
|
|||||||
private String namespace;
|
private String namespace;
|
||||||
private String podName;
|
private String podName;
|
||||||
private int port;
|
private int port;
|
||||||
|
|
||||||
private Properties properties;
|
private Properties properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -123,5 +122,4 @@ public class ContainerConfig {
|
|||||||
protected boolean getProperty(Properties properties, String key, boolean defaultValue) {
|
protected boolean getProperty(Properties properties, String key, boolean defaultValue) {
|
||||||
return "true".equalsIgnoreCase(properties.getProperty(key, Boolean.toString(defaultValue)));
|
return "true".equalsIgnoreCase(properties.getProperty(key, Boolean.toString(defaultValue)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,7 @@
|
|||||||
package io.ebean.config;
|
package io.ebean.config;
|
||||||
|
|
||||||
|
import io.ebean.DatabaseBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a ServiceLoader based mechanism to configure a DatabaseConfig.
|
* Provides a ServiceLoader based mechanism to configure a DatabaseConfig.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -35,5 +37,5 @@ public interface DatabaseConfigProvider {
|
|||||||
* Typically we explicitly register entity bean classes and thus avoid classpath scanning.
|
* Typically we explicitly register entity bean classes and thus avoid classpath scanning.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
void apply(DatabaseConfig config);
|
void apply(DatabaseBuilder config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package io.ebean.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the length-check mode.
|
||||||
|
*
|
||||||
|
* @author Roland Praml, FOCONIS AG
|
||||||
|
*/
|
||||||
|
public enum LengthCheck {
|
||||||
|
/**
|
||||||
|
* By default, length checking is off. This means, strings/jsons and files are passed to the DB and the DB might or might not check the length.
|
||||||
|
* The DB has to check the data length. Note this is not possible for certain datatypes (e.g. clob without size)
|
||||||
|
*/
|
||||||
|
OFF,
|
||||||
|
/**
|
||||||
|
* When enabling length check, ebean validates strings/json strings and files before saving them to DB.
|
||||||
|
*/
|
||||||
|
ON,
|
||||||
|
/**
|
||||||
|
* Same as "ON", but take the UTF8-bytelength for validation. This may be useful, if you have an UTF8 based charset (default for DB2)
|
||||||
|
*/
|
||||||
|
UTF8
|
||||||
|
}
|
||||||
@@ -1,50 +1,29 @@
|
|||||||
package io.ebean.config;
|
package io.ebean.config;
|
||||||
|
|
||||||
|
import io.ebean.ProfileLocation;
|
||||||
import io.ebean.bean.ObjectGraphNode;
|
import io.ebean.bean.ObjectGraphNode;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Slow query event.
|
* The data for the slow query.
|
||||||
*/
|
*/
|
||||||
public class SlowQueryEvent {
|
public interface SlowQueryEvent {
|
||||||
|
|
||||||
private final String sql;
|
|
||||||
|
|
||||||
private final long timeMillis;
|
|
||||||
|
|
||||||
private final int rowCount;
|
|
||||||
|
|
||||||
private final ObjectGraphNode originNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct with the SQL and execution time in millis.
|
|
||||||
*/
|
|
||||||
public SlowQueryEvent(String sql, long timeMillis, int rowCount, ObjectGraphNode originNode) {
|
|
||||||
this.sql = sql;
|
|
||||||
this.timeMillis = timeMillis;
|
|
||||||
this.rowCount = rowCount;
|
|
||||||
this.originNode = originNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the SQL for the slow query.
|
* Return the SQL for the slow query.
|
||||||
*/
|
*/
|
||||||
public String getSql() {
|
String getSql();
|
||||||
return sql;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the execution time in millis.
|
* Return the execution time in millis.
|
||||||
*/
|
*/
|
||||||
public long getTimeMillis() {
|
long getTimeMillis();
|
||||||
return timeMillis;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the total row count associated with the query.
|
* Return the total row count associated with the query.
|
||||||
*/
|
*/
|
||||||
public int getRowCount() {
|
int getRowCount();
|
||||||
return rowCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the origin point for the root query.
|
* Return the origin point for the root query.
|
||||||
@@ -53,7 +32,20 @@ public class SlowQueryEvent {
|
|||||||
* shows the code that invoked the query.
|
* shows the code that invoked the query.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public ObjectGraphNode getOriginNode() {
|
ObjectGraphNode getOriginNode();
|
||||||
return originNode;
|
|
||||||
}
|
/**
|
||||||
|
* Return the bind parameters.
|
||||||
|
*/
|
||||||
|
List<Object> getBindParams();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the label.
|
||||||
|
*/
|
||||||
|
String getLabel();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the profile location.
|
||||||
|
*/
|
||||||
|
ProfileLocation getProfileLocation();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -769,4 +769,15 @@ public class DatabasePlatform {
|
|||||||
public boolean supportsNativeJavaTime() {
|
public boolean supportsNativeJavaTime() {
|
||||||
return supportsNativeJavaTime;
|
return supportsNativeJavaTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String inlineSqlComment(String label) {
|
||||||
|
if (label == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return "/* " + label + " */ ";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String inlineSqlHint(String hint) {
|
||||||
|
return "/*+ " + hint + " */ ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.ebean.event;
|
package io.ebean.event;
|
||||||
|
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to configure the server on startup.
|
* Used to configure the server on startup.
|
||||||
@@ -13,6 +13,6 @@ public interface ServerConfigStartup {
|
|||||||
/**
|
/**
|
||||||
* On starting configure the DatabaseConfig.
|
* On starting configure the DatabaseConfig.
|
||||||
*/
|
*/
|
||||||
void onStart(DatabaseConfig config);
|
void onStart(DatabaseBuilder config);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import java.sql.Driver;
|
|||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
@@ -23,7 +24,7 @@ public final class ShutdownManager {
|
|||||||
|
|
||||||
private static final System.Logger log = EbeanVersion.log;
|
private static final System.Logger log = EbeanVersion.log;
|
||||||
private static final ReentrantLock lock = new ReentrantLock();
|
private static final ReentrantLock lock = new ReentrantLock();
|
||||||
private static final List<Database> databases = new ArrayList<>();
|
private static final List<Database> databases = Collections.synchronizedList(new ArrayList<>());
|
||||||
private static final ShutdownHook shutdownHook = new ShutdownHook();
|
private static final ShutdownHook shutdownHook = new ShutdownHook();
|
||||||
|
|
||||||
private static boolean stopping;
|
private static boolean stopping;
|
||||||
@@ -177,12 +178,7 @@ public final class ShutdownManager {
|
|||||||
* Register an ebeanServer to be shutdown when the JVM is shutdown.
|
* Register an ebeanServer to be shutdown when the JVM is shutdown.
|
||||||
*/
|
*/
|
||||||
public static void registerDatabase(Database server) {
|
public static void registerDatabase(Database server) {
|
||||||
lock.lock();
|
databases.add(server);
|
||||||
try {
|
|
||||||
databases.add(server);
|
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -192,12 +188,7 @@ public final class ShutdownManager {
|
|||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public static void unregisterDatabase(Database server) {
|
public static void unregisterDatabase(Database server) {
|
||||||
lock.lock();
|
databases.remove(server);
|
||||||
try {
|
|
||||||
databases.remove(server);
|
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ShutdownHook extends Thread {
|
private static class ShutdownHook extends Thread {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package io.ebean.plugin;
|
|||||||
import io.ebean.Database;
|
import io.ebean.Database;
|
||||||
import io.ebean.bean.BeanLoader;
|
import io.ebean.bean.BeanLoader;
|
||||||
import io.ebean.bean.EntityBeanIntercept;
|
import io.ebean.bean.EntityBeanIntercept;
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -16,7 +16,7 @@ public interface SpiServer extends Database {
|
|||||||
/**
|
/**
|
||||||
* Return the DatabaseConfig.
|
* Return the DatabaseConfig.
|
||||||
*/
|
*/
|
||||||
DatabaseConfig config();
|
DatabaseBuilder.Settings config();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the DatabasePlatform for this database.
|
* Return the DatabasePlatform for this database.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.ebean.service;
|
package io.ebean.service;
|
||||||
|
|
||||||
import io.ebean.Database;
|
import io.ebean.Database;
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the Database implementations. This is used internally by the EbeanServerFactory and is not currently
|
* Creates the Database implementations. This is used internally by the EbeanServerFactory and is not currently
|
||||||
@@ -14,7 +14,7 @@ public interface SpiContainer {
|
|||||||
*
|
*
|
||||||
* @param configuration The configuration information for this database.
|
* @param configuration The configuration information for this database.
|
||||||
*/
|
*/
|
||||||
Database createServer(DatabaseConfig configuration);
|
Database createServer(DatabaseBuilder configuration);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an EbeanServer just using the name.
|
* Create an EbeanServer just using the name.
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
/* Javadoc style sheet */
|
|
||||||
|
|
||||||
/* Define colors, fonts and other style attributes here to override the defaults */
|
|
||||||
|
|
||||||
/* Page background color */
|
|
||||||
body {
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
font-size: 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre.code {
|
|
||||||
padding: 1em;
|
|
||||||
margin-left: 2em;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Headings */
|
|
||||||
h1 {
|
|
||||||
font-size: 14pt
|
|
||||||
}
|
|
||||||
|
|
||||||
#overviewexamples h3 {
|
|
||||||
font-size: 10pt
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Table colors */
|
|
||||||
.TableHeadingColor {
|
|
||||||
background: #CCCCFF
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dark mauve */
|
|
||||||
.TableSubHeadingColor {
|
|
||||||
background: #EEEEFF
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Light mauve */
|
|
||||||
.TableRowColor {
|
|
||||||
background: #FFFFFF
|
|
||||||
}
|
|
||||||
|
|
||||||
/* White */
|
|
||||||
|
|
||||||
/* Font used in left-hand frame lists */
|
|
||||||
.FrameTitleFont {
|
|
||||||
font-size: 12pt;
|
|
||||||
font-family: Helvetica, Arial, sans-serif
|
|
||||||
}
|
|
||||||
|
|
||||||
.FrameHeadingFont {
|
|
||||||
font-size: 10pt;
|
|
||||||
font-family: Helvetica, Arial, sans-serif
|
|
||||||
}
|
|
||||||
|
|
||||||
.FrameItemFont {
|
|
||||||
font-size: 10pt;
|
|
||||||
font-family: Helvetica, Arial, sans-serif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Navigation bar fonts and colors */
|
|
||||||
.NavBarCell1 {
|
|
||||||
background-color: #EEEEFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Light mauve */
|
|
||||||
.NavBarCell1Rev {
|
|
||||||
background-color: #00008B;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dark Blue */
|
|
||||||
.NavBarFont1 {
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.NavBarFont1Rev {
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
color: #FFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.NavBarCell2 {
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.NavBarCell3 {
|
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -22,6 +22,8 @@ public class JsonWriteOptions {
|
|||||||
|
|
||||||
protected JsonConfig.Include include;
|
protected JsonConfig.Include include;
|
||||||
|
|
||||||
|
protected boolean includeLoadedImplicit = true;
|
||||||
|
|
||||||
protected Map<String, JsonWriteBeanVisitor<?>> visitorMap;
|
protected Map<String, JsonWriteBeanVisitor<?>> visitorMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -73,6 +75,20 @@ public class JsonWriteOptions {
|
|||||||
this.include = include;
|
this.include = include;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should loaded properties be included implicit, if no other fetch path is specified (default = true).
|
||||||
|
*/
|
||||||
|
public boolean isIncludeLoadedImplicit() {
|
||||||
|
return includeLoadedImplicit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set include loaded properties implicit (default = true).
|
||||||
|
*/
|
||||||
|
public void setIncludeLoadedImplicit(boolean includeLoadedImplicit) {
|
||||||
|
this.includeLoadedImplicit = includeLoadedImplicit;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a JsonWriteBeanVisitor for the root level.
|
* Register a JsonWriteBeanVisitor for the root level.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -21,9 +21,4 @@ class DbPrimaryTest {
|
|||||||
assertEquals("h2", DbPrimary.getDefaultServerName());
|
assertEquals("h2", DbPrimary.getDefaultServerName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLoadProperties() {
|
|
||||||
Properties properties = DbPrimary.getProperties();
|
|
||||||
assertFalse(properties.isEmpty());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.ebean.config;
|
package io.ebean.config;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebean.annotation.MutationDetection;
|
import io.ebean.annotation.MutationDetection;
|
||||||
import io.ebean.annotation.PersistBatch;
|
import io.ebean.annotation.PersistBatch;
|
||||||
import io.ebean.config.dbplatform.IdType;
|
import io.ebean.config.dbplatform.IdType;
|
||||||
@@ -17,7 +18,7 @@ class DatabaseConfigTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testLoadFromEbeanProperties() {
|
void testLoadFromEbeanProperties() {
|
||||||
DatabaseConfig config = new DatabaseConfig();
|
var config = new DatabaseConfig().settings();
|
||||||
config.loadFromProperties();
|
config.loadFromProperties();
|
||||||
|
|
||||||
assertEquals(PersistBatch.NONE, config.getPersistBatch());
|
assertEquals(PersistBatch.NONE, config.getPersistBatch());
|
||||||
@@ -32,7 +33,7 @@ class DatabaseConfigTest {
|
|||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
props.setProperty("ddl.initSql", "${user.home}" + fileSeparator + "initSql");
|
props.setProperty("ddl.initSql", "${user.home}" + fileSeparator + "initSql");
|
||||||
|
|
||||||
DatabaseConfig config = new DatabaseConfig();
|
var config = new DatabaseConfig().settings();
|
||||||
config.loadFromProperties(props);
|
config.loadFromProperties(props);
|
||||||
|
|
||||||
String ddlInitSql = config.getDdlInitSql();
|
String ddlInitSql = config.getDdlInitSql();
|
||||||
@@ -41,7 +42,7 @@ class DatabaseConfigTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testLoadWithProperties() {
|
void testLoadWithProperties() {
|
||||||
DatabaseConfig config = new DatabaseConfig();
|
DatabaseBuilder config = new DatabaseConfig();
|
||||||
config.setPersistBatch(PersistBatch.NONE);
|
config.setPersistBatch(PersistBatch.NONE);
|
||||||
config.setPersistBatchOnCascade(PersistBatch.NONE);
|
config.setPersistBatchOnCascade(PersistBatch.NONE);
|
||||||
config.setAutoReadOnlyDataSource(false);
|
config.setAutoReadOnlyDataSource(false);
|
||||||
@@ -73,6 +74,9 @@ class DatabaseConfigTest {
|
|||||||
props.setProperty("forUpdateNoKey", "true");
|
props.setProperty("forUpdateNoKey", "true");
|
||||||
props.setProperty("defaultServer", "false");
|
props.setProperty("defaultServer", "false");
|
||||||
props.setProperty("skipDataSourceCheck", "true");
|
props.setProperty("skipDataSourceCheck", "true");
|
||||||
|
props.setProperty("readOnlyDatabase", "true");
|
||||||
|
props.setProperty("lengthCheck", "ON");
|
||||||
|
props.setProperty("includeLabelInSql", "true");
|
||||||
|
|
||||||
props.setProperty("queryPlan.enable", "true");
|
props.setProperty("queryPlan.enable", "true");
|
||||||
props.setProperty("queryPlan.thresholdMicros", "10000");
|
props.setProperty("queryPlan.thresholdMicros", "10000");
|
||||||
@@ -83,49 +87,56 @@ class DatabaseConfigTest {
|
|||||||
|
|
||||||
config.loadFromProperties(props);
|
config.loadFromProperties(props);
|
||||||
|
|
||||||
assertFalse(config.isDefaultServer());
|
var settings = config.settings();
|
||||||
assertTrue(config.isDisableL2Cache());
|
assertFalse(settings.isDefaultServer());
|
||||||
assertTrue(config.isNotifyL2CacheInForeground());
|
assertTrue(settings.isDisableL2Cache());
|
||||||
assertTrue(config.isDbOffline());
|
assertTrue(settings.isNotifyL2CacheInForeground());
|
||||||
assertTrue(config.isAutoReadOnlyDataSource());
|
assertTrue(settings.isDbOffline());
|
||||||
assertTrue(config.isAutoLoadModuleInfo());
|
assertTrue(settings.isAutoReadOnlyDataSource());
|
||||||
assertTrue(config.isLoadModuleInfo());
|
assertTrue(settings.isAutoLoadModuleInfo());
|
||||||
assertTrue(config.skipDataSourceCheck());
|
assertTrue(settings.isLoadModuleInfo());
|
||||||
|
assertTrue(settings.skipDataSourceCheck());
|
||||||
|
assertTrue(settings.readOnlyDatabase());
|
||||||
|
assertTrue(settings.isIncludeLabelInSql());
|
||||||
|
assertThat(settings.getLengthCheck()).isEqualTo(LengthCheck.ON);
|
||||||
|
|
||||||
assertTrue(config.isIdGeneratorAutomatic());
|
assertTrue(settings.isIdGeneratorAutomatic());
|
||||||
assertFalse(config.getPlatformConfig().isCaseSensitiveCollation());
|
assertFalse(settings.getPlatformConfig().isCaseSensitiveCollation());
|
||||||
assertTrue(config.getPlatformConfig().isForUpdateNoKey());
|
assertTrue(settings.getPlatformConfig().isForUpdateNoKey());
|
||||||
|
|
||||||
assertThat(config.getNamingConvention()).isInstanceOf(MatchingNamingConvention.class);
|
assertThat(settings.getNamingConvention()).isInstanceOf(MatchingNamingConvention.class);
|
||||||
|
|
||||||
assertEquals(MutationDetection.NONE, config.getJsonMutationDetection());
|
assertEquals(MutationDetection.NONE, settings.getJsonMutationDetection());
|
||||||
config.setJsonMutationDetection(MutationDetection.SOURCE);
|
config.setJsonMutationDetection(MutationDetection.SOURCE);
|
||||||
assertEquals(MutationDetection.SOURCE, config.getJsonMutationDetection());
|
assertEquals(MutationDetection.SOURCE, settings.getJsonMutationDetection());
|
||||||
assertEquals(IdType.SEQUENCE, config.getIdType());
|
assertEquals(IdType.SEQUENCE, settings.getIdType());
|
||||||
assertEquals(PersistBatch.ALL, config.getPersistBatch());
|
assertEquals(PersistBatch.ALL, settings.getPersistBatch());
|
||||||
assertEquals(PersistBatch.ALL, config.getPersistBatchOnCascade());
|
assertEquals(PersistBatch.ALL, settings.getPersistBatchOnCascade());
|
||||||
Assertions.assertEquals(PlatformConfig.DbUuid.BINARY, config.getPlatformConfig().getDbUuid());
|
Assertions.assertEquals(PlatformConfig.DbUuid.BINARY, settings.getPlatformConfig().getDbUuid());
|
||||||
Assertions.assertEquals(JsonConfig.DateTime.MILLIS, config.getJsonDateTime());
|
Assertions.assertEquals(JsonConfig.DateTime.MILLIS, settings.getJsonDateTime());
|
||||||
assertEquals(JsonConfig.Date.MILLIS, config.getJsonDate());
|
assertEquals(JsonConfig.Date.MILLIS, settings.getJsonDate());
|
||||||
|
|
||||||
assertEquals("r0,users,orgs", config.getEnabledL2Regions());
|
assertEquals("r0,users,orgs", settings.getEnabledL2Regions());
|
||||||
|
|
||||||
assertEquals(42, config.getJdbcFetchSizeFindEach());
|
assertEquals(42, settings.getJdbcFetchSizeFindEach());
|
||||||
assertEquals(43, config.getJdbcFetchSizeFindList());
|
assertEquals(43, settings.getJdbcFetchSizeFindList());
|
||||||
assertEquals(4, config.getBackgroundExecutorSchedulePoolSize());
|
assertEquals(4, settings.getBackgroundExecutorSchedulePoolSize());
|
||||||
assertEquals(98, config.getBackgroundExecutorShutdownSecs());
|
assertEquals(98, settings.getBackgroundExecutorShutdownSecs());
|
||||||
|
|
||||||
assertTrue(config.isQueryPlanEnable());
|
assertTrue(settings.isQueryPlanEnable());
|
||||||
assertEquals(10000, config.getQueryPlanThresholdMicros());
|
assertEquals(10000, settings.getQueryPlanThresholdMicros());
|
||||||
assertTrue(config.isQueryPlanCapture());
|
assertTrue(settings.isQueryPlanCapture());
|
||||||
assertEquals(42, config.getQueryPlanCapturePeriodSecs());
|
assertEquals(42, settings.getQueryPlanCapturePeriodSecs());
|
||||||
assertEquals(560, config.getQueryPlanCaptureMaxTimeMillis());
|
assertEquals(560, settings.getQueryPlanCaptureMaxTimeMillis());
|
||||||
assertEquals(7, config.getQueryPlanCaptureMaxCount());
|
assertEquals(7, settings.getQueryPlanCaptureMaxCount());
|
||||||
|
|
||||||
assertThat(config.getMappingLocations()).containsExactly("classpath:/foo","bar");
|
assertThat(settings.getMappingLocations()).containsExactly("classpath:/foo","bar");
|
||||||
|
|
||||||
|
config.persistBatch(PersistBatch.NONE)
|
||||||
|
.persistBatchOnCascade(PersistBatch.NONE)
|
||||||
|
.lengthCheck(LengthCheck.ON)
|
||||||
|
.lengthCheck(LengthCheck.UTF8);
|
||||||
|
|
||||||
config.setPersistBatch(PersistBatch.NONE);
|
|
||||||
config.setPersistBatchOnCascade(PersistBatch.NONE);
|
|
||||||
|
|
||||||
Properties props1 = new Properties();
|
Properties props1 = new Properties();
|
||||||
props1.setProperty("ebean.persistBatch", "ALL");
|
props1.setProperty("ebean.persistBatch", "ALL");
|
||||||
@@ -137,19 +148,20 @@ class DatabaseConfigTest {
|
|||||||
props1.setProperty("ebean.notifyL2CacheInForeground", "false");
|
props1.setProperty("ebean.notifyL2CacheInForeground", "false");
|
||||||
|
|
||||||
config.loadFromProperties(props1);
|
config.loadFromProperties(props1);
|
||||||
assertFalse(config.isDisableL2Cache());
|
assertFalse(settings.isDisableL2Cache());
|
||||||
assertFalse(config.isNotifyL2CacheInForeground());
|
assertFalse(settings.isNotifyL2CacheInForeground());
|
||||||
|
|
||||||
assertEquals(PersistBatch.ALL, config.getPersistBatch());
|
assertEquals(PersistBatch.ALL, settings.getPersistBatch());
|
||||||
assertEquals(PersistBatch.ALL, config.getPersistBatchOnCascade());
|
assertEquals(PersistBatch.ALL, settings.getPersistBatchOnCascade());
|
||||||
|
assertEquals(LengthCheck.UTF8, settings.getLengthCheck());
|
||||||
|
|
||||||
config.setEnabledL2Regions("r0,orgs");
|
config.setEnabledL2Regions("r0,orgs");
|
||||||
assertEquals("r0,orgs", config.getEnabledL2Regions());
|
assertEquals("r0,orgs", settings.getEnabledL2Regions());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void test_defaults() {
|
void test_defaults() {
|
||||||
DatabaseConfig config = new DatabaseConfig();
|
DatabaseBuilder.Settings config = new DatabaseConfig().settings();
|
||||||
assertTrue(config.isIdGeneratorAutomatic());
|
assertTrue(config.isIdGeneratorAutomatic());
|
||||||
assertTrue(config.isDefaultServer());
|
assertTrue(config.isDefaultServer());
|
||||||
assertFalse(config.isAutoPersistUpdates());
|
assertFalse(config.isAutoPersistUpdates());
|
||||||
@@ -170,6 +182,8 @@ class DatabaseConfigTest {
|
|||||||
assertEquals(600, config.getQueryPlanCapturePeriodSecs());
|
assertEquals(600, config.getQueryPlanCapturePeriodSecs());
|
||||||
assertEquals(10000L, config.getQueryPlanCaptureMaxTimeMillis());
|
assertEquals(10000L, config.getQueryPlanCaptureMaxTimeMillis());
|
||||||
assertEquals(10, config.getQueryPlanCaptureMaxCount());
|
assertEquals(10, config.getQueryPlanCaptureMaxCount());
|
||||||
|
assertThat(config.getLengthCheck()).isEqualTo(LengthCheck.OFF);
|
||||||
|
assertFalse(config.isIncludeLabelInSql());
|
||||||
|
|
||||||
config.setLoadModuleInfo(false);
|
config.setLoadModuleInfo(false);
|
||||||
assertFalse(config.isAutoLoadModuleInfo());
|
assertFalse(config.isAutoLoadModuleInfo());
|
||||||
@@ -184,7 +198,7 @@ class DatabaseConfigTest {
|
|||||||
void test_putServiceObject() {
|
void test_putServiceObject() {
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
DatabaseConfig config = new DatabaseConfig();
|
var config = new DatabaseConfig().settings();
|
||||||
config.putServiceObject(objectMapper);
|
config.putServiceObject(objectMapper);
|
||||||
|
|
||||||
ObjectMapper mapper0 = config.getServiceObject(ObjectMapper.class);
|
ObjectMapper mapper0 = config.getServiceObject(ObjectMapper.class);
|
||||||
|
|||||||
+31
-34
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<name>ebean bom</name>
|
<name>ebean bom</name>
|
||||||
@@ -89,106 +89,103 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean</artifactId>
|
<artifactId>ebean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core-type</artifactId>
|
<artifactId>ebean-core-type</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-joda-time</artifactId>
|
<artifactId>ebean-joda-time</artifactId>
|
||||||
<version>13.18.0</version>
|
<version>14.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-jackson-jsonnode</artifactId>
|
<artifactId>ebean-jackson-jsonnode</artifactId>
|
||||||
<version>13.18.0</version>
|
<version>14.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-jackson-mapper</artifactId>
|
<artifactId>ebean-jackson-mapper</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-ddl-generator</artifactId>
|
<artifactId>ebean-ddl-generator</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-externalmapping-api</artifactId>
|
<artifactId>ebean-externalmapping-api</artifactId>
|
||||||
<version>13.18.0</version>
|
<version>14.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-externalmapping-xml</artifactId>
|
<artifactId>ebean-externalmapping-xml</artifactId>
|
||||||
<version>13.18.0</version>
|
<version>14.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-autotune</artifactId>
|
<artifactId>ebean-autotune</artifactId>
|
||||||
<version>13.18.0</version>
|
<version>14.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-querybean</artifactId>
|
<artifactId>ebean-querybean</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>querybean-generator</artifactId>
|
<artifactId>querybean-generator</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>kotlin-querybean-generator</artifactId>
|
<artifactId>kotlin-querybean-generator</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-test</artifactId>
|
<artifactId>ebean-test</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-redis</artifactId>
|
<artifactId>ebean-redis</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-spring-txn</artifactId>
|
<artifactId>ebean-spring-txn</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- platforms -->
|
<!-- platforms -->
|
||||||
@@ -196,79 +193,79 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-clickhouse</artifactId>
|
<artifactId>ebean-clickhouse</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-db2</artifactId>
|
<artifactId>ebean-db2</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-h2</artifactId>
|
<artifactId>ebean-h2</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-hana</artifactId>
|
<artifactId>ebean-hana</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-mariadb</artifactId>
|
<artifactId>ebean-mariadb</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-mysql</artifactId>
|
<artifactId>ebean-mysql</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-nuodb</artifactId>
|
<artifactId>ebean-nuodb</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-oracle</artifactId>
|
<artifactId>ebean-oracle</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-postgres</artifactId>
|
<artifactId>ebean-postgres</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-postgis</artifactId>
|
<artifactId>ebean-postgis</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-postgis-types</artifactId>
|
<artifactId>ebean-postgis-types</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-sqlite</artifactId>
|
<artifactId>ebean-sqlite</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-sqlserver</artifactId>
|
<artifactId>ebean-sqlserver</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
+3
-10
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>ebean-core-type</artifactId>
|
<artifactId>ebean-core-type</artifactId>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -30,17 +30,10 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.postgresql</groupId>
|
<groupId>org.postgresql</groupId>
|
||||||
<artifactId>postgresql</artifactId>
|
<artifactId>postgresql</artifactId>
|
||||||
<version>42.6.0</version>
|
<version>42.7.2</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.avaje</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>1.1</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -174,4 +174,9 @@ public interface DataBinder {
|
|||||||
*/
|
*/
|
||||||
String popJson();
|
String popJson();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last bound object (e.g. for BindValidation). Note for InputStreams you'll get an InputStreamInfo.
|
||||||
|
*/
|
||||||
|
Object popLastObject();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.ebean.core.type;
|
package io.ebean.core.type;
|
||||||
|
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -12,5 +12,5 @@ public interface ExtraTypeFactory {
|
|||||||
/**
|
/**
|
||||||
* Provide extra types to Ebean.
|
* Provide extra types to Ebean.
|
||||||
*/
|
*/
|
||||||
List<? extends ScalarType<?>> createTypes(DatabaseConfig config, Object objectMapper);
|
List<? extends ScalarType<?>> createTypes(DatabaseBuilder.Settings config, Object objectMapper);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package io.ebean.core.type;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to transports length info of DataBind.setBinaryStream(stream, length) to BindValidation
|
||||||
|
*
|
||||||
|
* @author Roland Praml, FOCONIS AG
|
||||||
|
*/
|
||||||
|
public final class InputStreamInfo {
|
||||||
|
|
||||||
|
private final InputStream stream;
|
||||||
|
private final long length;
|
||||||
|
|
||||||
|
public InputStreamInfo(InputStream stream, long length) {
|
||||||
|
this.stream = stream;
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream stream() {
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long length() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.ebean.core.type;
|
package io.ebean.core.type;
|
||||||
|
|
||||||
import io.avaje.lang.Nullable;
|
import io.avaje.lang.Nullable;
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory to create ScalarTypeSet.
|
* Factory to create ScalarTypeSet.
|
||||||
@@ -12,6 +12,6 @@ public interface ScalarTypeSetFactory {
|
|||||||
* Create the ScalarTypeSet given the config and optional objectMapper.
|
* Create the ScalarTypeSet given the config and optional objectMapper.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
ScalarTypeSet<?> createTypeSet(DatabaseConfig config, @Nullable Object objectMapper);
|
ScalarTypeSet<?> createTypeSet(DatabaseBuilder.Settings config, @Nullable Object objectMapper);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-16
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ebean-parent</artifactId>
|
<artifactId>ebean-parent</artifactId>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>ebean-core</artifactId>
|
<artifactId>ebean-core</artifactId>
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-api</artifactId>
|
<artifactId>ebean-api</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -46,19 +46,19 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-core-type</artifactId>
|
<artifactId>ebean-core-type</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-externalmapping-api</artifactId>
|
<artifactId>ebean-externalmapping-api</artifactId>
|
||||||
<version>13.18.0</version>
|
<version>14.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4-runtime</artifactId>
|
<artifactId>antlr4-runtime</artifactId>
|
||||||
<version>4.8-1</version>
|
<version>4.13.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.postgresql</groupId>
|
<groupId>org.postgresql</groupId>
|
||||||
<artifactId>postgresql</artifactId>
|
<artifactId>postgresql</artifactId>
|
||||||
<version>42.6.0</version>
|
<version>42.7.2</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -159,21 +159,21 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-h2</artifactId>
|
<artifactId>ebean-platform-h2</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-postgres</artifactId>
|
<artifactId>ebean-platform-postgres</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.ebean</groupId>
|
<groupId>io.ebean</groupId>
|
||||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||||
<version>13.23.0-jakarta</version>
|
<version>14.1.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -184,13 +184,6 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.avaje</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>1.1</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.ebeaninternal.api;
|
package io.ebeaninternal.api;
|
||||||
|
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebeaninternal.server.type.GeoTypeBinder;
|
import io.ebeaninternal.server.type.GeoTypeBinder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,5 +11,5 @@ public interface GeoTypeProvider {
|
|||||||
/**
|
/**
|
||||||
* Create a binder for binding geometry types.
|
* Create a binder for binding geometry types.
|
||||||
*/
|
*/
|
||||||
GeoTypeBinder createBinder(DatabaseConfig config);
|
GeoTypeBinder createBinder(DatabaseBuilder.Settings config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public final class LoadBeanRequest extends LoadRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String mode() {
|
private String mode() {
|
||||||
return lazy ? "+lazy" : loadBuffer.isCache() ? "+cache" : "+query";
|
return lazy ? "lazy" : loadBuffer.isCache() ? "cache" : "query";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package io.ebeaninternal.api;
|
|||||||
import io.ebean.CacheMode;
|
import io.ebean.CacheMode;
|
||||||
import io.ebean.bean.BeanCollection;
|
import io.ebean.bean.BeanCollection;
|
||||||
import io.ebean.bean.EntityBean;
|
import io.ebean.bean.EntityBean;
|
||||||
|
import io.ebean.bean.PersistenceContext;
|
||||||
import io.ebeaninternal.server.core.BindPadding;
|
import io.ebeaninternal.server.core.BindPadding;
|
||||||
import io.ebeaninternal.server.core.OrmQueryRequest;
|
import io.ebeaninternal.server.core.OrmQueryRequest;
|
||||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||||
@@ -57,17 +58,22 @@ public final class LoadManyRequest extends LoadRequest {
|
|||||||
return loadContext.fullPath();
|
return loadContext.fullPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Object> parentIdList(SpiEbeanServer server) {
|
private List<Object> parentIdList(SpiEbeanServer server, BeanPropertyAssocMany<?> many, PersistenceContext pc) {
|
||||||
List<Object> idList = new ArrayList<>();
|
final var idList = new ArrayList<>(loadContext.size());
|
||||||
BeanPropertyAssocMany<?> many = many();
|
final var descriptor = many.descriptor();
|
||||||
for (int i = 0; i < loadContext.size(); i++) {
|
for (int i = 0; i < loadContext.size(); i++) {
|
||||||
BeanCollection<?> bc = loadContext.get(i);
|
final BeanCollection<?> bc = loadContext.get(i);
|
||||||
if (bc != null) {
|
if (bc != null) {
|
||||||
if (lazy && !originIncluded && bc == originCollection) {
|
final var parent = bc.owner();
|
||||||
originIncluded = true;
|
final var parentId = descriptor.getId(parent);
|
||||||
}
|
idList.add(parentId);
|
||||||
idList.add(many.parentId(bc.owner()));
|
|
||||||
bc.setLoader(server); // don't use the load buffer again
|
bc.setLoader(server); // don't use the load buffer again
|
||||||
|
if (lazy) {
|
||||||
|
descriptor.contextPutIfAbsent(pc, parentId, parent);
|
||||||
|
if (!originIncluded && bc == originCollection) {
|
||||||
|
originIncluded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (originCollection != null && !originIncluded) {
|
if (originCollection != null && !originIncluded) {
|
||||||
@@ -75,7 +81,7 @@ public final class LoadManyRequest extends LoadRequest {
|
|||||||
idList.add(many.parentId(originCollection.owner()));
|
idList.add(many.parentId(originCollection.owner()));
|
||||||
originCollection.setLoader(server); // don't use the load buffer again
|
originCollection.setLoader(server); // don't use the load buffer again
|
||||||
}
|
}
|
||||||
if (many.targetDescriptor().isPadInExpression()) {
|
if (descriptor.isPadInExpression()) {
|
||||||
BindPadding.padIds(idList);
|
BindPadding.padIds(idList);
|
||||||
}
|
}
|
||||||
return idList;
|
return idList;
|
||||||
@@ -99,9 +105,10 @@ public final class LoadManyRequest extends LoadRequest {
|
|||||||
query.where().raw(extraWhere.replace("${ta}", "t0").replace("${mta}", "int_"));
|
query.where().raw(extraWhere.replace("${ta}", "t0").replace("${mta}", "int_"));
|
||||||
}
|
}
|
||||||
query.setLazyLoadForParents(many);
|
query.setLazyLoadForParents(many);
|
||||||
many.addWhereParentIdIn(query, parentIdList(server), loadContext.isUseDocStore());
|
final var pc = loadContext.persistenceContext();
|
||||||
query.setPersistenceContext(loadContext.persistenceContext());
|
many.addWhereParentIdIn(query, parentIdList(server, many, pc), loadContext.isUseDocStore());
|
||||||
query.setLoadDescription(lazy ? "+lazy" : "+query", description());
|
query.setPersistenceContext(pc);
|
||||||
|
query.setLoadDescription(lazy ? "lazy" : "query", description());
|
||||||
if (lazy) {
|
if (lazy) {
|
||||||
query.setLazyLoadBatchSize(loadContext.batchSize());
|
query.setLazyLoadBatchSize(loadContext.batchSize());
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package io.ebeaninternal.api;
|
|||||||
import io.ebean.TxScope;
|
import io.ebean.TxScope;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used internally to handle the scoping of transactions for methods.
|
* Used internally to handle the scoping of transactions for methods.
|
||||||
@@ -47,6 +49,11 @@ public final class ScopeTrans {
|
|||||||
private boolean nestedCommit;
|
private boolean nestedCommit;
|
||||||
private boolean nestedUseSavepoint;
|
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) {
|
public ScopeTrans(boolean rollbackOnChecked, boolean created, SpiTransaction transaction, TxScope txScope) {
|
||||||
this.rollbackOnChecked = rollbackOnChecked;
|
this.rollbackOnChecked = rollbackOnChecked;
|
||||||
this.created = created;
|
this.created = created;
|
||||||
@@ -218,4 +225,17 @@ public final class ScopeTrans {
|
|||||||
return e instanceof RuntimeException || rollbackOnChecked;
|
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.transaction.TransactionScopeManager;
|
||||||
import io.ebeaninternal.server.util.ArrayStack;
|
import io.ebeaninternal.server.util.ArrayStack;
|
||||||
|
|
||||||
import jakarta.persistence.PersistenceException;
|
import jakarta.persistence.PersistenceException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,4 +172,31 @@ public final class ScopedTransaction extends SpiTransactionProxy {
|
|||||||
return current.caughtThrowable(e);
|
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();
|
SpiTransactionManager transactionManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End the current transaction if it is active.
|
||||||
|
*/
|
||||||
|
void endTransaction();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all the descriptors.
|
* Return all the descriptors.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ public interface SpiExpression extends Expression {
|
|||||||
*
|
*
|
||||||
* @param request the associated request.
|
* @param request the associated request.
|
||||||
*/
|
*/
|
||||||
void addBindValues(SpiExpressionRequest request);
|
void addBindValues(SpiExpressionBind request);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate all the properties/paths associated with this expression.
|
* Validate all the properties/paths associated with this expression.
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package io.ebeaninternal.api;
|
||||||
|
|
||||||
|
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expression bind values capture.
|
||||||
|
*/
|
||||||
|
public interface SpiExpressionBind {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the bean descriptor for the root type.
|
||||||
|
*/
|
||||||
|
BeanDescriptor<?> descriptor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an encryption key to bind to this request.
|
||||||
|
*/
|
||||||
|
void addBindEncryptKey(Object encryptKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a bind value to this request.
|
||||||
|
*/
|
||||||
|
void addBindValue(Object bindValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes a string to use it as exact match in Like clause.
|
||||||
|
*/
|
||||||
|
String escapeLikeString(String value);
|
||||||
|
}
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
package io.ebeaninternal.api;
|
package io.ebeaninternal.api;
|
||||||
|
|
||||||
import io.ebeaninternal.server.core.SpiOrmQueryRequest;
|
import io.ebeaninternal.server.core.SpiOrmQueryRequest;
|
||||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
|
||||||
import io.ebeaninternal.server.expression.platform.DbExpressionHandler;
|
import io.ebeaninternal.server.expression.platform.DbExpressionHandler;
|
||||||
|
import io.ebeaninternal.server.expression.platform.DbExpressionRequest;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request object used for gathering expression sql and bind values.
|
* Request object used for gathering expression sql and bind values.
|
||||||
*/
|
*/
|
||||||
public interface SpiExpressionRequest {
|
public interface SpiExpressionRequest extends SpiExpressionBind, DbExpressionRequest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the DB specific handler for JSON and ARRAY expressions.
|
* Return the DB specific handler for JSON and ARRAY expressions.
|
||||||
@@ -21,11 +21,6 @@ public interface SpiExpressionRequest {
|
|||||||
*/
|
*/
|
||||||
String parseDeploy(String logicalProp);
|
String parseDeploy(String logicalProp);
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the bean descriptor for the root type.
|
|
||||||
*/
|
|
||||||
BeanDescriptor<?> descriptor();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the associated QueryRequest.
|
* Return the associated QueryRequest.
|
||||||
*/
|
*/
|
||||||
@@ -34,11 +29,13 @@ public interface SpiExpressionRequest {
|
|||||||
/**
|
/**
|
||||||
* Append to the expression sql without any parsing.
|
* Append to the expression sql without any parsing.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
SpiExpressionRequest append(String expression);
|
SpiExpressionRequest append(String expression);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append to the expression sql without any parsing.
|
* Append to the expression sql without any parsing.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
SpiExpressionRequest append(char c);
|
SpiExpressionRequest append(char c);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,6 +44,7 @@ public interface SpiExpressionRequest {
|
|||||||
* This is a fast path case when expression is a bean property path and falls back to using parse()
|
* This is a fast path case when expression is a bean property path and falls back to using parse()
|
||||||
* when that isn't the case.
|
* when that isn't the case.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
SpiExpressionRequest property(String expression);
|
SpiExpressionRequest property(String expression);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,16 +52,6 @@ public interface SpiExpressionRequest {
|
|||||||
*/
|
*/
|
||||||
SpiExpressionRequest parse(String expression);
|
SpiExpressionRequest parse(String expression);
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an encryption key to bind to this request.
|
|
||||||
*/
|
|
||||||
void addBindEncryptKey(Object encryptKey);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a bind value to this request.
|
|
||||||
*/
|
|
||||||
void addBindValue(Object bindValue);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the accumulated expression sql for all expressions in this request.
|
* Return the accumulated expression sql for all expressions in this request.
|
||||||
*/
|
*/
|
||||||
@@ -84,11 +72,6 @@ public interface SpiExpressionRequest {
|
|||||||
*/
|
*/
|
||||||
void appendLike(boolean rawLikeExpression);
|
void appendLike(boolean rawLikeExpression);
|
||||||
|
|
||||||
/**
|
|
||||||
* Escapes a string to use it as exact match in Like clause.
|
|
||||||
*/
|
|
||||||
String escapeLikeString(String value);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append IN expression taking into account platform and type support for Multi-value.
|
* Append IN expression taking into account platform and type support for Multi-value.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.api;
|
package io.ebeaninternal.api;
|
||||||
|
|
||||||
|
import io.avaje.lang.Nullable;
|
||||||
import io.ebean.CacheMode;
|
import io.ebean.CacheMode;
|
||||||
import io.ebean.CountDistinctOrder;
|
import io.ebean.CountDistinctOrder;
|
||||||
import io.ebean.ExpressionList;
|
import io.ebean.ExpressionList;
|
||||||
@@ -225,6 +226,11 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
|||||||
*/
|
*/
|
||||||
ProfileLocation profileLocation();
|
ProfileLocation profileLocation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the SQL hint to include in the query.
|
||||||
|
*/
|
||||||
|
String hint();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the label set on the query.
|
* Return the label set on the query.
|
||||||
*/
|
*/
|
||||||
@@ -339,7 +345,7 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
|||||||
/**
|
/**
|
||||||
* Set the on a secondary query given the label, relativePath and profile location of the parent query.
|
* Set the on a secondary query given the label, relativePath and profile location of the parent query.
|
||||||
*/
|
*/
|
||||||
void setProfilePath(String label, String relativePath, ProfileLocation profileLocation);
|
void setProfilePath(String label, String relativePath, @Nullable ProfileLocation profileLocation);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the query mode.
|
* Set the query mode.
|
||||||
@@ -653,6 +659,16 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
|||||||
*/
|
*/
|
||||||
ObjectGraphNode parentNode();
|
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.
|
* Return false when this is a lazy load or refresh query for a bean.
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
package io.ebeaninternal.server.autotune;
|
package io.ebeaninternal.server.autotune;
|
||||||
|
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebeaninternal.api.SpiEbeanServer;
|
import io.ebeaninternal.api.SpiEbeanServer;
|
||||||
|
|
||||||
public interface AutoTuneServiceProvider {
|
public interface AutoTuneServiceProvider {
|
||||||
|
|
||||||
AutoTuneService create(SpiEbeanServer server, DatabaseConfig config);
|
AutoTuneService create(SpiEbeanServer server, DatabaseBuilder config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
package io.ebeaninternal.server.bind;
|
package io.ebeaninternal.server.bind;
|
||||||
|
|
||||||
import io.ebean.core.type.DataBinder;
|
import io.ebean.core.type.DataBinder;
|
||||||
|
import io.ebean.core.type.InputStreamInfo;
|
||||||
import io.ebeaninternal.api.CoreLog;
|
import io.ebeaninternal.api.CoreLog;
|
||||||
import io.ebeaninternal.server.core.timezone.DataTimeZone;
|
import io.ebeaninternal.server.core.timezone.DataTimeZone;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.StringReader;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -23,6 +27,8 @@ public class DataBind implements DataBinder {
|
|||||||
protected int pos;
|
protected int pos;
|
||||||
private String json;
|
private String json;
|
||||||
|
|
||||||
|
private Object lastObject = null;
|
||||||
|
|
||||||
public DataBind(DataTimeZone dataTimeZone, PreparedStatement pstmt, Connection connection) {
|
public DataBind(DataTimeZone dataTimeZone, PreparedStatement pstmt, Connection connection) {
|
||||||
this.dataTimeZone = dataTimeZone;
|
this.dataTimeZone = dataTimeZone;
|
||||||
this.pstmt = pstmt;
|
this.pstmt = pstmt;
|
||||||
@@ -65,16 +71,19 @@ public class DataBind implements DataBinder {
|
|||||||
@Override
|
@Override
|
||||||
public void setObject(Object value) throws SQLException {
|
public void setObject(Object value) throws SQLException {
|
||||||
pstmt.setObject(++pos, value);
|
pstmt.setObject(++pos, value);
|
||||||
|
lastObject = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void setObject(Object value, int sqlType) throws SQLException {
|
public final void setObject(Object value, int sqlType) throws SQLException {
|
||||||
pstmt.setObject(++pos, value, sqlType);
|
pstmt.setObject(++pos, value, sqlType);
|
||||||
|
lastObject = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNull(int jdbcType) throws SQLException {
|
public void setNull(int jdbcType) throws SQLException {
|
||||||
pstmt.setNull(++pos, jdbcType);
|
pstmt.setNull(++pos, jdbcType);
|
||||||
|
lastObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -96,7 +105,7 @@ public class DataBind implements DataBinder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void closeInputStreams() {
|
public void closeInputStreams() {
|
||||||
if (inputStreams != null) {
|
if (inputStreams != null) {
|
||||||
for (InputStream inputStream : inputStreams) {
|
for (InputStream inputStream : inputStreams) {
|
||||||
try {
|
try {
|
||||||
@@ -117,36 +126,43 @@ public class DataBind implements DataBinder {
|
|||||||
@Override
|
@Override
|
||||||
public void setString(String value) throws SQLException {
|
public void setString(String value) throws SQLException {
|
||||||
pstmt.setString(++pos, value);
|
pstmt.setString(++pos, value);
|
||||||
|
lastObject = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void setInt(int value) throws SQLException {
|
public final void setInt(int value) throws SQLException {
|
||||||
pstmt.setInt(++pos, value);
|
pstmt.setInt(++pos, value);
|
||||||
|
lastObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void setLong(long value) throws SQLException {
|
public final void setLong(long value) throws SQLException {
|
||||||
pstmt.setLong(++pos, value);
|
pstmt.setLong(++pos, value);
|
||||||
|
lastObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void setShort(short value) throws SQLException {
|
public final void setShort(short value) throws SQLException {
|
||||||
pstmt.setShort(++pos, value);
|
pstmt.setShort(++pos, value);
|
||||||
|
lastObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void setFloat(float value) throws SQLException {
|
public final void setFloat(float value) throws SQLException {
|
||||||
pstmt.setFloat(++pos, value);
|
pstmt.setFloat(++pos, value);
|
||||||
|
lastObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void setDouble(double value) throws SQLException {
|
public final void setDouble(double value) throws SQLException {
|
||||||
pstmt.setDouble(++pos, value);
|
pstmt.setDouble(++pos, value);
|
||||||
|
lastObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void setBigDecimal(BigDecimal value) throws SQLException {
|
public final void setBigDecimal(BigDecimal value) throws SQLException {
|
||||||
pstmt.setBigDecimal(++pos, value);
|
pstmt.setBigDecimal(++pos, value);
|
||||||
|
lastObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -157,6 +173,7 @@ public class DataBind implements DataBinder {
|
|||||||
} else {
|
} else {
|
||||||
pstmt.setDate(++pos, value);
|
pstmt.setDate(++pos, value);
|
||||||
}
|
}
|
||||||
|
lastObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -167,6 +184,7 @@ public class DataBind implements DataBinder {
|
|||||||
} else {
|
} else {
|
||||||
pstmt.setTimestamp(++pos, value);
|
pstmt.setTimestamp(++pos, value);
|
||||||
}
|
}
|
||||||
|
lastObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -177,26 +195,31 @@ public class DataBind implements DataBinder {
|
|||||||
} else {
|
} else {
|
||||||
pstmt.setTime(++pos, value);
|
pstmt.setTime(++pos, value);
|
||||||
}
|
}
|
||||||
|
lastObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBoolean(boolean value) throws SQLException {
|
public void setBoolean(boolean value) throws SQLException {
|
||||||
pstmt.setBoolean(++pos, value);
|
pstmt.setBoolean(++pos, value);
|
||||||
|
lastObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBytes(byte[] value) throws SQLException {
|
public void setBytes(byte[] value) throws SQLException {
|
||||||
pstmt.setBytes(++pos, value);
|
pstmt.setBytes(++pos, value);
|
||||||
|
lastObject = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setByte(byte value) throws SQLException {
|
public void setByte(byte value) throws SQLException {
|
||||||
pstmt.setByte(++pos, value);
|
pstmt.setByte(++pos, value);
|
||||||
|
lastObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setChar(char value) throws SQLException {
|
public void setChar(char value) throws SQLException {
|
||||||
pstmt.setString(++pos, String.valueOf(value));
|
pstmt.setString(++pos, String.valueOf(value));
|
||||||
|
lastObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -211,21 +234,31 @@ public class DataBind implements DataBinder {
|
|||||||
}
|
}
|
||||||
inputStreams.add(inputStream);
|
inputStreams.add(inputStream);
|
||||||
pstmt.setBinaryStream(++pos, inputStream, length);
|
pstmt.setBinaryStream(++pos, inputStream, length);
|
||||||
|
lastObject = new InputStreamInfo(inputStream, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBlob(byte[] bytes) throws SQLException {
|
public void setBlob(byte[] bytes) throws SQLException {
|
||||||
pstmt.setBinaryStream(++pos, new ByteArrayInputStream(bytes), bytes.length);
|
pstmt.setBinaryStream(++pos, new ByteArrayInputStream(bytes), bytes.length);
|
||||||
|
lastObject = bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setClob(String content) throws SQLException {
|
public void setClob(String content) throws SQLException {
|
||||||
pstmt.setCharacterStream(++pos, new StringReader(content), content.length());
|
pstmt.setCharacterStream(++pos, new StringReader(content), content.length());
|
||||||
|
lastObject = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setArray(String arrayType, Object[] elements) throws SQLException {
|
public void setArray(String arrayType, Object[] elements) throws SQLException {
|
||||||
pstmt.setArray(++pos, connection.createArrayOf(arrayType, elements));
|
pstmt.setArray(++pos, connection.createArrayOf(arrayType, elements));
|
||||||
|
lastObject = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object popLastObject() {
|
||||||
|
Object ret = lastObject;
|
||||||
|
lastObject = null;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -4,7 +4,7 @@ import io.ebean.cache.QueryCacheEntryValidate;
|
|||||||
import io.ebean.cache.ServerCacheFactory;
|
import io.ebean.cache.ServerCacheFactory;
|
||||||
import io.ebean.cache.ServerCacheOptions;
|
import io.ebean.cache.ServerCacheOptions;
|
||||||
import io.ebean.config.CurrentTenantProvider;
|
import io.ebean.config.CurrentTenantProvider;
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebeaninternal.server.cluster.ClusterManager;
|
import io.ebeaninternal.server.cluster.ClusterManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -13,7 +13,7 @@ import io.ebeaninternal.server.cluster.ClusterManager;
|
|||||||
public final class CacheManagerOptions {
|
public final class CacheManagerOptions {
|
||||||
|
|
||||||
private final ClusterManager clusterManager;
|
private final ClusterManager clusterManager;
|
||||||
private final DatabaseConfig databaseConfig;
|
private final DatabaseBuilder.Settings databaseBuilder;
|
||||||
private final boolean localL2Caching;
|
private final boolean localL2Caching;
|
||||||
private CurrentTenantProvider currentTenantProvider;
|
private CurrentTenantProvider currentTenantProvider;
|
||||||
private QueryCacheEntryValidate queryCacheEntryValidate;
|
private QueryCacheEntryValidate queryCacheEntryValidate;
|
||||||
@@ -24,15 +24,15 @@ public final class CacheManagerOptions {
|
|||||||
CacheManagerOptions() {
|
CacheManagerOptions() {
|
||||||
this.localL2Caching = true;
|
this.localL2Caching = true;
|
||||||
this.clusterManager = null;
|
this.clusterManager = null;
|
||||||
this.databaseConfig = null;
|
this.databaseBuilder = null;
|
||||||
this.cacheFactory = new DefaultServerCacheFactory();
|
this.cacheFactory = new DefaultServerCacheFactory();
|
||||||
this.beanDefault = new ServerCacheOptions();
|
this.beanDefault = new ServerCacheOptions();
|
||||||
this.queryDefault = new ServerCacheOptions();
|
this.queryDefault = new ServerCacheOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CacheManagerOptions(ClusterManager clusterManager, DatabaseConfig config, boolean localL2Caching) {
|
public CacheManagerOptions(ClusterManager clusterManager, DatabaseBuilder.Settings config, boolean localL2Caching) {
|
||||||
this.clusterManager = clusterManager;
|
this.clusterManager = clusterManager;
|
||||||
this.databaseConfig = config;
|
this.databaseBuilder = config;
|
||||||
this.localL2Caching = localL2Caching;
|
this.localL2Caching = localL2Caching;
|
||||||
this.currentTenantProvider = config.getCurrentTenantProvider();
|
this.currentTenantProvider = config.getCurrentTenantProvider();
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ public final class CacheManagerOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getServerName() {
|
public String getServerName() {
|
||||||
return (databaseConfig == null) ? "db" : databaseConfig.getName();
|
return (databaseBuilder == null) ? "db" : databaseBuilder.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLocalL2Caching() {
|
public boolean isLocalL2Caching() {
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ package io.ebeaninternal.server.cache;
|
|||||||
import io.ebean.BackgroundExecutor;
|
import io.ebean.BackgroundExecutor;
|
||||||
import io.ebean.cache.ServerCacheFactory;
|
import io.ebean.cache.ServerCacheFactory;
|
||||||
import io.ebean.cache.ServerCachePlugin;
|
import io.ebean.cache.ServerCachePlugin;
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of ServerCachePlugin.
|
* Default implementation of ServerCachePlugin.
|
||||||
@@ -14,7 +14,7 @@ public final class DefaultServerCachePlugin implements ServerCachePlugin {
|
|||||||
* Creates the default ServerCacheFactory.
|
* Creates the default ServerCacheFactory.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ServerCacheFactory create(DatabaseConfig config, BackgroundExecutor executor) {
|
public ServerCacheFactory create(DatabaseBuilder config, BackgroundExecutor executor) {
|
||||||
return new DefaultServerCacheFactory(executor);
|
return new DefaultServerCacheFactory(executor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import io.ebean.Database;
|
|||||||
import io.ebean.config.ContainerConfig;
|
import io.ebean.config.ContainerConfig;
|
||||||
import io.ebeaninternal.server.transaction.RemoteTransactionEvent;
|
import io.ebeaninternal.server.transaction.RemoteTransactionEvent;
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
@@ -20,38 +19,22 @@ public class ClusterManager implements ServerLookup {
|
|||||||
private static final System.Logger clusterLogger = AppLog.getLogger("io.ebean.Cluster");
|
private static final System.Logger clusterLogger = AppLog.getLogger("io.ebean.Cluster");
|
||||||
|
|
||||||
private final ReentrantLock lock = new ReentrantLock();
|
private final ReentrantLock lock = new ReentrantLock();
|
||||||
|
|
||||||
private final ConcurrentHashMap<String, Database> serverMap = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<String, Database> serverMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final Object monitor = new Object();
|
|
||||||
|
|
||||||
private final ClusterBroadcast broadcast;
|
private final ClusterBroadcast broadcast;
|
||||||
|
|
||||||
private boolean started;
|
private boolean started;
|
||||||
|
|
||||||
private boolean shutdown;
|
private boolean shutdown;
|
||||||
|
|
||||||
public ClusterManager(ContainerConfig config) {
|
public ClusterManager(ContainerConfig config) {
|
||||||
ClusterBroadcastFactory factory = createFactory();
|
if (config.isActive()) {
|
||||||
if (factory != null && config.isActive()) {
|
ClusterBroadcastFactory factory = createFactory();
|
||||||
broadcast = factory.create(this, config);
|
broadcast = factory != null ? factory.create(this, config) : null;
|
||||||
} else {
|
} else {
|
||||||
broadcast = null;
|
broadcast = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the ClusterTransportFactory via ServiceLoader.
|
|
||||||
*/
|
|
||||||
private ClusterBroadcastFactory createFactory() {
|
private ClusterBroadcastFactory createFactory() {
|
||||||
|
return ServiceLoader.load(ClusterBroadcastFactory.class).findFirst().orElse(null);
|
||||||
ServiceLoader<ClusterBroadcastFactory> load = ServiceLoader.load(ClusterBroadcastFactory.class);
|
|
||||||
ClusterBroadcastFactory factory = null;
|
|
||||||
Iterator<ClusterBroadcastFactory> iterator = load.iterator();
|
|
||||||
if (iterator.hasNext()) {
|
|
||||||
factory = iterator.next();
|
|
||||||
}
|
|
||||||
return factory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerServer(Database server) {
|
public void registerServer(Database server) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package io.ebeaninternal.server.core;
|
|||||||
|
|
||||||
import io.avaje.classpath.scanner.ClassPathScanner;
|
import io.avaje.classpath.scanner.ClassPathScanner;
|
||||||
import io.avaje.classpath.scanner.ClassPathScannerFactory;
|
import io.avaje.classpath.scanner.ClassPathScannerFactory;
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -16,7 +16,7 @@ public class ClassPathScanners {
|
|||||||
/**
|
/**
|
||||||
* Return the list of ClassPathScanner services using DatabaseConfig service loader.
|
* Return the list of ClassPathScanner services using DatabaseConfig service loader.
|
||||||
*/
|
*/
|
||||||
public static List<ClassPathScanner> find(DatabaseConfig config) {
|
public static List<ClassPathScanner> find(DatabaseBuilder.Settings config) {
|
||||||
List<ClassPathScanner> scanners = new ArrayList<>();
|
List<ClassPathScanner> scanners = new ArrayList<>();
|
||||||
for (ClassPathScannerFactory factory : ServiceLoader.load(ClassPathScannerFactory.class)) {
|
for (ClassPathScannerFactory factory : ServiceLoader.load(ClassPathScannerFactory.class)) {
|
||||||
scanners.add(factory.createScanner(config.getClassLoadConfig().getClassLoader()));
|
scanners.add(factory.createScanner(config.getClassLoadConfig().getClassLoader()));
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package io.ebeaninternal.server.core;
|
||||||
|
|
||||||
|
import io.ebean.ProfileLocation;
|
||||||
|
import io.ebean.bean.ObjectGraphNode;
|
||||||
|
import io.ebean.config.SlowQueryEvent;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Slow query event.
|
||||||
|
*/
|
||||||
|
final class DSlowQueryEvent implements SlowQueryEvent {
|
||||||
|
|
||||||
|
private final String sql;
|
||||||
|
private final long timeMillis;
|
||||||
|
private final int rowCount;
|
||||||
|
private final ObjectGraphNode originNode;
|
||||||
|
private final List<Object> bindParams;
|
||||||
|
private final String label;
|
||||||
|
private final ProfileLocation profileLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct with the SQL and execution time in millis.
|
||||||
|
*/
|
||||||
|
DSlowQueryEvent(String sql, long timeMillis, int rowCount, ObjectGraphNode originNode,
|
||||||
|
List<Object> bindParams, String label, ProfileLocation profileLocation) {
|
||||||
|
this.sql = sql;
|
||||||
|
this.timeMillis = timeMillis;
|
||||||
|
this.rowCount = rowCount;
|
||||||
|
this.originNode = originNode;
|
||||||
|
this.bindParams = bindParams;
|
||||||
|
this.profileLocation = profileLocation;
|
||||||
|
this.label = label != null ? label : profileLocation == null ? null : profileLocation.label();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSql() {
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getTimeMillis() {
|
||||||
|
return timeMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowCount() {
|
||||||
|
return rowCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectGraphNode getOriginNode() {
|
||||||
|
return originNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Object> getBindParams() {
|
||||||
|
return bindParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProfileLocation getProfileLocation() {
|
||||||
|
return profileLocation;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.ebeaninternal.server.core;
|
package io.ebeaninternal.server.core;
|
||||||
|
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||||
import io.ebean.config.dbplatform.DatabasePlatformProvider;
|
import io.ebean.config.dbplatform.DatabasePlatformProvider;
|
||||||
import io.ebeaninternal.api.CoreLog;
|
import io.ebeaninternal.api.CoreLog;
|
||||||
@@ -37,7 +37,7 @@ public class DatabasePlatformFactory {
|
|||||||
/**
|
/**
|
||||||
* Create the appropriate database specific platform.
|
* Create the appropriate database specific platform.
|
||||||
*/
|
*/
|
||||||
public DatabasePlatform create(DatabaseConfig config) {
|
public DatabasePlatform create(DatabaseBuilder.Settings config) {
|
||||||
try {
|
try {
|
||||||
String offlinePlatform = DbOffline.getPlatform();
|
String offlinePlatform = DbOffline.getPlatform();
|
||||||
if (offlinePlatform != null) {
|
if (offlinePlatform != null) {
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ final class DefaultBeanLoader {
|
|||||||
Object parentId = parentDesc.getId(parentBean);
|
Object parentId = parentDesc.getId(parentBean);
|
||||||
if (pc == null) {
|
if (pc == null) {
|
||||||
pc = new DefaultPersistenceContext();
|
pc = new DefaultPersistenceContext();
|
||||||
parentDesc.contextPut(pc, parentId, parentBean);
|
|
||||||
}
|
}
|
||||||
|
parentDesc.contextPutIfAbsent(pc, parentId, parentBean);
|
||||||
boolean useManyIdCache = beanCollection != null && parentDesc.isManyPropCaching() && many.isUseCache();
|
boolean useManyIdCache = beanCollection != null && parentDesc.isManyPropCaching() && many.isUseCache();
|
||||||
if (useManyIdCache) {
|
if (useManyIdCache) {
|
||||||
Boolean readOnly = null;
|
Boolean readOnly = null;
|
||||||
@@ -82,9 +82,9 @@ final class DefaultBeanLoader {
|
|||||||
// populate a new collection
|
// populate a new collection
|
||||||
BeanCollection<?> emptyCollection = many.createEmpty(parentBean);
|
BeanCollection<?> emptyCollection = many.createEmpty(parentBean);
|
||||||
many.setValue(parentBean, emptyCollection);
|
many.setValue(parentBean, emptyCollection);
|
||||||
query.setLoadDescription("+refresh", null);
|
query.setLoadDescription("refresh", null);
|
||||||
} else {
|
} else {
|
||||||
query.setLoadDescription("+lazy", null);
|
query.setLoadDescription("lazy", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
query.select(parentDesc.idBinder().idSelect());
|
query.select(parentDesc.idBinder().idSelect());
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package io.ebeaninternal.server.core;
|
package io.ebeaninternal.server.core;
|
||||||
|
|
||||||
|
import io.ebean.Database;
|
||||||
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebean.config.*;
|
import io.ebean.config.*;
|
||||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||||
import io.ebean.event.ShutdownManager;
|
import io.ebean.event.ShutdownManager;
|
||||||
@@ -12,11 +14,13 @@ import io.ebeaninternal.server.cluster.ClusterManager;
|
|||||||
import io.ebeaninternal.server.core.bootup.BootupClassPathSearch;
|
import io.ebeaninternal.server.core.bootup.BootupClassPathSearch;
|
||||||
import io.ebeaninternal.server.core.bootup.BootupClasses;
|
import io.ebeaninternal.server.core.bootup.BootupClasses;
|
||||||
import io.ebeaninternal.server.executor.DefaultBackgroundExecutor;
|
import io.ebeaninternal.server.executor.DefaultBackgroundExecutor;
|
||||||
|
|
||||||
import jakarta.persistence.PersistenceException;
|
import jakarta.persistence.PersistenceException;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
@@ -32,12 +36,22 @@ public final class DefaultContainer implements SpiContainer {
|
|||||||
|
|
||||||
private final ReentrantLock lock = new ReentrantLock();
|
private final ReentrantLock lock = new ReentrantLock();
|
||||||
private final ClusterManager clusterManager;
|
private final ClusterManager clusterManager;
|
||||||
|
private final List<EntityClassRegister> entityClassRegisters;
|
||||||
|
|
||||||
public DefaultContainer(ContainerConfig containerConfig) {
|
public DefaultContainer(ContainerConfig containerConfig) {
|
||||||
this.clusterManager = new ClusterManager(containerConfig);
|
this.clusterManager = new ClusterManager(containerConfig);
|
||||||
// register so that we can shutdown any Ebean wide
|
// register so that we can shutdown any Ebean wide
|
||||||
// resources such as clustering
|
// resources such as clustering
|
||||||
ShutdownManager.registerContainer(this);
|
ShutdownManager.registerContainer(this);
|
||||||
|
entityClassRegisters = initEntityRegisters();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<EntityClassRegister> initEntityRegisters() {
|
||||||
|
var entityClassRegisters = new ArrayList<EntityClassRegister>();
|
||||||
|
for (EntityClassRegister entityClassRegister : ServiceLoader.load(EntityClassRegister.class)) {
|
||||||
|
entityClassRegisters.add(entityClassRegister);
|
||||||
|
}
|
||||||
|
return entityClassRegisters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -51,13 +65,12 @@ public final class DefaultContainer implements SpiContainer {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public SpiEbeanServer createServer(String name) {
|
public SpiEbeanServer createServer(String name) {
|
||||||
DatabaseConfig config = new DatabaseConfig();
|
var builder = Database.builder().name(name).loadFromProperties();
|
||||||
config.setName(name);
|
return createServer(builder);
|
||||||
config.loadFromProperties();
|
|
||||||
return createServer(config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private SpiBackgroundExecutor createBackgroundExecutor(DatabaseConfig config) {
|
private SpiBackgroundExecutor createBackgroundExecutor(DatabaseBuilder builder) {
|
||||||
|
var config = builder.settings();
|
||||||
String namePrefix = "ebean-" + config.getName();
|
String namePrefix = "ebean-" + config.getName();
|
||||||
int schedulePoolSize = config.getBackgroundExecutorSchedulePoolSize();
|
int schedulePoolSize = config.getBackgroundExecutorSchedulePoolSize();
|
||||||
int shutdownSecs = config.getBackgroundExecutorShutdownSecs();
|
int shutdownSecs = config.getBackgroundExecutorShutdownSecs();
|
||||||
@@ -69,9 +82,10 @@ public final class DefaultContainer implements SpiContainer {
|
|||||||
* Create the implementation from the configuration.
|
* Create the implementation from the configuration.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public SpiEbeanServer createServer(DatabaseConfig config) {
|
public SpiEbeanServer createServer(DatabaseBuilder builder) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
|
var config = builder.settings();
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
applyConfigServices(config);
|
applyConfigServices(config);
|
||||||
setNamingConvention(config);
|
setNamingConvention(config);
|
||||||
@@ -79,7 +93,7 @@ public final class DefaultContainer implements SpiContainer {
|
|||||||
|
|
||||||
boolean online = true;
|
boolean online = true;
|
||||||
if (config.isDocStoreOnly()) {
|
if (config.isDocStoreOnly()) {
|
||||||
config.setDatabasePlatform(new DatabasePlatform());
|
config.databasePlatform(new DatabasePlatform());
|
||||||
} else {
|
} else {
|
||||||
TenantMode tenantMode = config.getTenantMode();
|
TenantMode tenantMode = config.getTenantMode();
|
||||||
if (TenantMode.DB != tenantMode) {
|
if (TenantMode.DB != tenantMode) {
|
||||||
@@ -115,7 +129,7 @@ public final class DefaultContainer implements SpiContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyConfigServices(DatabaseConfig config) {
|
private void applyConfigServices(DatabaseBuilder.Settings config) {
|
||||||
if (config.isDefaultServer()) {
|
if (config.isDefaultServer()) {
|
||||||
for (DatabaseConfigProvider configProvider : ServiceLoader.load(DatabaseConfigProvider.class)) {
|
for (DatabaseConfigProvider configProvider : ServiceLoader.load(DatabaseConfigProvider.class)) {
|
||||||
configProvider.apply(config);
|
configProvider.apply(config);
|
||||||
@@ -123,12 +137,10 @@ public final class DefaultContainer implements SpiContainer {
|
|||||||
}
|
}
|
||||||
if (config.isLoadModuleInfo()) {
|
if (config.isLoadModuleInfo()) {
|
||||||
// auto register entity classes
|
// auto register entity classes
|
||||||
boolean found = false;
|
for (EntityClassRegister loader : entityClassRegisters) {
|
||||||
for (EntityClassRegister loader : ServiceLoader.load(EntityClassRegister.class)) {
|
|
||||||
config.addAll(loader.classesFor(config.getName(), config.isDefaultServer()));
|
config.addAll(loader.classesFor(config.getName(), config.isDefaultServer()));
|
||||||
found = true;
|
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (entityClassRegisters.isEmpty()) {
|
||||||
checkMissingModulePathProvides();
|
checkMissingModulePathProvides();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,7 +170,7 @@ public final class DefaultContainer implements SpiContainer {
|
|||||||
* Get the entities, scalarTypes, Listeners etc combining the class registered
|
* Get the entities, scalarTypes, Listeners etc combining the class registered
|
||||||
* ones with the already created instances.
|
* ones with the already created instances.
|
||||||
*/
|
*/
|
||||||
private BootupClasses bootupClasses(DatabaseConfig config) {
|
private BootupClasses bootupClasses(DatabaseBuilder.Settings config) {
|
||||||
BootupClasses bootup = bootupClasses1(config);
|
BootupClasses bootup = bootupClasses1(config);
|
||||||
bootup.addServerConfigStartup(config.getServerConfigStartupListeners());
|
bootup.addServerConfigStartup(config.getServerConfigStartupListeners());
|
||||||
bootup.runServerConfigStartup(config);
|
bootup.runServerConfigStartup(config);
|
||||||
@@ -176,7 +188,7 @@ public final class DefaultContainer implements SpiContainer {
|
|||||||
/**
|
/**
|
||||||
* Get the class based entities, scalarTypes, Listeners etc.
|
* Get the class based entities, scalarTypes, Listeners etc.
|
||||||
*/
|
*/
|
||||||
private BootupClasses bootupClasses1(DatabaseConfig config) {
|
private BootupClasses bootupClasses1(DatabaseBuilder.Settings config) {
|
||||||
Set<Class<?>> classes = config.classes();
|
Set<Class<?>> classes = config.classes();
|
||||||
if (config.isDisableClasspathSearch() || (classes != null && !classes.isEmpty())) {
|
if (config.isDisableClasspathSearch() || (classes != null && !classes.isEmpty())) {
|
||||||
// use classes we explicitly added via configuration
|
// use classes we explicitly added via configuration
|
||||||
@@ -188,16 +200,16 @@ public final class DefaultContainer implements SpiContainer {
|
|||||||
/**
|
/**
|
||||||
* Set the naming convention to underscore if it has not already been set.
|
* Set the naming convention to underscore if it has not already been set.
|
||||||
*/
|
*/
|
||||||
private void setNamingConvention(DatabaseConfig config) {
|
private void setNamingConvention(DatabaseBuilder.Settings config) {
|
||||||
if (config.getNamingConvention() == null) {
|
if (config.getNamingConvention() == null) {
|
||||||
config.setNamingConvention(new UnderscoreNamingConvention());
|
config.namingConvention(new UnderscoreNamingConvention());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the DatabasePlatform if it has not already been set.
|
* Set the DatabasePlatform if it has not already been set.
|
||||||
*/
|
*/
|
||||||
private void setDatabasePlatform(DatabaseConfig config) {
|
private void setDatabasePlatform(DatabaseBuilder.Settings config) {
|
||||||
DatabasePlatform platform = config.getDatabasePlatform();
|
DatabasePlatform platform = config.getDatabasePlatform();
|
||||||
if (platform == null) {
|
if (platform == null) {
|
||||||
if (config.getTenantMode().isDynamicDataSource()) {
|
if (config.getTenantMode().isDynamicDataSource()) {
|
||||||
@@ -205,7 +217,7 @@ public final class DefaultContainer implements SpiContainer {
|
|||||||
}
|
}
|
||||||
// automatically determine the platform
|
// automatically determine the platform
|
||||||
platform = new DatabasePlatformFactory().create(config);
|
platform = new DatabasePlatformFactory().create(config);
|
||||||
config.setDatabasePlatform(platform);
|
config.databasePlatform(platform);
|
||||||
}
|
}
|
||||||
platform.configure(config.getPlatformConfig());
|
platform.configure(config.getPlatformConfig());
|
||||||
}
|
}
|
||||||
@@ -213,7 +225,7 @@ public final class DefaultContainer implements SpiContainer {
|
|||||||
/**
|
/**
|
||||||
* Set the DataSource if it has not already been set.
|
* Set the DataSource if it has not already been set.
|
||||||
*/
|
*/
|
||||||
private void setDataSource(DatabaseConfig config) {
|
private void setDataSource(DatabaseBuilder.Settings config) {
|
||||||
if (isOfflineMode(config)) {
|
if (isOfflineMode(config)) {
|
||||||
log.log(DEBUG, "... DbOffline using platform [{0}]", DbOffline.getPlatform());
|
log.log(DEBUG, "... DbOffline using platform [{0}]", DbOffline.getPlatform());
|
||||||
} else {
|
} else {
|
||||||
@@ -221,7 +233,7 @@ public final class DefaultContainer implements SpiContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isOfflineMode(DatabaseConfig config) {
|
private boolean isOfflineMode(DatabaseBuilder.Settings config) {
|
||||||
return config.isDbOffline() || DbOffline.isSet();
|
return config.isDbOffline() || DbOffline.isSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,13 +241,11 @@ public final class DefaultContainer implements SpiContainer {
|
|||||||
* Check the autoCommit and Transaction Isolation levels of the DataSource.
|
* Check the autoCommit and Transaction Isolation levels of the DataSource.
|
||||||
* <p>
|
* <p>
|
||||||
* If autoCommit is true this could be a real problem.
|
* If autoCommit is true this could be a real problem.
|
||||||
* </p>
|
|
||||||
* <p>
|
* <p>
|
||||||
* If the Isolation level is not READ_COMMITTED then optimistic concurrency
|
* If the Isolation level is not READ_COMMITTED then optimistic concurrency
|
||||||
* checking may not work as expected.
|
* checking may not work as expected.
|
||||||
* </p>
|
|
||||||
*/
|
*/
|
||||||
private boolean checkDataSource(DatabaseConfig config) {
|
private boolean checkDataSource(DatabaseBuilder.Settings config) {
|
||||||
if (isOfflineMode(config)) {
|
if (isOfflineMode(config)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
|||||||
private static final System.Logger log = CoreLog.internal;
|
private static final System.Logger log = CoreLog.internal;
|
||||||
|
|
||||||
private final ReentrantLock lock = new ReentrantLock();
|
private final ReentrantLock lock = new ReentrantLock();
|
||||||
private final DatabaseConfig config;
|
private final DatabaseBuilder.Settings config;
|
||||||
private final String serverName;
|
private final String serverName;
|
||||||
private final DatabasePlatform databasePlatform;
|
private final DatabasePlatform databasePlatform;
|
||||||
private final TransactionManager transactionManager;
|
private final TransactionManager transactionManager;
|
||||||
@@ -170,7 +170,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
|||||||
/**
|
/**
|
||||||
* Create the CallStackFactory depending if AutoTune is being used.
|
* Create the CallStackFactory depending if AutoTune is being used.
|
||||||
*/
|
*/
|
||||||
private CallOriginFactory initCallStackFactory(DatabaseConfig config) {
|
private CallOriginFactory initCallStackFactory(DatabaseBuilder.Settings config) {
|
||||||
if (!config.getAutoTuneConfig().isActive()) {
|
if (!config.getAutoTuneConfig().isActive()) {
|
||||||
// use a common CallStack for performance as we don't care with no AutoTune
|
// use a common CallStack for performance as we don't care with no AutoTune
|
||||||
return new NoopCallOriginFactory();
|
return new NoopCallOriginFactory();
|
||||||
@@ -224,7 +224,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConfig config() {
|
public DatabaseBuilder.Settings config() {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,16 +756,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
|||||||
currentTransaction().flush();
|
currentTransaction().flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void commitTransaction() {
|
|
||||||
currentTransaction().commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void rollbackTransaction() {
|
|
||||||
currentTransaction().rollback();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endTransaction() {
|
public void endTransaction() {
|
||||||
Transaction transaction = transactionManager.inScope();
|
Transaction transaction = transactionManager.inScope();
|
||||||
@@ -961,7 +951,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
|||||||
}
|
}
|
||||||
if (!query.isRawSql()) {
|
if (!query.isRawSql()) {
|
||||||
query.setDefaultRawSqlIfRequired();
|
query.setDefaultRawSqlIfRequired();
|
||||||
if (query.isAutoTunable() && !autoTuneService.tuneQuery(query)) {
|
if (!query.isAutoTunable() || !autoTuneService.tuneQuery(query)) {
|
||||||
// use deployment FetchType.LAZY/EAGER annotations
|
// use deployment FetchType.LAZY/EAGER annotations
|
||||||
// to define the 'default' select clause
|
// to define the 'default' select clause
|
||||||
query.setDefaultSelectClause();
|
query.setDefaultSelectClause();
|
||||||
@@ -1273,6 +1263,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
|||||||
@Override
|
@Override
|
||||||
public <T> FutureRowCount<T> findFutureCount(SpiQuery<T> query) {
|
public <T> FutureRowCount<T> findFutureCount(SpiQuery<T> query) {
|
||||||
SpiQuery<T> copy = query.copy();
|
SpiQuery<T> copy = query.copy();
|
||||||
|
copy.usingFuture();
|
||||||
boolean createdTransaction = false;
|
boolean createdTransaction = false;
|
||||||
SpiTransaction transaction = query.transaction();
|
SpiTransaction transaction = query.transaction();
|
||||||
if (transaction == null) {
|
if (transaction == null) {
|
||||||
@@ -1291,6 +1282,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
|||||||
@Override
|
@Override
|
||||||
public <T> FutureIds<T> findFutureIds(SpiQuery<T> query) {
|
public <T> FutureIds<T> findFutureIds(SpiQuery<T> query) {
|
||||||
SpiQuery<T> copy = query.copy();
|
SpiQuery<T> copy = query.copy();
|
||||||
|
copy.usingFuture();
|
||||||
boolean createdTransaction = false;
|
boolean createdTransaction = false;
|
||||||
SpiTransaction transaction = query.transaction();
|
SpiTransaction transaction = query.transaction();
|
||||||
if (transaction == null) {
|
if (transaction == null) {
|
||||||
@@ -1309,6 +1301,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
|||||||
@Override
|
@Override
|
||||||
public <T> FutureList<T> findFutureList(SpiQuery<T> query) {
|
public <T> FutureList<T> findFutureList(SpiQuery<T> query) {
|
||||||
SpiQuery<T> spiQuery = query.copy();
|
SpiQuery<T> spiQuery = query.copy();
|
||||||
|
spiQuery.usingFuture();
|
||||||
// FutureList query always run in it's own persistence content
|
// FutureList query always run in it's own persistence content
|
||||||
spiQuery.setPersistenceContext(new DefaultPersistenceContext());
|
spiQuery.setPersistenceContext(new DefaultPersistenceContext());
|
||||||
if (!spiQuery.isDisableReadAudit()) {
|
if (!spiQuery.isDisableReadAudit()) {
|
||||||
@@ -1651,41 +1644,50 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
|||||||
}, transaction);
|
}, transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert the bean.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void insert(Object bean) {
|
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
|
@Override
|
||||||
public void insert(Object bean, @Nullable Transaction transaction) {
|
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
|
@Override
|
||||||
public void insertAll(Collection<?> beans) {
|
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
|
@Override
|
||||||
public void insertAll(@Nullable Collection<?> beans, @Nullable Transaction transaction) {
|
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()) {
|
if (beans == null || beans.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
executeInTrans((txn) -> {
|
executeInTrans((txn) -> {
|
||||||
|
txn.checkBatchEscalationOnCollection();
|
||||||
for (Object bean : beans) {
|
for (Object bean : beans) {
|
||||||
persister.insert(checkEntityBean(bean), txn);
|
persister.insert(checkEntityBean(bean), options, txn);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}, transaction);
|
}, transaction);
|
||||||
@@ -2182,7 +2184,9 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
|||||||
@Override
|
@Override
|
||||||
public void slowQueryCheck(long timeMicros, int rowCount, SpiQuery<?> query) {
|
public void slowQueryCheck(long timeMicros, int rowCount, SpiQuery<?> query) {
|
||||||
if (timeMicros > slowQueryMicros && slowQueryListener != null) {
|
if (timeMicros > slowQueryMicros && slowQueryListener != null) {
|
||||||
slowQueryListener.process(new SlowQueryEvent(query.getGeneratedSql(), timeMicros / 1000L, rowCount, query.parentNode()));
|
List<Object> bindParams = new SlowQueryBindCapture(query).capture();
|
||||||
|
slowQueryListener.process(new DSlowQueryEvent(query.getGeneratedSql(), timeMicros / 1000L, rowCount,
|
||||||
|
query.parentNode(), bindParams, query.label(), query.profileLocation()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package io.ebeaninternal.server.core;
|
package io.ebeaninternal.server.core;
|
||||||
|
|
||||||
import io.avaje.applog.AppLog;
|
import io.avaje.applog.AppLog;
|
||||||
import io.ebean.bean.ObjectGraphNode;
|
import io.ebean.ProfileLocation;
|
||||||
import io.ebean.config.SlowQueryEvent;
|
import io.ebean.config.SlowQueryEvent;
|
||||||
import io.ebean.config.SlowQueryListener;
|
import io.ebean.config.SlowQueryListener;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static java.lang.System.Logger.Level.WARNING;
|
import static java.lang.System.Logger.Level.WARNING;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -16,11 +18,10 @@ final class DefaultSlowQueryListener implements SlowQueryListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(SlowQueryEvent event) {
|
public void process(SlowQueryEvent event) {
|
||||||
String firstStack = "";
|
ProfileLocation profileLocation = event.getProfileLocation();
|
||||||
ObjectGraphNode node = event.getOriginNode();
|
String loc = profileLocation == null ? "" : profileLocation.fullLocation();
|
||||||
if (node != null) {
|
List<Object> bindParams = event.getBindParams();
|
||||||
firstStack = node.origin().top();
|
log.log(WARNING, "Slow query warning - millis:{0} rows:{1} location:{2} sql[{3}] params{4}",
|
||||||
}
|
event.getTimeMillis(), event.getRowCount(), loc, event.getSql(), bindParams);
|
||||||
log.log(WARNING, "Slow query warning - millis:{0} rows:{1} caller[{2}] sql[{3}]", event.getTimeMillis(), event.getRowCount(), firstStack, event.getSql());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
package io.ebeaninternal.server.core;
|
package io.ebeaninternal.server.core;
|
||||||
|
|
||||||
import io.ebean.annotation.Platform;
|
import io.ebean.annotation.Platform;
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebean.datasource.DataSourceAlertFactory;
|
import io.ebean.datasource.*;
|
||||||
import io.ebean.datasource.DataSourceConfig;
|
|
||||||
import io.ebean.datasource.DataSourceFactory;
|
|
||||||
import io.ebean.datasource.DataSourcePoolListener;
|
|
||||||
|
|
||||||
import jakarta.persistence.PersistenceException;
|
import jakarta.persistence.PersistenceException;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
@@ -15,16 +12,16 @@ import javax.sql.DataSource;
|
|||||||
*/
|
*/
|
||||||
final class InitDataSource {
|
final class InitDataSource {
|
||||||
|
|
||||||
private final DatabaseConfig config;
|
private final DatabaseBuilder.Settings config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and set the main DataSource and read-only DataSource.
|
* Create and set the main DataSource and read-only DataSource.
|
||||||
*/
|
*/
|
||||||
static void init(DatabaseConfig config) {
|
static void init(DatabaseBuilder.Settings config) {
|
||||||
new InitDataSource(config).initialise();
|
new InitDataSource(config).initialise();
|
||||||
}
|
}
|
||||||
|
|
||||||
InitDataSource(DatabaseConfig config) {
|
InitDataSource(DatabaseBuilder.Settings config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,19 +38,23 @@ final class InitDataSource {
|
|||||||
* Initialise the "main" read write DataSource from configuration.
|
* Initialise the "main" read write DataSource from configuration.
|
||||||
*/
|
*/
|
||||||
private DataSource initDataSource() {
|
private DataSource initDataSource() {
|
||||||
return createFromConfig(config.getDataSourceConfig(), false);
|
return createFromConfig(config.getDataSourceConfig(), config.readOnlyDatabase(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise the "read only" DataSource from configuration.
|
* Initialise the "read only" DataSource from configuration.
|
||||||
*/
|
*/
|
||||||
private DataSource initReadOnlyDataSource() {
|
private DataSource initReadOnlyDataSource() {
|
||||||
DataSourceConfig roConfig = readOnlyConfig();
|
if (config.readOnlyDatabase()) {
|
||||||
return roConfig == null ? null : createFromConfig(roConfig, true);
|
// using the same DataSource instance
|
||||||
|
return config.getDataSource();
|
||||||
|
}
|
||||||
|
var roConfig = readOnlyConfig();
|
||||||
|
return roConfig == null ? null : createFromConfig(roConfig, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
DataSourceConfig readOnlyConfig() {
|
DataSourceBuilder.Settings readOnlyConfig() {
|
||||||
DataSourceConfig roConfig = config.getReadOnlyDataSourceConfig();
|
var roConfig = config.getReadOnlyDataSourceConfig();
|
||||||
if (roConfig == null) {
|
if (roConfig == null) {
|
||||||
// it has explicitly been set to null, not expected but ok
|
// it has explicitly been set to null, not expected but ok
|
||||||
return null;
|
return null;
|
||||||
@@ -64,11 +65,11 @@ final class InitDataSource {
|
|||||||
// convenient alternate place to set the read-only url
|
// convenient alternate place to set the read-only url
|
||||||
final String readOnlyUrl = config.getDataSourceConfig().getReadOnlyUrl();
|
final String readOnlyUrl = config.getDataSourceConfig().getReadOnlyUrl();
|
||||||
if (urlSet(readOnlyUrl)) {
|
if (urlSet(readOnlyUrl)) {
|
||||||
roConfig.setUrl(readOnlyUrl);
|
roConfig.url(readOnlyUrl);
|
||||||
return roConfig;
|
return roConfig;
|
||||||
}
|
}
|
||||||
if (config.isAutoReadOnlyDataSource()) {
|
if (config.isAutoReadOnlyDataSource()) {
|
||||||
roConfig.setUrl(null); // blank out in case it is "none"
|
roConfig.url(null); // blank out in case it is "none"
|
||||||
return roConfig;
|
return roConfig;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
@@ -79,25 +80,27 @@ final class InitDataSource {
|
|||||||
return url != null && !"none".equalsIgnoreCase(url) && !url.trim().isEmpty();
|
return url != null && !"none".equalsIgnoreCase(url) && !url.trim().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataSource createFromConfig(DataSourceConfig dsConfig, boolean readOnly) {
|
private DataSource createFromConfig(DataSourceBuilder.Settings dsConfig, boolean readOnlyDB, boolean readOnly) {
|
||||||
if (dsConfig == null) {
|
if (dsConfig == null) {
|
||||||
throw new PersistenceException("No DataSourceConfig defined for " + config.getName());
|
throw new PersistenceException("No DataSourceBuilder defined for " + config.getName());
|
||||||
}
|
}
|
||||||
if (dsConfig.isOffline()) {
|
if (dsConfig.isOffline() && config.getDatabasePlatformName() == null) {
|
||||||
if (config.getDatabasePlatformName() == null) {
|
throw new PersistenceException("You MUST specify a DatabasePlatformName on DatabaseConfig when offline");
|
||||||
throw new PersistenceException("You MUST specify a DatabasePlatformName on DatabaseConfig when offline");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attachAlert(dsConfig);
|
attachAlert(dsConfig);
|
||||||
attachListener(dsConfig);
|
attachListener(dsConfig);
|
||||||
|
|
||||||
if (readOnly) {
|
if (readOnlyDB) {
|
||||||
|
dsConfig.autoCommit(true);
|
||||||
|
dsConfig.readOnly(true);
|
||||||
|
} else if (readOnly) {
|
||||||
// setup to use AutoCommit such that we skip explicit commit
|
// setup to use AutoCommit such that we skip explicit commit
|
||||||
dsConfig.setAutoCommit(true);
|
var mainSettings = config.getDataSourceConfig();
|
||||||
dsConfig.setReadOnly(true);
|
dsConfig.autoCommit(true);
|
||||||
dsConfig.setDefaults(config.getDataSourceConfig());
|
dsConfig.readOnly(true);
|
||||||
dsConfig.setIsolationLevel(config.getDataSourceConfig().getIsolationLevel());
|
dsConfig.setDefaults(mainSettings);
|
||||||
|
dsConfig.isolationLevel(mainSettings.getIsolationLevel());
|
||||||
} else if (isPostgresAllQuotedIdentifiers()) {
|
} else if (isPostgresAllQuotedIdentifiers()) {
|
||||||
dsConfig.addProperty("quoteReturningIdentifiers", false);
|
dsConfig.addProperty("quoteReturningIdentifiers", false);
|
||||||
}
|
}
|
||||||
@@ -108,32 +111,32 @@ final class InitDataSource {
|
|||||||
return config.isAllQuotedIdentifiers() && Platform.POSTGRES == config.getDatabasePlatform().platform().base();
|
return config.isAllQuotedIdentifiers() && Platform.POSTGRES == config.getDatabasePlatform().platform().base();
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataSource create(DataSourceConfig dsConfig, boolean readOnly) {
|
private DataSource create(DataSourceBuilder dsConfig, boolean readOnly) {
|
||||||
String poolName = config.getName() + (readOnly ? "-ro" : "");
|
String poolName = config.getName() + (readOnly ? "-ro" : "");
|
||||||
return DataSourceFactory.create(poolName, dsConfig);
|
return dsConfig.name(poolName).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach DataSourceAlert via service loader if present.
|
* Attach DataSourceAlert via service loader if present.
|
||||||
*/
|
*/
|
||||||
private void attachAlert(DataSourceConfig dsConfig) {
|
private void attachAlert(DataSourceBuilder.Settings dsConfig) {
|
||||||
DataSourceAlertFactory alertFactory = config.getServiceObject(DataSourceAlertFactory.class);
|
DataSourceAlertFactory alertFactory = config.getServiceObject(DataSourceAlertFactory.class);
|
||||||
if (alertFactory == null) {
|
if (alertFactory == null) {
|
||||||
alertFactory = ServiceUtil.service(DataSourceAlertFactory.class);
|
alertFactory = ServiceUtil.service(DataSourceAlertFactory.class);
|
||||||
}
|
}
|
||||||
if (alertFactory != null) {
|
if (alertFactory != null) {
|
||||||
dsConfig.setAlert(alertFactory.createAlert());
|
dsConfig.alert(alertFactory.createAlert());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and attach a DataSourcePoolListener if it has been specified via properties and there is not one already attached.
|
* Create and attach a DataSourcePoolListener if it has been specified via properties and there is not one already attached.
|
||||||
*/
|
*/
|
||||||
private void attachListener(DataSourceConfig dsConfig) {
|
private void attachListener(DataSourceBuilder.Settings dsConfig) {
|
||||||
if (dsConfig.getListener() == null) {
|
if (dsConfig.getListener() == null) {
|
||||||
String poolListener = dsConfig.getPoolListener();
|
String poolListener = dsConfig.getPoolListener();
|
||||||
if (poolListener != null) {
|
if (poolListener != null) {
|
||||||
dsConfig.setListener((DataSourcePoolListener) config.getClassLoadConfig().newInstance(poolListener));
|
dsConfig.listener((DataSourcePoolListener) config.getClassLoadConfig().newInstance(poolListener));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
package io.ebeaninternal.server.core;
|
package io.ebeaninternal.server.core;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonFactory;
|
import com.fasterxml.jackson.core.JsonFactory;
|
||||||
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebean.ExpressionFactory;
|
import io.ebean.ExpressionFactory;
|
||||||
import io.ebean.annotation.Platform;
|
import io.ebean.annotation.Platform;
|
||||||
import io.ebean.cache.*;
|
import io.ebean.cache.*;
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.config.*;
|
||||||
import io.ebean.config.ExternalTransactionManager;
|
|
||||||
import io.ebean.config.ProfilingConfig;
|
|
||||||
import io.ebean.config.SlowQueryListener;
|
|
||||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||||
import io.ebean.config.dbplatform.DbHistorySupport;
|
import io.ebean.config.dbplatform.DbHistorySupport;
|
||||||
import io.ebean.event.changelog.ChangeLogListener;
|
import io.ebean.event.changelog.ChangeLogListener;
|
||||||
@@ -71,7 +69,7 @@ public final class InternalConfiguration {
|
|||||||
|
|
||||||
private final TableModState tableModState;
|
private final TableModState tableModState;
|
||||||
private final boolean online;
|
private final boolean online;
|
||||||
private final DatabaseConfig config;
|
private final DatabaseBuilder.Settings config;
|
||||||
private final BootupClasses bootupClasses;
|
private final BootupClasses bootupClasses;
|
||||||
private final DatabasePlatform databasePlatform;
|
private final DatabasePlatform databasePlatform;
|
||||||
private final DeployInherit deployInherit;
|
private final DeployInherit deployInherit;
|
||||||
@@ -100,12 +98,12 @@ public final class InternalConfiguration {
|
|||||||
private boolean localL2Caching;
|
private boolean localL2Caching;
|
||||||
|
|
||||||
InternalConfiguration(boolean online, ClusterManager clusterManager, SpiBackgroundExecutor backgroundExecutor,
|
InternalConfiguration(boolean online, ClusterManager clusterManager, SpiBackgroundExecutor backgroundExecutor,
|
||||||
DatabaseConfig config, BootupClasses bootupClasses) {
|
DatabaseBuilder.Settings config, BootupClasses bootupClasses) {
|
||||||
|
|
||||||
this.online = online;
|
this.online = online;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.jacksonCorePresent = config.getClassLoadConfig().isJacksonCorePresent();
|
this.jacksonCorePresent = config.getClassLoadConfig().isJacksonCorePresent();
|
||||||
this.clockService = new ClockService(config.getClock());
|
this.clockService = new ClockService(config.settings().getClock());
|
||||||
this.tableModState = new TableModState();
|
this.tableModState = new TableModState();
|
||||||
this.logManager = initLogManager();
|
this.logManager = initLogManager();
|
||||||
this.docStoreFactory = initDocStoreFactory(service(DocStoreFactory.class));
|
this.docStoreFactory = initDocStoreFactory(service(DocStoreFactory.class));
|
||||||
@@ -175,7 +173,7 @@ public final class InternalConfiguration {
|
|||||||
/**
|
/**
|
||||||
* Create and return the ExpressionFactory based on configuration and database platform.
|
* Create and return the ExpressionFactory based on configuration and database platform.
|
||||||
*/
|
*/
|
||||||
private ExpressionFactory initExpressionFactory(DatabaseConfig config) {
|
private ExpressionFactory initExpressionFactory(DatabaseBuilder.Settings config) {
|
||||||
boolean nativeIlike = config.isExpressionNativeIlike() && databasePlatform.supportsNativeIlike();
|
boolean nativeIlike = config.isExpressionNativeIlike() && databasePlatform.supportsNativeIlike();
|
||||||
return new DefaultExpressionFactory(config.isExpressionEqualsWithNullAsNoop(), nativeIlike);
|
return new DefaultExpressionFactory(config.isExpressionEqualsWithNullAsNoop(), nativeIlike);
|
||||||
}
|
}
|
||||||
@@ -333,7 +331,7 @@ public final class InternalConfiguration {
|
|||||||
return config.getDatabasePlatform();
|
return config.getDatabasePlatform();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DatabaseConfig getConfig() {
|
public DatabaseBuilder.Settings getConfig() {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,14 +588,16 @@ public final class InternalConfiguration {
|
|||||||
*/
|
*/
|
||||||
QueryPlanLogger queryPlanLogger(Platform platform) {
|
QueryPlanLogger queryPlanLogger(Platform platform) {
|
||||||
switch (platform.base()) {
|
switch (platform.base()) {
|
||||||
case POSTGRES:
|
|
||||||
return new QueryPlanLoggerPostgres();
|
|
||||||
case SQLSERVER:
|
case SQLSERVER:
|
||||||
return new QueryPlanLoggerSqlServer();
|
return new QueryPlanLoggerSqlServer();
|
||||||
case ORACLE:
|
case ORACLE:
|
||||||
return new QueryPlanLoggerOracle();
|
return new QueryPlanLoggerOracle();
|
||||||
|
case POSTGRES:
|
||||||
|
return new QueryPlanLoggerExplain("explain (analyze, buffers) ");
|
||||||
|
case YUGABYTE:
|
||||||
|
return new QueryPlanLoggerExplain("explain (analyze, buffers, dist) ");
|
||||||
default:
|
default:
|
||||||
return new QueryPlanLoggerExplain();
|
return new QueryPlanLoggerExplain("explain ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
|||||||
private final OrmQueryEngine queryEngine;
|
private final OrmQueryEngine queryEngine;
|
||||||
private final SpiQuery<T> query;
|
private final SpiQuery<T> query;
|
||||||
private final BeanFindController finder;
|
private final BeanFindController finder;
|
||||||
private final Boolean readOnly;
|
|
||||||
private LoadContext loadContext;
|
private LoadContext loadContext;
|
||||||
private PersistenceContext persistenceContext;
|
private PersistenceContext persistenceContext;
|
||||||
private HashQuery cacheKey;
|
private HashQuery cacheKey;
|
||||||
@@ -52,7 +51,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
|||||||
this.finder = beanDescriptor.beanFinder();
|
this.finder = beanDescriptor.beanFinder();
|
||||||
this.queryEngine = queryEngine;
|
this.queryEngine = queryEngine;
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.readOnly = query.isReadOnly();
|
|
||||||
this.persistenceContext = query.persistenceContext();
|
this.persistenceContext = query.persistenceContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,13 +133,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
|||||||
return loadContext.secondaryQueriesMinBatchSize();
|
return loadContext.secondaryQueriesMinBatchSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the Normal, sharedInstance, ReadOnly state of this query.
|
|
||||||
*/
|
|
||||||
public Boolean isReadOnly() {
|
|
||||||
return readOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the BeanDescriptor for the associated bean.
|
* Return the BeanDescriptor for the associated bean.
|
||||||
*/
|
*/
|
||||||
@@ -782,4 +773,10 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
|||||||
public int forwardOnlyFetchSize() {
|
public int forwardOnlyFetchSize() {
|
||||||
return queryEngine.forwardOnlyFetchSize();
|
return queryEngine.forwardOnlyFetchSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearContext() {
|
||||||
|
if (!transaction.isAutoPersistUpdates()) {
|
||||||
|
beanDescriptor.contextClear(transaction.persistenceContext());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.ebeaninternal.server.core;
|
package io.ebeaninternal.server.core;
|
||||||
|
|
||||||
|
import io.ebean.InsertOptions;
|
||||||
import io.ebean.ValuePair;
|
import io.ebean.ValuePair;
|
||||||
import io.ebean.annotation.DocStoreMode;
|
import io.ebean.annotation.DocStoreMode;
|
||||||
import io.ebean.bean.EntityBean;
|
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.
|
* Many-to-many intersection table changes that are held for later batch processing.
|
||||||
*/
|
*/
|
||||||
private List<SaveMany> saveMany;
|
private List<SaveMany> saveMany;
|
||||||
|
private InsertOptions insertOptions;
|
||||||
|
|
||||||
public PersistRequestBean(SpiEbeanServer server, T bean, Object parentBean, BeanManager<T> mgr, SpiTransaction t,
|
public PersistRequestBean(SpiEbeanServer server, T bean, Object parentBean, BeanManager<T> mgr, SpiTransaction t,
|
||||||
PersistExecute persistExecute, PersistRequest.Type type, int flags) {
|
PersistExecute persistExecute, PersistRequest.Type type, int flags) {
|
||||||
@@ -380,6 +382,14 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
|||||||
return intercept.dirtyPropertyNames();
|
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.
|
* Return the dirty properties on this request.
|
||||||
*/
|
*/
|
||||||
@@ -865,8 +875,8 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
|||||||
}
|
}
|
||||||
setNotifyCache();
|
setNotifyCache();
|
||||||
boolean isChangeLog = beanDescriptor.isChangeLog();
|
boolean isChangeLog = beanDescriptor.isChangeLog();
|
||||||
if (type == Type.UPDATE && (isChangeLog || notifyCache || docStoreMode == DocStoreMode.UPDATE)) {
|
if (type == Type.UPDATE) {
|
||||||
// get the dirty properties for update notification to the doc store
|
// get the dirty properties for notify cache & orphanRemoval of vanilla collection detection
|
||||||
dirtyProperties = intercept.dirtyProperties();
|
dirtyProperties = intercept.dirtyProperties();
|
||||||
}
|
}
|
||||||
if (isChangeLog) {
|
if (isChangeLog) {
|
||||||
@@ -909,21 +919,27 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void controllerPost() {
|
private void controllerPost() {
|
||||||
switch (type) {
|
boolean old = transaction.isFlushOnQuery();
|
||||||
case INSERT:
|
transaction.setFlushOnQuery(false);
|
||||||
controller.postInsert(this);
|
try {
|
||||||
break;
|
switch (type) {
|
||||||
case UPDATE:
|
case INSERT:
|
||||||
controller.postUpdate(this);
|
controller.postInsert(this);
|
||||||
break;
|
break;
|
||||||
case DELETE_SOFT:
|
case UPDATE:
|
||||||
controller.postSoftDelete(this);
|
controller.postUpdate(this);
|
||||||
break;
|
break;
|
||||||
case DELETE:
|
case DELETE_SOFT:
|
||||||
controller.postDelete(this);
|
controller.postSoftDelete(this);
|
||||||
break;
|
break;
|
||||||
default:
|
case DELETE:
|
||||||
break;
|
controller.postDelete(this);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
transaction.setFlushOnQuery(old);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1408,4 +1424,12 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
|||||||
private void setGeneratedId() {
|
private void setGeneratedId() {
|
||||||
beanDescriptor.setGeneratedId(entityBean, transaction);
|
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
|
@Override
|
||||||
public void postExecute() {
|
public void postExecute() {
|
||||||
|
OrmUpdateType ormUpdateType = ormUpdate.ormUpdateType();
|
||||||
|
if (OrmUpdateType.INSERT != ormUpdateType && !transaction.isAutoPersistUpdates()) {
|
||||||
|
beanDescriptor.contextClear(transaction.persistenceContext());
|
||||||
|
}
|
||||||
if (startNanos > 0) {
|
if (startNanos > 0) {
|
||||||
persistExecute.collectOrmUpdate(label, startNanos);
|
persistExecute.collectOrmUpdate(label, startNanos);
|
||||||
}
|
}
|
||||||
OrmUpdateType ormUpdateType = ormUpdate.ormUpdateType();
|
|
||||||
String tableName = ormUpdate.baseTable();
|
String tableName = ormUpdate.baseTable();
|
||||||
if (transaction.isLogSummary()) {
|
if (transaction.isLogSummary()) {
|
||||||
transaction.logSummary("{0} table[{1}] rows[{2}] bind[{3}]", ormUpdateType, tableName, rowCount, bindLog);
|
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.SpiEbeanServer;
|
||||||
import io.ebeaninternal.api.SpiSqlUpdate;
|
import io.ebeaninternal.api.SpiSqlUpdate;
|
||||||
import io.ebeaninternal.api.SpiTransaction;
|
import io.ebeaninternal.api.SpiTransaction;
|
||||||
|
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||||
import io.ebeaninternal.server.persist.BatchControl;
|
import io.ebeaninternal.server.persist.BatchControl;
|
||||||
import io.ebeaninternal.server.persist.PersistExecute;
|
import io.ebeaninternal.server.persist.PersistExecute;
|
||||||
import io.ebeaninternal.server.persist.TrimLogSql;
|
import io.ebeaninternal.server.persist.TrimLogSql;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persist request specifically for CallableSql.
|
* Persist request specifically for CallableSql.
|
||||||
*/
|
*/
|
||||||
@@ -156,6 +159,14 @@ public final class PersistRequestUpdateSql extends PersistRequest {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void postExecute() {
|
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) {
|
if (startNanos > 0) {
|
||||||
persistExecute.collectSqlUpdate(label, startNanos);
|
persistExecute.collectSqlUpdate(label, startNanos);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
package io.ebeaninternal.server.core;
|
package io.ebeaninternal.server.core;
|
||||||
|
|
||||||
import io.ebean.CallableSql;
|
import io.avaje.lang.Nullable;
|
||||||
import io.ebean.MergeOptions;
|
import io.ebean.*;
|
||||||
import io.ebean.Query;
|
|
||||||
import io.ebean.SqlUpdate;
|
|
||||||
import io.ebean.Transaction;
|
|
||||||
import io.ebean.Update;
|
|
||||||
import io.ebean.bean.EntityBean;
|
import io.ebean.bean.EntityBean;
|
||||||
import io.ebean.meta.MetricVisitor;
|
import io.ebean.meta.MetricVisitor;
|
||||||
import io.ebeaninternal.api.SpiSqlUpdate;
|
import io.ebeaninternal.api.SpiSqlUpdate;
|
||||||
@@ -31,9 +27,9 @@ public interface Persister {
|
|||||||
void update(EntityBean entityBean, Transaction t);
|
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.
|
* 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.
|
* Delete a bean given it's type and id value.
|
||||||
* <p>
|
* <p>
|
||||||
* This will also cascade delete one level of children.
|
* This will also cascade delete one level of children.
|
||||||
* </p>
|
|
||||||
*/
|
*/
|
||||||
int delete(Class<?> beanType, Object id, Transaction transaction, boolean permanent);
|
int delete(Class<?> beanType, Object id, Transaction transaction, boolean permanent);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package io.ebeaninternal.server.core;
|
||||||
|
|
||||||
|
import io.ebeaninternal.api.BindParams;
|
||||||
|
import io.ebeaninternal.api.SpiExpressionBind;
|
||||||
|
import io.ebeaninternal.api.SpiExpressionList;
|
||||||
|
import io.ebeaninternal.api.SpiQuery;
|
||||||
|
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||||
|
import io.ebeaninternal.server.persist.MultiValueWrapper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
final class SlowQueryBindCapture implements SpiExpressionBind {
|
||||||
|
|
||||||
|
private final SpiQuery<?> query;
|
||||||
|
private final List<Object> bindParams = new ArrayList<>();
|
||||||
|
|
||||||
|
SlowQueryBindCapture(SpiQuery<?> query) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Object> capture() {
|
||||||
|
var params = query.bindParams();
|
||||||
|
if (params != null) {
|
||||||
|
var positionedParameters = params.positionedParameters();
|
||||||
|
for (BindParams.Param param : positionedParameters) {
|
||||||
|
if (param.isInParam()) {
|
||||||
|
add(param.inValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Object id = query.getId();
|
||||||
|
if (id != null) {
|
||||||
|
add(id);
|
||||||
|
}
|
||||||
|
SpiExpressionList<?> spiExpressionList = query.whereExpressions();
|
||||||
|
if (spiExpressionList != null) {
|
||||||
|
spiExpressionList.addBindValues(this);
|
||||||
|
}
|
||||||
|
return bindParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void add(Object value) {
|
||||||
|
if (value instanceof MultiValueWrapper) {
|
||||||
|
var mvw = (MultiValueWrapper) value;
|
||||||
|
bindParams.add(mvw.getValues());
|
||||||
|
} else {
|
||||||
|
bindParams.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BeanDescriptor<?> descriptor() {
|
||||||
|
return query.descriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBindValue(Object bindValue) {
|
||||||
|
add(bindValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBindEncryptKey(Object encryptKey) {
|
||||||
|
bindParams.add("*");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeLikeString(String value) {
|
||||||
|
return query.descriptor().ebeanServer().databasePlatform().escapeLikeString(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
package io.ebeaninternal.server.core.bootup;
|
package io.ebeaninternal.server.core.bootup;
|
||||||
|
|
||||||
import io.avaje.classpath.scanner.ClassPathScanner;
|
import io.avaje.classpath.scanner.ClassPathScanner;
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebeaninternal.api.CoreLog;
|
import io.ebeaninternal.api.CoreLog;
|
||||||
import io.ebeaninternal.server.core.ClassPathScanners;
|
import io.ebeaninternal.server.core.ClassPathScanners;
|
||||||
|
|
||||||
@@ -24,11 +24,11 @@ public class BootupClassPathSearch {
|
|||||||
* Search the classPath for the classes we are interested in returning
|
* Search the classPath for the classes we are interested in returning
|
||||||
* them as BootupClasses.
|
* them as BootupClasses.
|
||||||
*/
|
*/
|
||||||
public static BootupClasses search(DatabaseConfig config) {
|
public static BootupClasses search(DatabaseBuilder.Settings config) {
|
||||||
return new BootupClassPathSearch(config).getBootupClasses();
|
return new BootupClassPathSearch(config).getBootupClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
private BootupClassPathSearch(DatabaseConfig config) {
|
private BootupClassPathSearch(DatabaseBuilder.Settings config) {
|
||||||
// find packages defined in ebean.mf resources
|
// find packages defined in ebean.mf resources
|
||||||
Set<String> mfPackages = ManifestReader.create(config.getClassLoadConfig().getClassLoader())
|
Set<String> mfPackages = ManifestReader.create(config.getClassLoadConfig().getClassLoader())
|
||||||
.read("META-INF/ebean.mf")
|
.read("META-INF/ebean.mf")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package io.ebeaninternal.server.core.bootup;
|
package io.ebeaninternal.server.core.bootup;
|
||||||
|
|
||||||
import io.ebean.annotation.DocStore;
|
import io.ebean.annotation.DocStore;
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebean.config.IdGenerator;
|
import io.ebean.config.IdGenerator;
|
||||||
import io.ebean.config.ScalarTypeConverter;
|
import io.ebean.config.ScalarTypeConverter;
|
||||||
import io.ebean.core.type.ScalarType;
|
import io.ebean.core.type.ScalarType;
|
||||||
@@ -91,7 +91,7 @@ public class BootupClasses implements Predicate<Class<?>> {
|
|||||||
/**
|
/**
|
||||||
* Run any ServerConfigStartup listeners.
|
* Run any ServerConfigStartup listeners.
|
||||||
*/
|
*/
|
||||||
public void runServerConfigStartup(DatabaseConfig config) {
|
public void runServerConfigStartup(DatabaseBuilder config) {
|
||||||
for (Class<?> cls : serverConfigStartupCandidates) {
|
for (Class<?> cls : serverConfigStartupCandidates) {
|
||||||
try {
|
try {
|
||||||
ServerConfigStartup newInstance = (ServerConfigStartup) cls.getDeclaredConstructor().newInstance();
|
ServerConfigStartup newInstance = (ServerConfigStartup) cls.getDeclaredConstructor().newInstance();
|
||||||
@@ -172,7 +172,7 @@ public class BootupClasses implements Predicate<Class<?>> {
|
|||||||
add(startupInstances, serverConfigStartupInstances, serverConfigStartupCandidates);
|
add(startupInstances, serverConfigStartupInstances, serverConfigStartupCandidates);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addChangeLogInstances(DatabaseConfig config) {
|
public void addChangeLogInstances(DatabaseBuilder.Settings config) {
|
||||||
readAuditPrepare = config.getReadAuditPrepare();
|
readAuditPrepare = config.getReadAuditPrepare();
|
||||||
readAuditLogger = config.getReadAuditLogger();
|
readAuditLogger = config.getReadAuditLogger();
|
||||||
changeLogPrepare = config.getChangeLogPrepare();
|
changeLogPrepare = config.getChangeLogPrepare();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import io.ebean.*;
|
|||||||
import io.ebean.annotation.DocStoreMode;
|
import io.ebean.annotation.DocStoreMode;
|
||||||
import io.ebean.bean.*;
|
import io.ebean.bean.*;
|
||||||
import io.ebean.cache.QueryCacheEntry;
|
import io.ebean.cache.QueryCacheEntry;
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebean.config.EncryptKey;
|
import io.ebean.config.EncryptKey;
|
||||||
import io.ebean.config.dbplatform.IdType;
|
import io.ebean.config.dbplatform.IdType;
|
||||||
import io.ebean.config.dbplatform.PlatformIdGenerator;
|
import io.ebean.config.dbplatform.PlatformIdGenerator;
|
||||||
@@ -237,7 +237,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
|||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.multiValueSupported = owner.isMultiValueSupported();
|
this.multiValueSupported = owner.isMultiValueSupported();
|
||||||
this.entityType = deploy.getEntityType();
|
this.entityType = deploy.getEntityType();
|
||||||
this.properties = deploy.getProperties();
|
this.properties = deploy.propertyNames();
|
||||||
this.name = InternString.intern(deploy.getName());
|
this.name = InternString.intern(deploy.getName());
|
||||||
this.baseTableAlias = "t0";
|
this.baseTableAlias = "t0";
|
||||||
this.fullName = InternString.intern(deploy.getFullName());
|
this.fullName = InternString.intern(deploy.getFullName());
|
||||||
@@ -278,7 +278,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
|||||||
this.partitionMeta = deploy.getPartitionMeta();
|
this.partitionMeta = deploy.getPartitionMeta();
|
||||||
this.tablespaceMeta = deploy.getTablespaceMeta();
|
this.tablespaceMeta = deploy.getTablespaceMeta();
|
||||||
this.storageEngine = deploy.getStorageEngine();
|
this.storageEngine = deploy.getStorageEngine();
|
||||||
this.autoTunable = beanFinder == null && (entityType == EntityType.ORM || entityType == EntityType.VIEW);
|
this.autoTunable = entityType == EntityType.ORM || entityType == EntityType.VIEW;
|
||||||
// helper object used to derive lists of properties
|
// helper object used to derive lists of properties
|
||||||
DeployBeanPropertyLists listHelper = new DeployBeanPropertyLists(owner, this, deploy);
|
DeployBeanPropertyLists listHelper = new DeployBeanPropertyLists(owner, this, deploy);
|
||||||
this.softDeleteProperty = listHelper.getSoftDeleteProperty();
|
this.softDeleteProperty = listHelper.getSoftDeleteProperty();
|
||||||
@@ -423,7 +423,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
|||||||
/**
|
/**
|
||||||
* Return the DatabaseConfig.
|
* Return the DatabaseConfig.
|
||||||
*/
|
*/
|
||||||
public DatabaseConfig config() {
|
public DatabaseBuilder.Settings config() {
|
||||||
return owner.config();
|
return owner.config();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2056,6 +2056,13 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
|||||||
pc.clear(rootBeanType, idValue);
|
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).
|
* Delete a bean from the persistence context (such that we don't fetch it in the same transaction).
|
||||||
*/
|
*/
|
||||||
|
|||||||
+37
-20
@@ -1,6 +1,7 @@
|
|||||||
package io.ebeaninternal.server.deploy;
|
package io.ebeaninternal.server.deploy;
|
||||||
|
|
||||||
import io.ebean.BackgroundExecutor;
|
import io.ebean.BackgroundExecutor;
|
||||||
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebean.Model;
|
import io.ebean.Model;
|
||||||
import io.ebean.RawSqlBuilder;
|
import io.ebean.RawSqlBuilder;
|
||||||
import io.ebean.annotation.ConstraintMode;
|
import io.ebean.annotation.ConstraintMode;
|
||||||
@@ -78,7 +79,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
|||||||
private final NamingConvention namingConvention;
|
private final NamingConvention namingConvention;
|
||||||
private final DeployCreateProperties createProperties;
|
private final DeployCreateProperties createProperties;
|
||||||
private final BeanManagerFactory beanManagerFactory;
|
private final BeanManagerFactory beanManagerFactory;
|
||||||
private final DatabaseConfig config;
|
private final DatabaseBuilder.Settings config;
|
||||||
private final ChangeLogListener changeLogListener;
|
private final ChangeLogListener changeLogListener;
|
||||||
private final ChangeLogRegister changeLogRegister;
|
private final ChangeLogRegister changeLogRegister;
|
||||||
private final ChangeLogPrepare changeLogPrepare;
|
private final ChangeLogPrepare changeLogPrepare;
|
||||||
@@ -105,6 +106,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
|||||||
private final String asOfViewSuffix;
|
private final String asOfViewSuffix;
|
||||||
private final boolean jacksonCorePresent;
|
private final boolean jacksonCorePresent;
|
||||||
private final int queryPlanTTLSeconds;
|
private final int queryPlanTTLSeconds;
|
||||||
|
private final BindMaxLength bindMaxLength;
|
||||||
private int entityBeanCount;
|
private int entityBeanCount;
|
||||||
private List<BeanDescriptor<?>> immutableDescriptorList;
|
private List<BeanDescriptor<?>> immutableDescriptorList;
|
||||||
/**
|
/**
|
||||||
@@ -159,6 +161,19 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
|||||||
this.changeLogListener = config.changeLogListener(bootupClasses.getChangeLogListener());
|
this.changeLogListener = config.changeLogListener(bootupClasses.getChangeLogListener());
|
||||||
this.changeLogRegister = config.changeLogRegister(bootupClasses.getChangeLogRegister());
|
this.changeLogRegister = config.changeLogRegister(bootupClasses.getChangeLogRegister());
|
||||||
this.jacksonCorePresent = config.isJacksonCorePresent();
|
this.jacksonCorePresent = config.isJacksonCorePresent();
|
||||||
|
this.bindMaxLength = initMaxLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
BindMaxLength initMaxLength() {
|
||||||
|
LengthCheck lengthCheck = this.config.getLengthCheck();
|
||||||
|
switch (lengthCheck) {
|
||||||
|
case OFF:
|
||||||
|
return null;
|
||||||
|
case UTF8:
|
||||||
|
return BindMaxLength.ofUtf8();
|
||||||
|
default:
|
||||||
|
return BindMaxLength.ofStandard();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -195,19 +210,19 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
|||||||
/**
|
/**
|
||||||
* Return the AsOfViewSuffix based on the DbHistorySupport.
|
* Return the AsOfViewSuffix based on the DbHistorySupport.
|
||||||
*/
|
*/
|
||||||
private String asOfViewSuffix(DatabasePlatform databasePlatform, DatabaseConfig serverConfig) {
|
private String asOfViewSuffix(DatabasePlatform databasePlatform, DatabaseBuilder.Settings config) {
|
||||||
DbHistorySupport historySupport = databasePlatform.historySupport();
|
DbHistorySupport historySupport = databasePlatform.historySupport();
|
||||||
// with historySupport returns a simple view suffix or the sql2011 as of timestamp suffix
|
// with historySupport returns a simple view suffix or the sql2011 as of timestamp suffix
|
||||||
return (historySupport == null) ? serverConfig.getAsOfViewSuffix() : historySupport.getAsOfViewSuffix(serverConfig.getAsOfViewSuffix());
|
return (historySupport == null) ? config.getAsOfViewSuffix() : historySupport.getAsOfViewSuffix(config.getAsOfViewSuffix());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the versions between timestamp suffix based on the DbHistorySupport.
|
* Return the versions between timestamp suffix based on the DbHistorySupport.
|
||||||
*/
|
*/
|
||||||
private String versionsBetweenSuffix(DatabasePlatform databasePlatform, DatabaseConfig serverConfig) {
|
private String versionsBetweenSuffix(DatabasePlatform databasePlatform, DatabaseBuilder.Settings config) {
|
||||||
DbHistorySupport historySupport = databasePlatform.historySupport();
|
DbHistorySupport historySupport = databasePlatform.historySupport();
|
||||||
// with historySupport returns a simple view suffix or the sql2011 versions between timestamp suffix
|
// with historySupport returns a simple view suffix or the sql2011 versions between timestamp suffix
|
||||||
return (historySupport == null) ? serverConfig.getAsOfViewSuffix() : historySupport.getVersionsBetweenSuffix(serverConfig.getAsOfViewSuffix());
|
return (historySupport == null) ? config.getAsOfViewSuffix() : historySupport.getVersionsBetweenSuffix(config.getAsOfViewSuffix());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -216,7 +231,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConfig config() {
|
public DatabaseBuilder.Settings config() {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,7 +413,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
|||||||
* Return the BeanDescriptors mapped to the table.
|
* Return the BeanDescriptors mapped to the table.
|
||||||
*/
|
*/
|
||||||
public List<BeanDescriptor<?>> descriptors(String tableName) {
|
public List<BeanDescriptor<?>> descriptors(String tableName) {
|
||||||
return tableToDescMap.get(tableName.toLowerCase());
|
return tableName == null ? Collections.emptyList() : tableToDescMap.get(tableName.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -443,11 +458,10 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
|||||||
// build map of tables to view entities dependent on those tables
|
// build map of tables to view entities dependent on those tables
|
||||||
// for the purpose of invalidating appropriate query caches
|
// for the purpose of invalidating appropriate query caches
|
||||||
String[] dependentTables = desc.dependentTables();
|
String[] dependentTables = desc.dependentTables();
|
||||||
if (dependentTables != null && dependentTables.length > 0) {
|
if (dependentTables != null) {
|
||||||
for (String depTable : dependentTables) {
|
for (String depTable : dependentTables) {
|
||||||
depTable = depTable.toLowerCase();
|
depTable = depTable.toLowerCase();
|
||||||
List<BeanDescriptor<?>> list = tableToViewDescMap.computeIfAbsent(depTable, k -> new ArrayList<>(1));
|
tableToViewDescMap.computeIfAbsent(depTable, k -> new ArrayList<>(1)).add(desc);
|
||||||
list.add(desc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -578,7 +592,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> String errNothingRegistered() {
|
private String errNothingRegistered() {
|
||||||
return "There are no registered entities. If using query beans, that generates EbeanEntityRegister.java into " +
|
return "There are no registered entities. If using query beans, that generates EbeanEntityRegister.java into " +
|
||||||
"generated sources and is service loaded. If using module-info.java, then probably missing 'provides io.ebean.config.EntityClassRegister with EbeanEntityRegister' clause.";
|
"generated sources and is service loaded. If using module-info.java, then probably missing 'provides io.ebean.config.EntityClassRegister with EbeanEntityRegister' clause.";
|
||||||
}
|
}
|
||||||
@@ -1186,7 +1200,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
|||||||
setConcurrencyMode(desc);
|
setConcurrencyMode(desc);
|
||||||
}
|
}
|
||||||
// generate the byte code
|
// generate the byte code
|
||||||
createByteCode(desc);
|
setAccessors(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1255,13 +1269,13 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
|||||||
return databasePlatform.createSequenceIdGenerator(backgroundExecutor, dataSource, stepSize, seqName);
|
return databasePlatform.createSequenceIdGenerator(backgroundExecutor, dataSource, stepSize, seqName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createByteCode(DeployBeanDescriptor<?> deploy) {
|
private void setAccessors(DeployBeanDescriptor<?> deploy) {
|
||||||
// check to see if the bean supports EntityBean interface
|
// check to see if the bean supports EntityBean interface
|
||||||
// generate a subclass if required
|
// generate a subclass if required
|
||||||
setEntityBeanClass(deploy);
|
confirmEnhanced(deploy);
|
||||||
// use Code generation or Standard reflection to support
|
// use Code generation or Standard reflection to support
|
||||||
// getter and setter methods
|
// getter and setter methods
|
||||||
setBeanReflect(deploy);
|
setPropertyAccessors(deploy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1288,15 +1302,14 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
|||||||
* and getting of properties. It is generally faster to use code generation
|
* and getting of properties. It is generally faster to use code generation
|
||||||
* rather than reflection to do this.
|
* rather than reflection to do this.
|
||||||
*/
|
*/
|
||||||
private void setBeanReflect(DeployBeanDescriptor<?> desc) {
|
private void setPropertyAccessors(DeployBeanDescriptor<?> desc) {
|
||||||
// Set the BeanReflectGetter and BeanReflectSetter that typically
|
// Set the BeanReflectGetter and BeanReflectSetter that typically
|
||||||
// use generated code. NB: Due to Bug 166 so now doing this for
|
// use generated code. NB: Due to Bug 166 so now doing this for
|
||||||
// abstract classes as well.
|
// abstract classes as well.
|
||||||
BeanPropertiesReader reflectProps = new BeanPropertiesReader(desc.getBeanType());
|
BeanPropertiesReader reflectProps = new BeanPropertiesReader(desc.propertyNames());
|
||||||
desc.setProperties(reflectProps.getProperties());
|
|
||||||
for (DeployBeanProperty prop : desc.propertiesAll()) {
|
for (DeployBeanProperty prop : desc.propertiesAll()) {
|
||||||
String propName = prop.getName();
|
String propName = prop.getName();
|
||||||
Integer pos = reflectProps.getPropertyIndex(propName);
|
Integer pos = reflectProps.propertyIndex(propName);
|
||||||
if (pos == null) {
|
if (pos == null) {
|
||||||
if (isPersistentField(prop)) {
|
if (isPersistentField(prop)) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
@@ -1368,7 +1381,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
|||||||
/**
|
/**
|
||||||
* Test the bean type to see if it implements EntityBean interface already.
|
* Test the bean type to see if it implements EntityBean interface already.
|
||||||
*/
|
*/
|
||||||
private void setEntityBeanClass(DeployBeanDescriptor<?> desc) {
|
private void confirmEnhanced(DeployBeanDescriptor<?> desc) {
|
||||||
Class<?> beanClass = desc.getBeanType();
|
Class<?> beanClass = desc.getBeanType();
|
||||||
if (!hasEntityBeanInterface(beanClass)) {
|
if (!hasEntityBeanInterface(beanClass)) {
|
||||||
String msg = "Bean " + beanClass + " is not enhanced? Check packages specified in ebean.mf. If you are running in IDEA or " +
|
String msg = "Bean " + beanClass + " is not enhanced? Check packages specified in ebean.mf. If you are running in IDEA or " +
|
||||||
@@ -1502,6 +1515,10 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BindMaxLength bindMaxLength() {
|
||||||
|
return bindMaxLength;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Comparator to sort the BeanDescriptors by name.
|
* Comparator to sort the BeanDescriptors by name.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.ebeaninternal.server.deploy;
|
package io.ebeaninternal.server.deploy;
|
||||||
|
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebean.config.EncryptKey;
|
import io.ebean.config.EncryptKey;
|
||||||
import io.ebean.config.NamingConvention;
|
import io.ebean.config.NamingConvention;
|
||||||
import io.ebean.core.type.ScalarType;
|
import io.ebean.core.type.ScalarType;
|
||||||
@@ -25,7 +25,7 @@ public interface BeanDescriptorMap {
|
|||||||
/**
|
/**
|
||||||
* Return the DatabaseConfig.
|
* Return the DatabaseConfig.
|
||||||
*/
|
*/
|
||||||
DatabaseConfig config();
|
DatabaseBuilder.Settings config();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the Cache Manager.
|
* Return the Cache Manager.
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@ package io.ebeaninternal.server.deploy;
|
|||||||
|
|
||||||
import io.ebean.annotation.PostSoftDelete;
|
import io.ebean.annotation.PostSoftDelete;
|
||||||
import io.ebean.annotation.PreSoftDelete;
|
import io.ebean.annotation.PreSoftDelete;
|
||||||
import io.ebean.config.DatabaseConfig;
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebean.event.BeanPersistAdapter;
|
import io.ebean.event.BeanPersistAdapter;
|
||||||
import io.ebean.event.BeanPersistRequest;
|
import io.ebean.event.BeanPersistRequest;
|
||||||
import io.ebean.event.BeanPostConstructListener;
|
import io.ebean.event.BeanPostConstructListener;
|
||||||
@@ -34,7 +34,7 @@ final class BeanLifecycleAdapterFactory {
|
|||||||
|
|
||||||
private final boolean postConstructPresent;
|
private final boolean postConstructPresent;
|
||||||
|
|
||||||
BeanLifecycleAdapterFactory(DatabaseConfig config) {
|
BeanLifecycleAdapterFactory(DatabaseBuilder.Settings config) {
|
||||||
this.postConstructPresent = config.getClassLoadConfig().isJavaxPostConstructPresent();
|
this.postConstructPresent = config.getClassLoadConfig().isJavaxPostConstructPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.ebeaninternal.server.deploy;
|
package io.ebeaninternal.server.deploy;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonToken;
|
import com.fasterxml.jackson.core.JsonToken;
|
||||||
|
import io.ebean.DataIntegrityException;
|
||||||
import io.ebean.ValuePair;
|
import io.ebean.ValuePair;
|
||||||
import io.ebean.bean.EntityBean;
|
import io.ebean.bean.EntityBean;
|
||||||
import io.ebean.bean.EntityBeanIntercept;
|
import io.ebean.bean.EntityBeanIntercept;
|
||||||
@@ -40,8 +41,8 @@ import io.ebeanservice.docstore.api.mapping.DocMappingBuilder;
|
|||||||
import io.ebeanservice.docstore.api.mapping.DocPropertyMapping;
|
import io.ebeanservice.docstore.api.mapping.DocPropertyMapping;
|
||||||
import io.ebeanservice.docstore.api.mapping.DocPropertyOptions;
|
import io.ebeanservice.docstore.api.mapping.DocPropertyOptions;
|
||||||
import io.ebeanservice.docstore.api.support.DocStructure;
|
import io.ebeanservice.docstore.api.support.DocStructure;
|
||||||
|
|
||||||
import jakarta.persistence.PersistenceException;
|
import jakarta.persistence.PersistenceException;
|
||||||
|
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -166,6 +167,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
|||||||
*/
|
*/
|
||||||
private final String dbComment;
|
private final String dbComment;
|
||||||
private final DbEncryptFunction dbEncryptFunction;
|
private final DbEncryptFunction dbEncryptFunction;
|
||||||
|
private final BindMaxLength bindMaxLength;
|
||||||
private int deployOrder;
|
private int deployOrder;
|
||||||
final boolean jsonSerialize;
|
final boolean jsonSerialize;
|
||||||
final boolean jsonDeserialize;
|
final boolean jsonDeserialize;
|
||||||
@@ -258,6 +260,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
|||||||
}
|
}
|
||||||
this.jsonSerialize = deploy.isJsonSerialize();
|
this.jsonSerialize = deploy.isJsonSerialize();
|
||||||
this.jsonDeserialize = deploy.isJsonDeserialize();
|
this.jsonDeserialize = deploy.isJsonDeserialize();
|
||||||
|
this.bindMaxLength = deploy.bindMaxLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String tableAliasIntern(BeanDescriptor<?> descriptor, String s, boolean dbEncrypted, String dbColumn) {
|
private String tableAliasIntern(BeanDescriptor<?> descriptor, String s, boolean dbEncrypted, String dbColumn) {
|
||||||
@@ -345,6 +348,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
|||||||
this.elPlaceHolderEncrypted = override.replace(source.elPlaceHolderEncrypted, source.dbColumn);
|
this.elPlaceHolderEncrypted = override.replace(source.elPlaceHolderEncrypted, source.dbColumn);
|
||||||
this.jsonSerialize = source.jsonSerialize;
|
this.jsonSerialize = source.jsonSerialize;
|
||||||
this.jsonDeserialize = source.jsonDeserialize;
|
this.jsonDeserialize = source.jsonDeserialize;
|
||||||
|
this.bindMaxLength = source.bindMaxLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -555,6 +559,18 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void bind(DataBind b, Object value) throws SQLException {
|
public void bind(DataBind b, Object value) throws SQLException {
|
||||||
scalarType.bind(b, value);
|
scalarType.bind(b, value);
|
||||||
|
if (bindMaxLength != null) {
|
||||||
|
Object obj = b.popLastObject();
|
||||||
|
long length = bindMaxLength.length(dbLength, obj);
|
||||||
|
if (length > dbLength) {
|
||||||
|
b.closeInputStreams();
|
||||||
|
String s = String.valueOf(value); // take original bind value here.
|
||||||
|
if (s.length() > 50) {
|
||||||
|
s = s.substring(0, 47) + "...";
|
||||||
|
}
|
||||||
|
throw new DataIntegrityException("Cannot bind value '" + s + "' (effective length=" + length + ") to column '" + dbColumn + "' (length=" + dbLength + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings(value = "unchecked")
|
@SuppressWarnings(value = "unchecked")
|
||||||
@@ -1166,14 +1182,14 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
|
|||||||
* Returns true if this <code>isLob()</code> or the type will effectively map to a lob.
|
* Returns true if this <code>isLob()</code> or the type will effectively map to a lob.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isDbLob() {
|
public boolean isLobForPlatform() {
|
||||||
if (lob) {
|
if (lob) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
switch (dbType) {
|
switch (dbType) {
|
||||||
case DbPlatformType.JSON:
|
case DbPlatformType.JSON:
|
||||||
case DbPlatformType.JSONB:
|
case DbPlatformType.JSONB:
|
||||||
return dbLength == 0; // must be analog to DbPlatformTypeMapping.lookup
|
return dbLength == 0 || dbLength > 4000; // must be analog to DbPlatformTypeMapping.lookup
|
||||||
case DbPlatformType.JSONBlob:
|
case DbPlatformType.JSONBlob:
|
||||||
case DbPlatformType.JSONClob:
|
case DbPlatformType.JSONClob:
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -379,6 +379,9 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
|||||||
for (ExportedProperty exportedProperty : exportedProperties) {
|
for (ExportedProperty exportedProperty : exportedProperties) {
|
||||||
row.addColumn(exportedProperty.getForeignDbColumn());
|
row.addColumn(exportedProperty.getForeignDbColumn());
|
||||||
}
|
}
|
||||||
|
if (importedId == null) {
|
||||||
|
throw new PersistenceException("Missing @Id property on bean related to ManyToMany " + fullName());
|
||||||
|
}
|
||||||
importedId.buildImport(row);
|
importedId.buildImport(row);
|
||||||
return row.build();
|
return row.build();
|
||||||
}
|
}
|
||||||
@@ -585,10 +588,9 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the join properties from the parent bean to the child bean.
|
* Set the parent bean to the child (update the relationship).
|
||||||
* This is only valid for OneToMany and NOT valid for ManyToMany.
|
|
||||||
*/
|
*/
|
||||||
public void setJoinValuesToChild(EntityBean parent, EntityBean child, Object mapKeyValue) {
|
public void setParentToChild(EntityBean parent, EntityBean child, Object mapKeyValue) {
|
||||||
if (mapKeyProperty != null) {
|
if (mapKeyProperty != null) {
|
||||||
mapKeyProperty.setValue(child, mapKeyValue);
|
mapKeyProperty.setValue(child, mapKeyValue);
|
||||||
}
|
}
|
||||||
@@ -599,6 +601,31 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the parent bean has been set to the child (updated the relationship).
|
||||||
|
*/
|
||||||
|
public boolean setParentToChild(EntityBean parent, EntityBean child, Object mapKeyValue, BeanDescriptor<?> parentDesc) {
|
||||||
|
if (manyToMany
|
||||||
|
|| childMasterProperty == null
|
||||||
|
|| !child._ebean_getIntercept().isLoadedProperty(childMasterProperty.propertyIndex())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object currentParent = childMasterProperty.getValue(child);
|
||||||
|
if (currentParent != null) {
|
||||||
|
Object newId = parentDesc.getId(parent);
|
||||||
|
Object oldId = parentDesc.id(currentParent);
|
||||||
|
if (Objects.equals(newId, oldId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
childMasterProperty.setValueIntercept(child, parent);
|
||||||
|
if (mapKeyProperty != null) {
|
||||||
|
mapKeyProperty.setValue(child, mapKeyValue);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the order by clause used to order the fetching of the data for
|
* Return the order by clause used to order the fetching of the data for
|
||||||
* this list, set or map.
|
* this list, set or map.
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package io.ebeaninternal.server.deploy;
|
||||||
|
|
||||||
|
import io.ebean.core.type.InputStreamInfo;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The max length check on bind values.
|
||||||
|
*/
|
||||||
|
public interface BindMaxLength {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a UTF8 based implementation.
|
||||||
|
*/
|
||||||
|
static BindMaxLength ofUtf8() {
|
||||||
|
return new UTF8();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a standard implementation.
|
||||||
|
*/
|
||||||
|
static BindMaxLength ofStandard() {
|
||||||
|
return new Standard();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the length of the object.
|
||||||
|
*/
|
||||||
|
long length(int dbLength, Object obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length check based on UTF8 bytes.
|
||||||
|
*/
|
||||||
|
final class UTF8 implements BindMaxLength {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long length(int dbLength, Object obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
return -1;
|
||||||
|
} else if (obj instanceof String) {
|
||||||
|
String s = (String) obj;
|
||||||
|
return utf8String(dbLength, s);
|
||||||
|
} else if (obj instanceof byte[]) {
|
||||||
|
return ((byte[]) obj).length;
|
||||||
|
} else if (obj instanceof InputStreamInfo) {
|
||||||
|
return ((InputStreamInfo) obj).length();
|
||||||
|
} else if ("org.postgresql.util.PGobject".equals(obj.getClass().getCanonicalName())) {
|
||||||
|
String value = ((org.postgresql.util.PGobject) obj).getValue();
|
||||||
|
return value == null ? -1 : utf8String(dbLength, value);
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int utf8String(int dbLength, String s) {
|
||||||
|
int stringLength = s.length();
|
||||||
|
if (stringLength > dbLength) {
|
||||||
|
return stringLength;
|
||||||
|
} else if (stringLength * 4 <= dbLength) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return s.getBytes(StandardCharsets.UTF_8).length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard string length implementation.
|
||||||
|
*/
|
||||||
|
final class Standard implements BindMaxLength {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long length(int dbLength, Object obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
return -1;
|
||||||
|
} else if (obj instanceof String) {
|
||||||
|
return ((String) obj).length();
|
||||||
|
} else if (obj instanceof byte[]) {
|
||||||
|
return ((byte[]) obj).length;
|
||||||
|
} else if (obj instanceof InputStreamInfo) {
|
||||||
|
return ((InputStreamInfo) obj).length();
|
||||||
|
} else if ("org.postgresql.util.PGobject".equals(obj.getClass().getCanonicalName())) {
|
||||||
|
String value = ((org.postgresql.util.PGobject) obj).getValue();
|
||||||
|
return value == null ? -1 : value.length();
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -63,7 +63,7 @@ class DynamicPropertyAggregationFormula extends DynamicPropertyBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDbLob() {
|
public boolean isLobForPlatform() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-5
@@ -1,10 +1,8 @@
|
|||||||
package io.ebeaninternal.server.deploy.generatedproperty;
|
package io.ebeaninternal.server.deploy.generatedproperty;
|
||||||
|
|
||||||
|
import io.ebean.DatabaseBuilder;
|
||||||
import io.ebean.Transaction;
|
import io.ebean.Transaction;
|
||||||
import io.ebean.config.ClassLoadConfig;
|
import io.ebean.config.*;
|
||||||
import io.ebean.config.CurrentUserProvider;
|
|
||||||
import io.ebean.config.DatabaseConfig;
|
|
||||||
import io.ebean.config.IdGenerator;
|
|
||||||
import io.ebean.config.dbplatform.PlatformIdGenerator;
|
import io.ebean.config.dbplatform.PlatformIdGenerator;
|
||||||
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||||
|
|
||||||
@@ -29,7 +27,7 @@ public final class GeneratedPropertyFactory {
|
|||||||
private final ClassLoadConfig classLoadConfig;
|
private final ClassLoadConfig classLoadConfig;
|
||||||
private final Map<String, PlatformIdGenerator> idGeneratorMap = new HashMap<>();
|
private final Map<String, PlatformIdGenerator> idGeneratorMap = new HashMap<>();
|
||||||
|
|
||||||
public GeneratedPropertyFactory(boolean offlineMode, DatabaseConfig config, List<IdGenerator> idGenerators) {
|
public GeneratedPropertyFactory(boolean offlineMode, DatabaseBuilder.Settings config, List<IdGenerator> idGenerators) {
|
||||||
this.classLoadConfig = config.getClassLoadConfig();
|
this.classLoadConfig = config.getClassLoadConfig();
|
||||||
this.insertFactory = new InsertTimestampFactory(classLoadConfig);
|
this.insertFactory = new InsertTimestampFactory(classLoadConfig);
|
||||||
this.updateFactory = new UpdateTimestampFactory(classLoadConfig);
|
this.updateFactory = new UpdateTimestampFactory(classLoadConfig);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package io.ebeaninternal.server.deploy.id;
|
package io.ebeaninternal.server.deploy.id;
|
||||||
|
|
||||||
import io.ebean.bean.EntityBean;
|
import io.ebean.bean.EntityBean;
|
||||||
|
import io.ebeaninternal.api.SpiExpressionBind;
|
||||||
import io.ebeaninternal.api.SpiExpressionRequest;
|
import io.ebeaninternal.api.SpiExpressionRequest;
|
||||||
import io.ebeaninternal.server.core.DefaultSqlUpdate;
|
import io.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||||
@@ -143,7 +144,7 @@ public interface IdBinder {
|
|||||||
/**
|
/**
|
||||||
* Binds multiple id value to a request.
|
* Binds multiple id value to a request.
|
||||||
*/
|
*/
|
||||||
void addBindValues(SpiExpressionRequest request, Collection<?> ids);
|
void addBindValues(SpiExpressionBind request, Collection<?> ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the sql for binding the id using an IN clause.
|
* Return the sql for binding the id using an IN clause.
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user