mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
348
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5414fa17cf | ||
|
|
807b017463 | ||
|
|
6c7cedc1f1 | ||
|
|
01155c3466 | ||
|
|
c297ebda5a | ||
|
|
cec7492c10 | ||
|
|
4252445eb4 | ||
|
|
a23f241fff | ||
|
|
d145e6494d | ||
|
|
2563d52ecf | ||
|
|
8632aef268 | ||
|
|
f827a292ff | ||
|
|
a027c630b1 | ||
|
|
ab1a49abee | ||
|
|
bc5cf0e326 | ||
|
|
348535ec6c | ||
|
|
273f994cdf | ||
|
|
c0a3f7e05d | ||
|
|
1bc9bab988 | ||
|
|
dc730fd97b | ||
|
|
6c15115530 | ||
|
|
841b268fc7 | ||
|
|
6c8db9dec7 | ||
|
|
51d2f52d19 | ||
|
|
ff45f9ab63 | ||
|
|
507027df0a | ||
|
|
50d45c6da9 | ||
|
|
f5e9356451 | ||
|
|
dfe46cc011 | ||
|
|
34cdbc5620 | ||
|
|
595c057964 | ||
|
|
73bc9e516e | ||
|
|
6a4cfb231d | ||
|
|
4523db85c3 | ||
|
|
d703709f14 | ||
|
|
e8afba7ed2 | ||
|
|
dd5bb3edff | ||
|
|
475b05052e | ||
|
|
4cc012b974 | ||
|
|
c214fe52f0 | ||
|
|
4f57bd3511 | ||
|
|
82dc2d031a | ||
|
|
a831ee9ac9 | ||
|
|
e01b20aecb | ||
|
|
58713c7083 | ||
|
|
2df6f2e5fb | ||
|
|
19724e71db | ||
|
|
1a74c7ca85 | ||
|
|
0356f595c8 | ||
|
|
b12a9adf46 | ||
|
|
2b874189a2 | ||
|
|
f2d95cf012 | ||
|
|
d4825cd72c | ||
|
|
c7bd6c8bde | ||
|
|
c9b3a91539 | ||
|
|
565f6c5ac6 | ||
|
|
356b5e58d9 | ||
|
|
094fc3f4b8 | ||
|
|
cfb9d860f9 | ||
|
|
2f7b553d7c | ||
|
|
ec9481420c | ||
|
|
797e1f4bd2 | ||
|
|
a14507e563 | ||
|
|
732f0e13e2 | ||
|
|
a6304ebe8b | ||
|
|
4050d5e900 | ||
|
|
87cc95f60d | ||
|
|
e8d663c94e | ||
|
|
effcb86174 | ||
|
|
7e50e6e427 | ||
|
|
47b940f672 | ||
|
|
01d5aa8199 | ||
|
|
7474430a63 | ||
|
|
ed830aeb0c | ||
|
|
54cbdae22d | ||
|
|
bb77d6588a | ||
|
|
f930471beb | ||
|
|
3a84e4183d | ||
|
|
d12dc9bfed | ||
|
|
5f689dee1b | ||
|
|
08d3a3b2f5 | ||
|
|
4ed5f91963 | ||
|
|
f36e4543ee | ||
|
|
37f92bf967 | ||
|
|
eb14531b66 | ||
|
|
6c1a3647f9 | ||
|
|
fa9e9be003 | ||
|
|
02ead0bcdb | ||
|
|
892e7bc84a | ||
|
|
4bdcd49eab | ||
|
|
7a0de51721 | ||
|
|
0ea44b36dc | ||
|
|
35e1aa2737 | ||
|
|
dab428ead5 | ||
|
|
dbcc779731 | ||
|
|
3c2b5f253f | ||
|
|
31c20ca9a2 | ||
|
|
0100d024d9 | ||
|
|
7a6d91c2f4 | ||
|
|
31ac0f794f | ||
|
|
648bdf4553 | ||
|
|
bda0786924 | ||
|
|
64311b2b9d | ||
|
|
743acf1f30 | ||
|
|
74fef50b67 | ||
|
|
185404a537 | ||
|
|
ced5bb1089 | ||
|
|
52759e0510 | ||
|
|
7db2210ba4 | ||
|
|
9b80dd97c9 | ||
|
|
23ca0e716c | ||
|
|
eac03a0721 | ||
|
|
cf8f099447 | ||
|
|
6698dda8ae | ||
|
|
1cb011df5b | ||
|
|
ac1e1757e8 | ||
|
|
48404fc85d | ||
|
|
9252e72581 | ||
|
|
64f99f5205 | ||
|
|
a5e3b9e68a | ||
|
|
4b43751512 | ||
|
|
1d9db88050 | ||
|
|
5f6efd29ef | ||
|
|
110bc614e4 | ||
|
|
ec89d31a32 | ||
|
|
fbae9cad8a | ||
|
|
fdfe2533c9 | ||
|
|
7e3d39ac1a | ||
|
|
ce19837649 | ||
|
|
11e20edb59 | ||
|
|
88b6a60feb | ||
|
|
43dac07d5b | ||
|
|
04434215d0 | ||
|
|
52e6c0c625 | ||
|
|
745fbe883e | ||
|
|
283e0b66fa | ||
|
|
523deb20f4 | ||
|
|
23d52ca192 | ||
|
|
d20d276d56 | ||
|
|
5b92ac6e02 | ||
|
|
6392f90f32 | ||
|
|
bb8f3831b8 | ||
|
|
4bb43814b7 | ||
|
|
95c1554642 | ||
|
|
2cd59c5166 | ||
|
|
2d65a3f1c9 | ||
|
|
afdb1df7ce | ||
|
|
fa6fdf124d | ||
|
|
1e044f03ed | ||
|
|
7989fcd6ce | ||
|
|
a5256df6f2 | ||
|
|
fa11dac2b2 | ||
|
|
c40ca2fad7 | ||
|
|
5b9359f509 | ||
|
|
403556d8b2 | ||
|
|
06ad2edfc1 | ||
|
|
16e2489ba0 | ||
|
|
162b3449e8 | ||
|
|
8c3ed6996e | ||
|
|
583c5f74eb | ||
|
|
ab047996d2 | ||
|
|
239f87bb5d | ||
|
|
5be3b7717c | ||
|
|
e29d83a379 | ||
|
|
8301fd5e74 | ||
|
|
3e3647816d | ||
|
|
9aa7ae79e2 | ||
|
|
168c940b79 | ||
|
|
1ee18a1823 | ||
|
|
c02ab7340c | ||
|
|
c67773505d | ||
|
|
9c354919e5 | ||
|
|
c8be59fd95 | ||
|
|
d1a40b4739 | ||
|
|
bb9cfe9d0f | ||
|
|
ede2ad4d54 | ||
|
|
1060503fe1 | ||
|
|
2edfc33d00 | ||
|
|
37902c75eb | ||
|
|
14abb34739 | ||
|
|
68680ffd34 | ||
|
|
8106ffd73d | ||
|
|
d00cb854fc | ||
|
|
ca445b5226 | ||
|
|
74b4994221 | ||
|
|
62106935f4 | ||
|
|
bf034eb2a1 | ||
|
|
c5e980991e | ||
|
|
1004675a0b | ||
|
|
12e508ab48 | ||
|
|
be0e1116a7 | ||
|
|
4b03c8a00a | ||
|
|
0db93bc82d | ||
|
|
e04a1baabe | ||
|
|
506e2f5625 | ||
|
|
7fbc1f8111 | ||
|
|
4f3c9adf6f | ||
|
|
ceac2d12b1 | ||
|
|
cc7f3d49a4 | ||
|
|
091c40867e | ||
|
|
71b7aa5946 | ||
|
|
9dea51b7a0 | ||
|
|
b7d6374370 | ||
|
|
195cb9c86c | ||
|
|
1329a4775c | ||
|
|
cc91ca5c2a | ||
|
|
c863fe7781 | ||
|
|
8dec17c1f3 | ||
|
|
36d589d4f3 | ||
|
|
dedafa0b93 | ||
|
|
7b91b9ec48 | ||
|
|
c5940dacf1 | ||
|
|
a4df643d82 | ||
|
|
74174444bb | ||
|
|
317ad8de9c | ||
|
|
4b260483ce | ||
|
|
6a575cb1bf | ||
|
|
a13e1cf074 | ||
|
|
c59475084a | ||
|
|
f41704b58c | ||
|
|
5bb9745b3c | ||
|
|
1c072f1d0a | ||
|
|
bac7eb11bd | ||
|
|
a8c2e4db3f | ||
|
|
67a4e66b00 | ||
|
|
0d1d212f9f | ||
|
|
f44c77f5f5 | ||
|
|
65d07f4af9 | ||
|
|
c74de4c221 | ||
|
|
ebbef86def | ||
|
|
3fab465a13 | ||
|
|
ff662bff58 | ||
|
|
cc7acd4761 | ||
|
|
1365e39e94 | ||
|
|
a73eb1c42f | ||
|
|
3f5a610df1 | ||
|
|
d96e28991c | ||
|
|
e84d12dad8 | ||
|
|
1d4f2ad856 | ||
|
|
84042397b6 | ||
|
|
a70461d779 | ||
|
|
d1b5400f2c | ||
|
|
244f336f54 | ||
|
|
f92887b2f0 | ||
|
|
f49b93a845 | ||
|
|
a6f3a4f922 | ||
|
|
d6a65e4e66 | ||
|
|
ea5b4e9271 | ||
|
|
ffa50b3176 | ||
|
|
2cf83278ea | ||
|
|
5c332286b6 | ||
|
|
1cd319c495 | ||
|
|
cec8a2e482 | ||
|
|
d036edf7fd | ||
|
|
2fefb5c7ef | ||
|
|
4278aa46f5 | ||
|
|
7873a2b327 | ||
|
|
9d3a3ddfeb | ||
|
|
ac0b9aa025 | ||
|
|
4d4f8e2c4b | ||
|
|
2b581fb148 | ||
|
|
35bd98c14f | ||
|
|
8db9991ea3 | ||
|
|
fac69f75d0 | ||
|
|
b18226711b | ||
|
|
4bdb48d340 | ||
|
|
d2a742fefb | ||
|
|
22de23ddf4 | ||
|
|
496d9674d2 | ||
|
|
4ece9fe6cc | ||
|
|
62f162e4fb | ||
|
|
38803aa7f8 | ||
|
|
f9943f14b7 | ||
|
|
1b24c888ee | ||
|
|
45233e96ab | ||
|
|
517556bfe3 | ||
|
|
07101d1528 | ||
|
|
9fa1def22b | ||
|
|
dd9d49cfa2 | ||
|
|
7680a75ca9 | ||
|
|
786286421d | ||
|
|
b517551352 | ||
|
|
507ba7da1c | ||
|
|
835796f614 | ||
|
|
ab9a6fb69a | ||
|
|
4d7a3d135c | ||
|
|
937b15c07a | ||
|
|
47cf81fef9 | ||
|
|
b21123343f | ||
|
|
303f63fe5e | ||
|
|
59d12c908c | ||
|
|
e736263148 | ||
|
|
72712c0e46 | ||
|
|
5245ef597d | ||
|
|
9d2621d353 | ||
|
|
015ef0289f | ||
|
|
5b9ca2933f | ||
|
|
4ba23ebc22 | ||
|
|
cacbee5fd5 | ||
|
|
e1b9bf62a3 | ||
|
|
4d21fbfcf8 | ||
|
|
76b02ff56a | ||
|
|
356af08f68 | ||
|
|
846afba724 | ||
|
|
d34da06840 | ||
|
|
50e13c4c99 | ||
|
|
30ec3145ed | ||
|
|
e20a2269ae | ||
|
|
d6ee67cf4e | ||
|
|
3bcb891133 | ||
|
|
a270caf605 | ||
|
|
aaade167e1 | ||
|
|
ffb292dcd5 | ||
|
|
2e799be9e3 | ||
|
|
3863fa5fc6 | ||
|
|
2490562918 | ||
|
|
d6fe60bb33 | ||
|
|
a4fc61549f | ||
|
|
354b76e698 | ||
|
|
f01e60094f | ||
|
|
956ebf173e | ||
|
|
c4eece36d3 | ||
|
|
385867b9f5 | ||
|
|
4b30c51ff4 | ||
|
|
0969e1427b | ||
|
|
b2349bb044 | ||
|
|
c766756efe | ||
|
|
0e6c6965f0 | ||
|
|
7a17cd0797 | ||
|
|
56acac9f08 | ||
|
|
756e3e4a1c | ||
|
|
669d004d1b | ||
|
|
67fc7cdb48 | ||
|
|
8432fa1320 | ||
|
|
6b81dbbaa2 | ||
|
|
9862526352 | ||
|
|
0e548ec1c5 | ||
|
|
493e2d7463 | ||
|
|
ea30c1d43b | ||
|
|
8c800e992d | ||
|
|
d348794d92 | ||
|
|
526e476ba1 | ||
|
|
45003b3d5f | ||
|
|
3179aa23ea | ||
|
|
bed4721823 | ||
|
|
307832edae | ||
|
|
1f684107b6 | ||
|
|
5ab02715ef |
@@ -36,5 +36,5 @@ jobs:
|
||||
# - name: Maven single test
|
||||
# run: mvn --batch-mode clean verify -Dtest="io.ebeaninternal.server.core.DefaultServer_getReferenceTest" -DfailIfNoTests=false
|
||||
- name: Build with Maven
|
||||
run: mvn clean package
|
||||
run: mvn -T 8 clean test
|
||||
|
||||
|
||||
@@ -35,4 +35,4 @@ jobs:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: db2
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-db2.properties
|
||||
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-db2.properties
|
||||
|
||||
@@ -37,5 +37,5 @@ jobs:
|
||||
- name: Maven version
|
||||
run: mvn --version
|
||||
- name: H2Database
|
||||
run: mvn clean package
|
||||
run: mvn -T 8 clean package
|
||||
|
||||
|
||||
@@ -35,5 +35,5 @@ jobs:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: Build with Maven
|
||||
run: mvn package
|
||||
run: mvn -T 8 test
|
||||
|
||||
|
||||
@@ -16,9 +16,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
## valhalla - failing on javadoc with:
|
||||
## javadoc: error - The code being documented uses packages in the unnamed module, but the packages defined in https://ebean.io/platforms/ebean-platform-h2/apidocs/ are in named modules.
|
||||
java_version: [17,18,19,loom,metropolis,panama]
|
||||
java_version: [GA,EA]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
@@ -36,6 +34,8 @@ jobs:
|
||||
path:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: Maven version
|
||||
run: mvn --version
|
||||
- name: Build with Maven
|
||||
run: mvn package
|
||||
run: mvn -T 8 test
|
||||
|
||||
|
||||
@@ -35,4 +35,4 @@ jobs:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: mariadb 10.6
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-mariadb.properties
|
||||
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-mariadb.properties
|
||||
|
||||
@@ -35,4 +35,4 @@ jobs:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: mysql
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-mysql.properties
|
||||
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-mysql.properties
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
name: Oracle18
|
||||
name: Oracle
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -35,4 +35,4 @@ jobs:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: oracle
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-oracle.properties
|
||||
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-oracle.properties
|
||||
@@ -35,4 +35,4 @@ jobs:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: postgres
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-postgres.properties
|
||||
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-postgres.properties
|
||||
|
||||
@@ -35,4 +35,4 @@ jobs:
|
||||
~/.m2
|
||||
key: build-${{ env.cache-name }}
|
||||
- name: sqlserver 2017
|
||||
run: mvn clean test -Dprops.file=testconfig/ebean-sqlserver17.properties
|
||||
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-sqlserver17.properties
|
||||
|
||||
@@ -1,26 +1,56 @@
|
||||
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/build.yml)
|
||||
[](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean)
|
||||
[](https://github.com/ebean-orm/ebean/blob/master/LICENSE)
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/multi-jdk-build.yml)
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/jdk-18-ea.yml)
|
||||
|
||||
##### Build with database platforms
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/h2database.yml)
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/postgres.yml)
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/mysql.yml)
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/mariadb.yml)
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/oracle.yml)
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/sqlserver.yml)
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/yugabyte.yml)
|
||||
|
||||
|
||||
#### Builds against EA (Early Access) versions of Java (19, Loom, panama etc)
|
||||
|
||||
##### Build with Java Early Access versions
|
||||
[](https://github.com/ebean-orm/ebean/actions/workflows/jdk-ea.yml)
|
||||
[](https://github.com/ebean-orm/ebean-datasource/actions/workflows/jdk-ea.yml)
|
||||
[](https://github.com/ebean-orm/ebean-migration/actions/workflows/jdk-ea.yml)
|
||||
[](https://github.com/ebean-orm/ebean-test-docker/actions/workflows/jdk-ea.yml)
|
||||
[](https://github.com/ebean-orm/ebean-agent/actions/workflows/jdk-ea.yml)
|
||||
|
||||
----------------------
|
||||
|
||||
# Ebean ORM for Java & Kotlin
|
||||
|
||||
**Multiple abstraction levels**: Ebean provides multiple levels of query abstraction [ORM Queries, mixed with SQL](https://ebean.io/docs/intro/queries/orm-query), [DTO Queries](https://ebean.io/docs/intro/queries/dto-query), [SqlQuery and JDBC](https://ebean.io/docs/intro/queries/sql-query).
|
||||
Work at the highest level of abstraction and drop down levels as needed.
|
||||
|
||||
**Database migrations**: Built in [DB migration](https://ebean.io/docs/db-migrations/) generation and running. Support for "rebase" migrations as well as repeatable, init and 'normal' migrations.
|
||||
|
||||
**Awesome SQL**: Ebean produces SQL that you would hand craft yourself. Use great SQL, never generate SQL cartesian product, always honor relational limit/offset.
|
||||
|
||||
**Automated query tuning**: For ORM queries Ebean can profile the object graph being used and either [automatically tune the query](https://ebean.io/docs/query/background/autotune).
|
||||
|
||||
**Docker test containers**: [Docker test containers](https://ebean.io/docs/testing/) for all the supported databases. Get 100% test coverage on all the features of the database we use.
|
||||
|
||||
**Type safe queries**: We can build queries using type safe [query beans](https://ebean.io/docs/query/query-beans). IDE auto-complete when writing queries, compile time checking and it's FUN.
|
||||
|
||||
**Performance isn't optional**: Optimise queries to only fetch what we need (partial objects). Automatically avoid N+1 via a smart load context.
|
||||
|
||||
#### Benefits of ORM
|
||||
|
||||
* Automatically avoid N+1
|
||||
* L2 caching to reduce database load
|
||||
* Queries mixing database and L2 cache
|
||||
* Automatically tune ORM queries
|
||||
* Elasticsearch for search or L3 cache
|
||||
|
||||
|
||||
----------------------
|
||||
# Sponsors
|
||||
<table>
|
||||
<tbody>
|
||||
@@ -50,14 +80,44 @@
|
||||
</table>
|
||||
|
||||
## Need help?
|
||||
Post questions or issues to the Ebean google group - https://groups.google.com/forum/#!forum/ebean
|
||||
Post questions or issues to the [Ebean google group](https://groups.google.com/forum/#!forum/ebean)
|
||||
or [github discussions](https://github.com/ebean-orm/ebean/discussions)
|
||||
|
||||
## Documentation
|
||||
Goto [https://ebean.io/docs/](https://ebean.io/docs/)
|
||||
|
||||
|
||||
## Maven central
|
||||
[Maven central - io.ebean](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22io.ebean%22%20)
|
||||
[Maven central - g:io.ebean](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22io.ebean%22%20)
|
||||
|
||||
## Building Ebean from source
|
||||
|
||||
- JDK 11 or higher installed
|
||||
- Maven installed
|
||||
- `git clone git@github.com:ebean-orm/ebean.git`
|
||||
- `mvn clean install`
|
||||
|
||||
Ebean 13 uses Java modules with module-info. This means that there are stricter compilation
|
||||
rules in place now than when building with classpath pre version 13.
|
||||
|
||||
For Maven Surefire testing we use `<surefire.useModulePath>false</surefire.useModulePath>` such
|
||||
that tests run using classpath and not module-path. We are doing this until all the tooling
|
||||
(Maven, IDE) improves in the area of testing with module-info.
|
||||
|
||||
#### Eclipse IDE
|
||||
|
||||
Right now we can't use Eclipse IDE to build Ebean and run its tests due to its poor support
|
||||
for java modules. See [ebean/issues/2653](https://github.com/ebean-orm/ebean/issues/2653)
|
||||
|
||||
The current recommendation is to use IntelliJ IDEA as the IDE to build and hack Ebean.
|
||||
|
||||
|
||||
#### IntelliJ IDEA
|
||||
|
||||
We want to get IntelliJ to run tests using classpath similar to Maven Surefire. To do this set:
|
||||
`JUnit -> modify options -> Do not use module-path option`
|
||||
|
||||
To set this option as the global default for IntelliJ use:
|
||||
|
||||
`Run - Edit Configurations -> Edit configuration templates -> JUnit -> modify options - Do not use module-path option`
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-clickhouse</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-clickhouse</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-cockroach</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-db2</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-db2</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-h2</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-hana</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-hana</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-mariadb</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mariadb</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-mysql</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mysql</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-nuodb</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-nuodb</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-oracle</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-oracle</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-postgres</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-sqlite</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlite</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-sqlserver</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-yugabyte</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean (all platforms)</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-all</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>composites</artifactId>
|
||||
|
||||
+43
-14
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean api</name>
|
||||
@@ -13,21 +13,23 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!--
|
||||
Projects are expected to explicit depend on version
|
||||
of slf4j that they want to use
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.30</version>
|
||||
<scope>provided</scope>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-applog</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- exclude avaje-applog-slf4j to direct logging to something else -->
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-applog-slf4j</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-config</artifactId>
|
||||
<version>1.7</version>
|
||||
<version>2.2</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
@@ -37,25 +39,25 @@
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-lang</artifactId>
|
||||
<version>1.0</version>
|
||||
<version>1.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>persistence-api</artifactId>
|
||||
<version>2.2.5</version>
|
||||
<version>${ebean-persistence-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-annotation</artifactId>
|
||||
<version>8.0</version>
|
||||
<version>${ebean-annotation.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-types</artifactId>
|
||||
<version>2.2</version>
|
||||
<version>${ebean-types.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -64,6 +66,14 @@
|
||||
<version>${ebean-datasource.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Support MdcBackgroundExecutorWrapper -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.36</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Jackson core used internally by Ebean -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
@@ -103,4 +113,23 @@
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<includes>
|
||||
<include>**/ebean-maven-version.txt</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>false</filtering>
|
||||
<excludes>
|
||||
<exclude>**/ebean-maven-version.txt</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -39,26 +39,6 @@ public interface BackgroundExecutor {
|
||||
*/
|
||||
void execute(Runnable task);
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to scheduleWithFixedDelay().
|
||||
* Execute a task periodically with a fixed delay between each execution.
|
||||
* <p>
|
||||
* For example, execute a runnable every minute.
|
||||
* <p>
|
||||
* The delay is the time between executions no matter how long the task took.
|
||||
* That is, this method has the same behaviour characteristics as
|
||||
* {@link ScheduledExecutorService#scheduleWithFixedDelay(Runnable, long, long, TimeUnit)}
|
||||
*/
|
||||
@Deprecated
|
||||
void executePeriodically(Runnable task, long delay, TimeUnit unit);
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to scheduleWithFixedDelay().
|
||||
* Execute a task periodically additionally with an initial delay different from delay.
|
||||
*/
|
||||
@Deprecated
|
||||
void executePeriodically(Runnable task, long initialDelay, long delay, TimeUnit unit);
|
||||
|
||||
/**
|
||||
* Execute a task periodically with a given delay.
|
||||
*
|
||||
|
||||
@@ -12,6 +12,7 @@ import java.util.Optional;
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* @Component
|
||||
* public class CustomerFinder extends BeanFinder<Long,Customer> {
|
||||
*
|
||||
* @Inject
|
||||
@@ -26,29 +27,37 @@ import java.util.Optional;
|
||||
*
|
||||
* @param <I> The ID type
|
||||
* @param <T> The Bean type
|
||||
*
|
||||
* @see BeanRepository
|
||||
*/
|
||||
@NonNullApi
|
||||
public abstract class BeanFinder<I,T> {
|
||||
|
||||
/**
|
||||
* Migrate to using database rather than server.
|
||||
*/
|
||||
@Deprecated
|
||||
protected final Database server;
|
||||
protected final Database database;
|
||||
protected final Class<T> type;
|
||||
|
||||
/**
|
||||
* Create with the given bean type and Database instance.
|
||||
*
|
||||
* @param type The bean type
|
||||
* @param server The Database instance typically created via Spring factory or equivalent.
|
||||
* @param database The Database instance typically created via Spring factory or equivalent.
|
||||
*/
|
||||
protected BeanFinder(Class<T> type, Database server) {
|
||||
protected BeanFinder(Class<T> type, Database database) {
|
||||
this.type = type;
|
||||
this.server = server;
|
||||
this.database = database;
|
||||
this.server = database;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Database to use.
|
||||
*/
|
||||
public Database db() {
|
||||
return server;
|
||||
return database;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,10 +79,10 @@ public abstract class BeanFinder<I,T> {
|
||||
* <p>
|
||||
* This is equivalent to {@link DB#byName(String)}
|
||||
*
|
||||
* @param server The name of the Database. If this is null then the default Database is returned.
|
||||
* @param name The name of the Database. If this is null then the default Database is returned.
|
||||
*/
|
||||
public Database db(String server) {
|
||||
return DB.byName(server);
|
||||
public Database db(String name) {
|
||||
return DB.byName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,11 +6,15 @@ import io.ebean.bean.EntityBean;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Provides finder functionality for use with "Dependency Injection style" use of Ebean.
|
||||
* Provides find and persist functionality for use with "Dependency Injection style" use of Ebean.
|
||||
* <p>
|
||||
* Extend the BeanRepository with additional finder and persisting methods as needed by the
|
||||
* application. The intention is to keep all the related logic together, for example, all the
|
||||
* persisting and finding logic for Customer would be in CustomerRepository.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* @Repository
|
||||
* @Component
|
||||
* public class CustomerRepository extends BeanRepository<Long,Customer> {
|
||||
*
|
||||
* @Inject
|
||||
@@ -50,10 +54,10 @@ public abstract class BeanRepository<I, T> extends BeanFinder<I, T> {
|
||||
* }</pre>
|
||||
*
|
||||
* @param type The bean type
|
||||
* @param server The Database instance typically created via Spring factory or equivalent
|
||||
* @param database The Database instance typically created via Spring factory or equivalent
|
||||
*/
|
||||
protected BeanRepository(Class<T> type, Database server) {
|
||||
super(type, server);
|
||||
protected BeanRepository(Class<T> type, Database database) {
|
||||
super(type, database);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,8 +126,8 @@ public abstract class BeanRepository<I, T> extends BeanFinder<I, T> {
|
||||
/**
|
||||
* Save all the beans in the collection.
|
||||
*/
|
||||
public int saveAll(Collection<T> bean) {
|
||||
return db().saveAll(bean);
|
||||
public int saveAll(Collection<T> beans) {
|
||||
return db().saveAll(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -238,7 +238,7 @@ public final class DB {
|
||||
}
|
||||
|
||||
/**
|
||||
* The batch will be flushing automatically but you can use this to explicitly
|
||||
* The batch will be flushing automatically but, you can use this to explicitly
|
||||
* flush the batch if you like.
|
||||
* <p>
|
||||
* Flushing occurs automatically when:
|
||||
@@ -961,7 +961,7 @@ public final class DB {
|
||||
*
|
||||
* DB.execute(scope, new TxRunnable() {
|
||||
* public void run() {
|
||||
* User u1 = DB.find(User.class, 1);
|
||||
* User u1 = DB.find(User.class, 1);
|
||||
* ...
|
||||
* }
|
||||
* });
|
||||
@@ -1010,9 +1010,9 @@ public final class DB {
|
||||
*
|
||||
* DB.executeCall(scope, new Callable<String>() {
|
||||
* public String call() {
|
||||
* User u1 = DB.find(User.class, 1);
|
||||
* ...
|
||||
* return u1.getEmail();
|
||||
* User u1 = DB.find(User.class, 1);
|
||||
* ...
|
||||
* return u1.getEmail();
|
||||
* }
|
||||
* });
|
||||
* }</pre>
|
||||
|
||||
@@ -30,10 +30,8 @@ import java.util.concurrent.Callable;
|
||||
* singleton (see {@link DatabaseConfig#setRegister(boolean)}). The DB
|
||||
* singleton is essentially a map of Database's that have been registered
|
||||
* with it.
|
||||
* </p>
|
||||
* <p>
|
||||
* The Database can then be retrieved later via {@link DB#byName(String)}.
|
||||
* </p>
|
||||
*
|
||||
* <h5>The 'default' Database</h5>
|
||||
* <p>
|
||||
@@ -41,18 +39,15 @@ import java.util.concurrent.Callable;
|
||||
* (see {@link DatabaseConfig#setDefaultServer(boolean)}. Many methods on DB
|
||||
* such as {@link DB#find(Class)} etc are actually just a convenient way to
|
||||
* call methods on the 'default/primary' Database.
|
||||
* </p>
|
||||
*
|
||||
* <h5>Constructing a Database</h5>
|
||||
* <p>
|
||||
* Database's 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
|
||||
* can be automatically constructed on demand using configuration information in
|
||||
* the application.properties file.
|
||||
* </p>
|
||||
*
|
||||
* <h5>Example: Get a Database</h5>
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // Get access to the Human Resources Database
|
||||
@@ -71,22 +66,19 @@ import java.util.concurrent.Callable;
|
||||
*
|
||||
* <h5>Database vs DB API</h5>
|
||||
* <p>
|
||||
* Database provides additional API compared with DB. For example it
|
||||
* Database provides additional API compared with DB. For example, it
|
||||
* provides more control over the use of Transactions that is not available in
|
||||
* the DB API.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* <em>External Transactions:</em> If you wanted to use transactions created
|
||||
* externally to Ebean then Database provides additional methods where you
|
||||
* can explicitly pass a transaction (that can be created externally).
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* <em>Bypass ThreadLocal Mechanism:</em> If you want to bypass the built in
|
||||
* <em>Bypass ThreadLocal Mechanism:</em> If you want to bypass the built-in
|
||||
* ThreadLocal transaction management you can use the createTransaction()
|
||||
* method. Example: a single thread requires more than one transaction.
|
||||
* </p>
|
||||
*
|
||||
* @see DB
|
||||
* @see DatabaseFactory
|
||||
@@ -104,12 +96,10 @@ public interface Database {
|
||||
* Shutdown the Database instance programmatically.
|
||||
* <p>
|
||||
* This method is not normally required. Ebean registers a shutdown hook and shuts down cleanly.
|
||||
* </p>
|
||||
* <p>
|
||||
* If the under underlying DataSource is the Ebean implementation then you
|
||||
* also have the option of shutting down the DataSource and deregistering the
|
||||
* also have the option of shutting down the DataSource and de-registering the
|
||||
* JDBC driver.
|
||||
* </p>
|
||||
*
|
||||
* @param shutdownDataSource if true then shutdown the underlying DataSource if it is the Ebean
|
||||
* DataSource implementation.
|
||||
@@ -155,10 +145,10 @@ public interface Database {
|
||||
* <p>
|
||||
* Note many platforms have multiple specific platform types so often we want to
|
||||
* get the base platform via {@link Platform#base()}.
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* Platform platform = database.getPlatform().base();
|
||||
* Platform platform = database.platform().base();
|
||||
* if (platform == Platform.MYSQL) {
|
||||
* // do MySql specific function
|
||||
* }
|
||||
@@ -178,7 +168,6 @@ public interface Database {
|
||||
* Return the BeanState for a given entity bean.
|
||||
* <p>
|
||||
* This will return null if the bean is not an enhanced entity bean.
|
||||
* </p>
|
||||
*/
|
||||
BeanState beanState(Object bean);
|
||||
|
||||
@@ -192,7 +181,6 @@ public interface Database {
|
||||
* <p>
|
||||
* For example, if the id value passed in is a String but ought to be a Long or UUID etc
|
||||
* then it will automatically be converted.
|
||||
* </p>
|
||||
*
|
||||
* @param bean The entity bean to set the id value on.
|
||||
* @param id The id value to set.
|
||||
@@ -204,7 +192,6 @@ public interface Database {
|
||||
* <p>
|
||||
* When null is passed in for b, then the 'OldValues' of a is used for the
|
||||
* difference comparison.
|
||||
* </p>
|
||||
*/
|
||||
Map<String, ValuePair> diff(Object newBean, Object oldBean);
|
||||
|
||||
@@ -214,7 +201,6 @@ public interface Database {
|
||||
* Useful if you use BeanPostConstructListeners or @PostConstruct Annotations.
|
||||
* In this case you should not use "new Bean...()". Making all bean constructors protected
|
||||
* could be a good idea here.
|
||||
* </p>
|
||||
*/
|
||||
<T> T createEntityBean(Class<T> type);
|
||||
|
||||
@@ -248,7 +234,6 @@ public interface Database {
|
||||
* Create a named query.
|
||||
* <p>
|
||||
* For RawSql the named query is expected to be in ebean.xml.
|
||||
* </p>
|
||||
*
|
||||
* @param beanType The type of entity bean
|
||||
* @param namedQuery The name of the query
|
||||
@@ -304,17 +289,14 @@ public interface Database {
|
||||
* <p>
|
||||
* You can use the methods on the Query object to specify fetch paths,
|
||||
* predicates, order by, limits etc.
|
||||
* </p>
|
||||
* <p>
|
||||
* You then use findList(), findSet(), findMap() and findOne() to execute
|
||||
* the query and return the collection or bean.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that a query executed by {@link Query#findList()}
|
||||
* {@link Query#findSet()} etc will execute against the same Database from
|
||||
* which is was created.
|
||||
* </p>
|
||||
* <p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* // Find order 2 specifying explicitly the parts of the object graph to
|
||||
@@ -344,7 +326,7 @@ public interface Database {
|
||||
* Create a query using native SQL.
|
||||
* <p>
|
||||
* The native SQL can contain named parameters or positioned parameters.
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = "select c.id, c.name from customer c where c.name like ? order by c.name";
|
||||
@@ -367,12 +349,10 @@ public interface Database {
|
||||
* <p>
|
||||
* This will only work when a IdGenerator is on the bean such as for beans
|
||||
* that use a DB sequence or UUID.
|
||||
* </p>
|
||||
* <p>
|
||||
* For DB's supporting getGeneratedKeys and sequences such as Oracle10 you do
|
||||
* not need to use this method generally. It is made available for more
|
||||
* complex cases where it is useful to get an ID prior to some processing.
|
||||
* </p>
|
||||
*/
|
||||
Object nextId(Class<?> beanType);
|
||||
|
||||
@@ -381,10 +361,8 @@ public interface Database {
|
||||
* going back to the database.
|
||||
* <p>
|
||||
* This produces and returns a new list with the sort and filters applied.
|
||||
* </p>
|
||||
* <p>
|
||||
* Refer to {@link Filter} for an example of its use.
|
||||
* </p>
|
||||
*/
|
||||
<T> Filter<T> filter(Class<T> beanType);
|
||||
|
||||
@@ -401,12 +379,10 @@ public interface Database {
|
||||
* <p>
|
||||
* If you leave off any keywords the defaults are ascending order and treating
|
||||
* nulls as high values.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that the sorting uses a Comparator and Collections.sort(); and does
|
||||
* not invoke a DB query.
|
||||
* </p>
|
||||
* <p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* // find orders and their customers
|
||||
@@ -431,17 +407,15 @@ public interface Database {
|
||||
<T> void sort(List<T> list, String sortByClause);
|
||||
|
||||
/**
|
||||
* Create a orm update where you will supply the insert/update or delete
|
||||
* Create an orm update where you will supply the insert/update or delete
|
||||
* statement (rather than using a named one that is already defined using the
|
||||
* @NamedUpdates annotation).
|
||||
* <p>
|
||||
* The orm update differs from the sql update in that it you can use the bean
|
||||
* name and bean property names rather than table and column names.
|
||||
* </p>
|
||||
* <p>
|
||||
* An example:
|
||||
* </p>
|
||||
* <p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* // The bean name and properties - "topic","postCount" and "id"
|
||||
@@ -466,7 +440,6 @@ public interface Database {
|
||||
* <p>
|
||||
* DTO beans are just normal bean like classes with public constructor(s) and setters.
|
||||
* They do not need to be registered with DB before use.
|
||||
* </p>
|
||||
*
|
||||
* @param dtoType The type of the DTO bean the rows will be mapped into.
|
||||
* @param sql The SQL query to execute.
|
||||
@@ -479,7 +452,6 @@ public interface Database {
|
||||
* <p>
|
||||
* DTO beans are just normal bean like classes with public constructor(s) and setters.
|
||||
* They do not need to be registered with DB before use.
|
||||
* </p>
|
||||
*
|
||||
* @param dtoType The type of the DTO bean the rows will be mapped into.
|
||||
* @param namedQuery The name of the query
|
||||
@@ -493,10 +465,8 @@ public interface Database {
|
||||
*
|
||||
* <p>
|
||||
* Refer to {@link DtoQuery} for native sql queries returning DTO beans.
|
||||
* </p>
|
||||
* <p>
|
||||
* Refer to {@link #findNative(Class, String)} for native sql queries returning entity beans.
|
||||
* </p>
|
||||
*/
|
||||
SqlQuery sqlQuery(String sql);
|
||||
|
||||
@@ -505,11 +475,9 @@ public interface Database {
|
||||
* <p>
|
||||
* Use this to execute a Insert Update or Delete statement. The statement will
|
||||
* be native to the database and contain database table and column names.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* See {@link SqlUpdate} for example usage.
|
||||
* </p>
|
||||
*
|
||||
* @return The SqlUpdate instance to set parameters and execute
|
||||
*/
|
||||
@@ -522,7 +490,7 @@ public interface Database {
|
||||
|
||||
/**
|
||||
* Register a TransactionCallback on the currently active transaction.
|
||||
* <p/>
|
||||
* <p>
|
||||
* If there is no currently active transaction then a PersistenceException is thrown.
|
||||
*
|
||||
* @param transactionCallback The transaction callback to be registered with the current transaction.
|
||||
@@ -536,7 +504,6 @@ public interface Database {
|
||||
* You will want to do this if you want multiple Transactions in a single
|
||||
* thread or generally use transactions outside of the TransactionThreadLocal
|
||||
* management.
|
||||
* </p>
|
||||
*/
|
||||
Transaction createTransaction();
|
||||
|
||||
@@ -544,7 +511,6 @@ public interface Database {
|
||||
* Create a new transaction additionally specifying the isolation level.
|
||||
* <p>
|
||||
* Note that this transaction is NOT stored in a thread local.
|
||||
* </p>
|
||||
*/
|
||||
Transaction createTransaction(TxIsolation isolation);
|
||||
|
||||
@@ -552,86 +518,77 @@ public interface Database {
|
||||
* Start a transaction with 'REQUIRED' semantics.
|
||||
* <p>
|
||||
* With REQUIRED semantics if an active transaction already exists that transaction will be used.
|
||||
* </p>
|
||||
* <p>
|
||||
* The transaction is stored in a ThreadLocal variable and typically you only
|
||||
* need to use the returned Transaction <em>IF</em> you wish to do things like
|
||||
* use batch mode, change the transaction isolation level, use savepoints or
|
||||
* log comments to the transaction log.
|
||||
* </p>
|
||||
* <p>
|
||||
* Example of using a transaction to span multiple calls to find(), save()
|
||||
* etc.
|
||||
* </p>
|
||||
* <p>
|
||||
* Example of using a transaction to span multiple calls to find(), save() etc.
|
||||
*
|
||||
* <h3>Using try with resources</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // start a transaction (stored in a ThreadLocal)
|
||||
* // start a transaction (stored in a ThreadLocal)
|
||||
* try (Transaction txn = database.beginTransaction()) {
|
||||
*
|
||||
* try (Transaction txn = database.beginTransaction()) {
|
||||
* Order order = database.find(Order.class, 10);
|
||||
* ...
|
||||
* database.save(order);
|
||||
*
|
||||
* Order order = database.find(Order.class, 10);
|
||||
* ...
|
||||
* database.save(order);
|
||||
*
|
||||
* txn.commit();
|
||||
* }
|
||||
* txn.commit();
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
* <p>
|
||||
*
|
||||
* <h3>Using try finally block</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // start a transaction (stored in a ThreadLocal)
|
||||
* Transaction txn = database.beginTransaction();
|
||||
* try {
|
||||
* Order order = database.find(Order.class,10);
|
||||
* // start a transaction (stored in a ThreadLocal)
|
||||
* Transaction txn = database.beginTransaction();
|
||||
* try {
|
||||
* Order order = database.find(Order.class,10);
|
||||
*
|
||||
* database.save(order);
|
||||
*
|
||||
* txn.commit();
|
||||
*
|
||||
* } finally {
|
||||
* txn.end();
|
||||
* }
|
||||
* database.save(order);
|
||||
* txn.commit();
|
||||
*
|
||||
* } finally {
|
||||
* txn.end();
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>
|
||||
*
|
||||
* <h3>Transaction options</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* try (Transaction txn = database.beginTransaction()) {
|
||||
* try (Transaction txn = database.beginTransaction()) {
|
||||
*
|
||||
* // explicitly turn on/off JDBC batch use
|
||||
* txn.setBatchMode(true);
|
||||
* txn.setBatchSize(50);
|
||||
* // explicitly turn on/off JDBC batch use
|
||||
* txn.setBatchMode(true);
|
||||
* txn.setBatchSize(50);
|
||||
*
|
||||
* // control flushing when mixing save and queries
|
||||
* txn.setBatchFlushOnQuery(false);
|
||||
* // control flushing when mixing save and queries
|
||||
* txn.setBatchFlushOnQuery(false);
|
||||
*
|
||||
* // turn off persist cascade if needed
|
||||
* txn.setPersistCascade(false);
|
||||
* // turn off persist cascade if needed
|
||||
* txn.setPersistCascade(false);
|
||||
*
|
||||
* // for large batch insert processing when we do not
|
||||
* // ... need the generatedKeys, don't get them
|
||||
* txn.setBatchGetGeneratedKeys(false);
|
||||
* // for large batch insert processing when we do not
|
||||
* // ... need the generatedKeys, don't get them
|
||||
* txn.setBatchGetGeneratedKeys(false);
|
||||
*
|
||||
* // explicitly flush the JDBC batch buffer
|
||||
* txn.flush();
|
||||
* // explicitly flush the JDBC batch buffer
|
||||
* txn.flush();
|
||||
*
|
||||
* ...
|
||||
* ...
|
||||
*
|
||||
* txn.commit();
|
||||
* }
|
||||
* txn.commit();
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
* <p>
|
||||
* <p>
|
||||
* If you want to externalise the transaction management then you use
|
||||
* createTransaction() and pass the transaction around to the various methods on
|
||||
* Database yourself.
|
||||
* </p>
|
||||
*/
|
||||
Transaction beginTransaction();
|
||||
|
||||
@@ -643,11 +600,9 @@ public interface Database {
|
||||
/**
|
||||
* Start a transaction typically specifying REQUIRES_NEW or REQUIRED semantics.
|
||||
* <p>
|
||||
* <p>
|
||||
* Note that this provides an try finally alternative to using {@link #executeCall(TxScope, Callable)} or
|
||||
* {@link #execute(TxScope, Runnable)}.
|
||||
* </p>
|
||||
* <p>
|
||||
*
|
||||
* <h3>REQUIRES_NEW example:</h3>
|
||||
* <pre>{@code
|
||||
* // Start a new transaction. If there is a current transaction
|
||||
@@ -694,10 +649,8 @@ public interface Database {
|
||||
* This only is useful when JDBC batch is used. Flush occurs automatically when the
|
||||
* transaction commits or batch size is reached. This manually flushes the JDBC batch
|
||||
* buffer.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is the same as <code>currentTransaction().flush()</code>.
|
||||
* </p>
|
||||
*/
|
||||
void flush();
|
||||
|
||||
@@ -717,7 +670,6 @@ public interface Database {
|
||||
* <p>
|
||||
* Useful to put in a finally block to ensure the transaction is ended, rather
|
||||
* than a rollbackTransaction() in each catch block.
|
||||
* </p>
|
||||
* <p>
|
||||
* Code example:
|
||||
* <p>
|
||||
@@ -744,7 +696,6 @@ public interface Database {
|
||||
* <p>
|
||||
* Note that this resets OneToMany and ManyToMany properties so that if they
|
||||
* are accessed a lazy load will refresh the many property.
|
||||
* </p>
|
||||
*/
|
||||
void refresh(Object bean);
|
||||
|
||||
@@ -763,12 +714,11 @@ public interface Database {
|
||||
* // Fetch order 1
|
||||
* Order order = database.find(Order.class, 1);
|
||||
* }</pre>
|
||||
* <p>
|
||||
*
|
||||
* <p>
|
||||
* If you want more control over the query then you can use createQuery() and
|
||||
* Query.findOne();
|
||||
* </p>
|
||||
* <p>
|
||||
*
|
||||
* <pre>{@code
|
||||
* // ... additionally fetching customer, customer shipping address,
|
||||
* // order details, and the product associated with each order detail.
|
||||
@@ -810,10 +760,9 @@ public interface Database {
|
||||
* <p>
|
||||
* This will not perform a query against the database unless some property other
|
||||
* that the id property is accessed.
|
||||
* </p>
|
||||
* <p>
|
||||
* It is most commonly used to set a 'foreign key' on another bean like:
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* Product product = database.getReference(Product.class, 1);
|
||||
@@ -853,12 +802,10 @@ public interface Database {
|
||||
* <p>
|
||||
* The extended API has the options for executing queries that take an explicit
|
||||
* transaction as an argument.
|
||||
* </p>
|
||||
* <p>
|
||||
* Typically we only need to use the extended API when we do NOT want to use the
|
||||
* Typically, we only need to use the extended API when we do NOT want to use the
|
||||
* usual ThreadLocal based mechanism to obtain the current transaction but instead
|
||||
* supply the transaction explicitly.
|
||||
* </p>
|
||||
*/
|
||||
ExtendedServer extended();
|
||||
|
||||
@@ -867,32 +814,27 @@ public interface Database {
|
||||
* <p>
|
||||
* If there is no current transaction one will be created and committed for
|
||||
* you automatically.
|
||||
* </p>
|
||||
* <p>
|
||||
* Save can cascade along relationships. For this to happen you need to
|
||||
* specify a cascade of CascadeType.ALL or CascadeType.PERSIST on the
|
||||
* OneToMany, OneToOne or ManyToMany annotation.
|
||||
* </p>
|
||||
* <p>
|
||||
* In this example below the details property has a CascadeType.ALL set so
|
||||
* saving an order will also save all its details.
|
||||
* </p>
|
||||
* <p>
|
||||
*
|
||||
* <pre>{@code
|
||||
* public class Order { ...
|
||||
*
|
||||
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
|
||||
* List<OrderDetail> details;
|
||||
* ...
|
||||
* List<OrderDetail> details;
|
||||
* ...
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>
|
||||
* <p>
|
||||
* When a save cascades via a OneToMany or ManyToMany Ebean will automatically
|
||||
* set the 'parent' object to the 'detail' object. In the example below in
|
||||
* saving the order and cascade saving the order details the 'parent' order
|
||||
* will be set against each order detail when it is saved.
|
||||
* </p>
|
||||
*/
|
||||
void save(Object bean) throws OptimisticLockException;
|
||||
|
||||
@@ -910,16 +852,13 @@ public interface Database {
|
||||
* Delete the bean.
|
||||
* <p>
|
||||
* This will return true if the bean was deleted successfully or JDBC batch is being used.
|
||||
* </p>
|
||||
* <p>
|
||||
* If there is no current transaction one will be created and committed for
|
||||
* you automatically.
|
||||
* </p>
|
||||
* <p>
|
||||
* If the Bean does not have a version property (or loaded version property) and
|
||||
* the bean does not exist then this returns false indicating that nothing was
|
||||
* deleted. Note that, if JDBC batch mode is used then this always returns true.
|
||||
* </p>
|
||||
*/
|
||||
boolean delete(Object bean) throws OptimisticLockException;
|
||||
|
||||
@@ -927,12 +866,10 @@ public interface Database {
|
||||
* Delete the bean with an explicit transaction.
|
||||
* <p>
|
||||
* This will return true if the bean was deleted successfully or JDBC batch is being used.
|
||||
* </p>
|
||||
* <p>
|
||||
* If the Bean does not have a version property (or loaded version property) and
|
||||
* the bean does not exist then this returns false indicating that nothing was
|
||||
* deleted. However, if JDBC batch mode is used then this always returns true.
|
||||
* </p>
|
||||
*/
|
||||
boolean delete(Object bean, Transaction transaction) throws OptimisticLockException;
|
||||
|
||||
@@ -1014,16 +951,13 @@ public interface Database {
|
||||
* <p>
|
||||
* If you wish to execute a Sql Select natively then you should use the
|
||||
* SqlQuery object or DtoQuery.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that the table modification information is automatically deduced and
|
||||
* you do not need to call the DB.externalModification() method when you
|
||||
* use this method.
|
||||
* </p>
|
||||
* <p>
|
||||
* Example:
|
||||
* </p>
|
||||
* <p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* // example that uses 'named' parameters
|
||||
@@ -1051,7 +985,6 @@ public interface Database {
|
||||
* transaction.
|
||||
* <p>
|
||||
* This returns the number of rows that where inserted, updated or deleted.
|
||||
* </p>
|
||||
*/
|
||||
int execute(Update<?> update);
|
||||
|
||||
@@ -1065,8 +998,7 @@ public interface Database {
|
||||
* For making calls to stored procedures.
|
||||
* <p>
|
||||
* Example:
|
||||
* </p>
|
||||
* <p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = "{call sp_order_modify(?,?,?)}";
|
||||
@@ -1091,23 +1023,19 @@ public interface Database {
|
||||
* <p>
|
||||
* If you use database.execute(UpdateSql) then the table modification information
|
||||
* is automatically deduced and you do not need to call this method yourself.
|
||||
* </p>
|
||||
* <p>
|
||||
* This information is used to invalidate objects out of the cache and
|
||||
* potentially text indexes. This information is also automatically broadcast
|
||||
* across the cluster.
|
||||
* </p>
|
||||
* <p>
|
||||
* If there is a transaction then this information is placed into the current
|
||||
* transactions event information. When the transaction is committed this
|
||||
* information is registered (with the transaction manager). If this
|
||||
* transaction is rolled back then none of the transaction event information
|
||||
* registers including the information you put in via this method.
|
||||
* </p>
|
||||
* <p>
|
||||
* If there is NO current transaction when you call this method then this
|
||||
* information is registered immediately (with the transaction manager).
|
||||
* </p>
|
||||
*
|
||||
* @param tableName the name of the table that was modified
|
||||
* @param inserted true if rows where inserted into the table
|
||||
@@ -1147,7 +1075,6 @@ public interface Database {
|
||||
* Note: This checks only the root bean!
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // there is a unique constraint on title
|
||||
*
|
||||
* Document doc = new Document();
|
||||
@@ -1176,7 +1103,7 @@ public interface Database {
|
||||
* // uniqueProperties > [title]
|
||||
* // custom msg > property[title] value[One flew over the cuckoo's nest]
|
||||
*
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
@@ -1200,13 +1127,12 @@ public interface Database {
|
||||
* dirty so that it is not skipped.
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
* Customer customer = database.find(Customer, id);
|
||||
*
|
||||
* Customer customer = database.find(Customer, id);
|
||||
*
|
||||
* // mark the bean as dirty so that a save() or update() will
|
||||
* // increment the version property
|
||||
* database.markAsDirty(customer);
|
||||
* database.save(customer);
|
||||
* // mark the bean as dirty so that a save() or update() will
|
||||
* // increment the version property
|
||||
* database.markAsDirty(customer);
|
||||
* database.save(customer);
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@@ -1219,18 +1145,17 @@ public interface Database {
|
||||
* <b>Stateless updates:</b> Note that the bean does not have to be previously fetched to call
|
||||
* update().You can create a new instance and set some of its properties programmatically for via
|
||||
* JSON/XML marshalling etc. This is described as a 'stateless update'.
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>Optimistic Locking: </b> Note that if the version property is not set when update() is
|
||||
* called then no optimistic locking is performed (internally ConcurrencyMode.NONE is used).
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* // A 'stateless update' example
|
||||
* Customer customer = new Customer();
|
||||
* customer.setId(7);
|
||||
* customer.setName("ModifiedNameNoOCC");
|
||||
* database.update(customer);
|
||||
* // A 'stateless update' example
|
||||
* Customer customer = new Customer();
|
||||
* customer.setId(7);
|
||||
* customer.setName("ModifiedNameNoOCC");
|
||||
* database.update(customer);
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@@ -1281,7 +1206,6 @@ public interface Database {
|
||||
* Compared to save() this forces bean to perform an insert rather than trying to decide
|
||||
* based on the bean state. As such this is useful when you fetch beans from one database
|
||||
* and want to insert them into another database (and you want to explicitly insert them).
|
||||
* </p>
|
||||
*/
|
||||
void insert(Object bean);
|
||||
|
||||
@@ -1314,21 +1238,18 @@ public interface Database {
|
||||
/**
|
||||
* Execute a Runnable in a Transaction with an explicit scope.
|
||||
* <p>
|
||||
* The scope can control the transaction type, isolation and rollback
|
||||
* semantics.
|
||||
* </p>
|
||||
* <p>
|
||||
* The scope can control the transaction type, isolation and rollback semantics.
|
||||
*
|
||||
* <pre>{@code
|
||||
* // set specific transactional scope settings
|
||||
* TxScope scope = TxScope.requiresNew().setIsolation(TxIsolation.SERIALIZABLE);
|
||||
*
|
||||
* // set specific transactional scope settings
|
||||
* TxScope scope = TxScope.requiresNew().setIsolation(TxIsolation.SERIALIZABLE);
|
||||
*
|
||||
* database.execute(scope, new Runnable() {
|
||||
* public void run() {
|
||||
* User u1 = database.find(User.class, 1);
|
||||
* ...
|
||||
* }
|
||||
* });
|
||||
* database.execute(scope, new Runnable() {
|
||||
* public void run() {
|
||||
* User u1 = database.find(User.class, 1);
|
||||
* ...
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@@ -1339,21 +1260,19 @@ public interface Database {
|
||||
* <p>
|
||||
* The default scope runs with REQUIRED and by default will rollback on any
|
||||
* exception (checked or runtime).
|
||||
* </p>
|
||||
* <p>
|
||||
*
|
||||
* <pre>{@code
|
||||
* database.execute(() -> {
|
||||
*
|
||||
* database.execute(() -> {
|
||||
* User u1 = database.find(User.class, 1);
|
||||
* User u2 = database.find(User.class, 2);
|
||||
*
|
||||
* User u1 = database.find(User.class, 1);
|
||||
* User u2 = database.find(User.class, 2);
|
||||
* u1.setName("u1 mod");
|
||||
* u2.setName("u2 mod");
|
||||
*
|
||||
* u1.setName("u1 mod");
|
||||
* u2.setName("u2 mod");
|
||||
*
|
||||
* u1.save();
|
||||
* u2.save();
|
||||
* });
|
||||
* u1.save();
|
||||
* u2.save();
|
||||
* });
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@@ -1364,18 +1283,16 @@ public interface Database {
|
||||
* <p>
|
||||
* The scope can control the transaction type, isolation and rollback
|
||||
* semantics.
|
||||
* </p>
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* <pre>{@code
|
||||
* // set specific transactional scope settings
|
||||
* TxScope scope = TxScope.requiresNew().setIsolation(TxIsolation.SERIALIZABLE);
|
||||
*
|
||||
* database.executeCall(scope, new Callable<String>() {
|
||||
* public String call() {
|
||||
* User u1 = database.find(User.class, 1);
|
||||
* ...
|
||||
* return u1.getEmail();
|
||||
* public String call() {
|
||||
* User u1 = database.find(User.class, 1);
|
||||
* ...
|
||||
* return u1.getEmail();
|
||||
* }
|
||||
* });
|
||||
*
|
||||
@@ -1388,10 +1305,8 @@ public interface Database {
|
||||
* <p>
|
||||
* The default scope runs with REQUIRED and by default will rollback on any
|
||||
* exception (checked or runtime).
|
||||
* </p>
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* <pre>{@code
|
||||
* database.executeCall(new Callable<String>() {
|
||||
* public String call() {
|
||||
* User u1 = database.find(User.class, 1);
|
||||
@@ -1406,7 +1321,6 @@ public interface Database {
|
||||
* return u1.getEmail();
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
<T> T executeCall(Callable<T> callable);
|
||||
@@ -1417,8 +1331,7 @@ public interface Database {
|
||||
ServerCacheManager cacheManager();
|
||||
|
||||
/**
|
||||
* Return the BackgroundExecutor service for asynchronous processing of
|
||||
* queries.
|
||||
* Return the BackgroundExecutor service for asynchronous processing of queries.
|
||||
*/
|
||||
BackgroundExecutor backgroundExecutor();
|
||||
|
||||
@@ -1427,33 +1340,30 @@ public interface Database {
|
||||
* <p>
|
||||
* This instance is safe to be used concurrently by multiple threads and this
|
||||
* method is cheap to call.
|
||||
* </p>
|
||||
* <p>
|
||||
*
|
||||
* <h3>Simple example:</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* JsonContext json = database.json();
|
||||
* String jsonOutput = json.toJson(list);
|
||||
* System.out.println(jsonOutput);
|
||||
*
|
||||
* JsonContext json = database.json();
|
||||
* String jsonOutput = json.toJson(list);
|
||||
* System.out.println(jsonOutput);
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* <h3>Using PathProperties:</h3>
|
||||
* <pre>{@code
|
||||
* // specify just the properties we want
|
||||
* PathProperties paths = PathProperties.parse("name, status, anniversary");
|
||||
*
|
||||
* // specify just the properties we want
|
||||
* PathProperties paths = PathProperties.parse("name, status, anniversary");
|
||||
* List<Customer> customers =
|
||||
* database.find(Customer.class)
|
||||
* // apply those paths to the query (only fetch what we need)
|
||||
* .apply(paths)
|
||||
* .where().ilike("name", "rob%")
|
||||
* .findList();
|
||||
*
|
||||
* List<Customer> customers =
|
||||
* database.find(Customer.class)
|
||||
* // apply those paths to the query (only fetch what we need)
|
||||
* .apply(paths)
|
||||
* .where().ilike("name", "rob%")
|
||||
* .findList();
|
||||
*
|
||||
* // ... get the json
|
||||
* JsonContext jsonContext = database.json();
|
||||
* String json = jsonContext.toJson(customers, paths);
|
||||
* // ... get the json
|
||||
* JsonContext jsonContext = database.json();
|
||||
* String json = jsonContext.toJson(customers, paths);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
@@ -1478,7 +1388,6 @@ public interface Database {
|
||||
* Publish a single bean given its type and id returning the resulting live bean.
|
||||
* <p>
|
||||
* The values are published from the draft to the live bean.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param beanType the type of the entity bean
|
||||
@@ -1493,7 +1402,6 @@ public interface Database {
|
||||
* This will use the current transaction or create one if required.
|
||||
* <p>
|
||||
* The values are published from the draft to the live bean.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param beanType the type of the entity bean
|
||||
@@ -1506,7 +1414,6 @@ public interface Database {
|
||||
* Publish the beans that match the query returning the resulting published beans.
|
||||
* <p>
|
||||
* The values are published from the draft beans to the live beans.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param query the query used to select the draft beans to publish
|
||||
@@ -1519,7 +1426,6 @@ public interface Database {
|
||||
* This will use the current transaction or create one if required.
|
||||
* <p>
|
||||
* The values are published from the draft beans to the live beans.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param query the query used to select the draft beans to publish
|
||||
@@ -1531,7 +1437,6 @@ public interface Database {
|
||||
* <p>
|
||||
* The values from the live beans are set back to the draft bean and the
|
||||
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param beanType the type of the entity bean
|
||||
@@ -1546,7 +1451,6 @@ public interface Database {
|
||||
* <p>
|
||||
* The values from the live beans are set back to the draft bean and the
|
||||
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param beanType the type of the entity bean
|
||||
@@ -1560,7 +1464,6 @@ public interface Database {
|
||||
* <p>
|
||||
* The values from the live beans are set back to the draft bean and the
|
||||
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param query the query used to select the draft beans to restore
|
||||
@@ -1573,7 +1476,6 @@ public interface Database {
|
||||
* <p>
|
||||
* The values from the live beans are set back to the draft bean and the
|
||||
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of the entity bean
|
||||
* @param query the query used to select the draft beans to restore
|
||||
@@ -1585,7 +1487,6 @@ public interface Database {
|
||||
* <p>
|
||||
* Validate the query checking the where and orderBy expression paths to confirm if
|
||||
* they represent valid properties/path for the given bean type.
|
||||
* </p>
|
||||
*/
|
||||
<T> Set<String> validateQuery(Query<T> query);
|
||||
|
||||
@@ -1611,6 +1512,6 @@ public interface Database {
|
||||
/**
|
||||
* Truncate the base tables for the given bean types.
|
||||
*/
|
||||
void truncate(Class<?>... tables);
|
||||
void truncate(Class<?>... beanTypes);
|
||||
|
||||
}
|
||||
|
||||
@@ -2,20 +2,21 @@ package io.ebean;
|
||||
|
||||
import io.ebean.config.BeanNotEnhancedException;
|
||||
import io.ebean.datasource.DataSourceConfigurationException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static java.lang.System.Logger.Level.ERROR;
|
||||
|
||||
/**
|
||||
* Holds Database instances.
|
||||
*/
|
||||
final class DbContext {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger("io.ebean");
|
||||
private static final System.Logger log = EbeanVersion.log;
|
||||
|
||||
static {
|
||||
EbeanVersion.getVersion();
|
||||
}
|
||||
@@ -52,7 +53,7 @@ final class DbContext {
|
||||
throw new DataSourceConfigurationException(msg, e);
|
||||
|
||||
} catch (Throwable e) {
|
||||
log.error("Error trying to create the default Database", e);
|
||||
log.log(ERROR, "Error trying to create the default Database", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,15 +0,0 @@
|
||||
package io.ebean;
|
||||
|
||||
/**
|
||||
* Deprecated - please migrate to <code>io.ebean.Database</code>.
|
||||
* Provides the API for fetching and saving beans to a particular Database.
|
||||
* <p>
|
||||
* Effectively this is an alias for {@link Database} which is now the new
|
||||
* and improved name for EbeanServer.
|
||||
* <p>
|
||||
* The preference is to use DB and Database rather than Ebean and EbeanServer.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface EbeanServer extends Database {
|
||||
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.config.ContainerConfig;
|
||||
import io.ebean.config.ServerConfig;
|
||||
|
||||
/**
|
||||
* Deprecated - please migrate to DatabaseFactory.
|
||||
* <p>
|
||||
* Creates EbeanServer instances.
|
||||
* <p>
|
||||
* This uses either a ServerConfig or properties in the ebean.properties file to
|
||||
* configure and create a EbeanServer instance.
|
||||
* </p>
|
||||
* <p>
|
||||
* The EbeanServer instance can either be registered with the Ebean singleton or
|
||||
* not. The Ebean singleton effectively holds a map of EbeanServers by a name.
|
||||
* If the EbeanServer is registered with the Ebean singleton you can retrieve it
|
||||
* later via {@link Ebean#getServer(String)}.
|
||||
* </p>
|
||||
* <p>
|
||||
* One EbeanServer can be nominated as the 'default/primary' EbeanServer. Many
|
||||
* methods on the Ebean singleton such as {@link Ebean#find(Class)} are just a
|
||||
* convenient way of using the 'default/primary' EbeanServer.
|
||||
* </p>
|
||||
*/
|
||||
@Deprecated
|
||||
public class EbeanServerFactory {
|
||||
|
||||
/**
|
||||
* Initialise the container with clustering configuration.
|
||||
* <p>
|
||||
* Call this prior to creating any EbeanServer instances or alternatively set the
|
||||
* ContainerConfig on the ServerConfig when creating the first EbeanServer instance.
|
||||
*/
|
||||
public static void initialiseContainer(ContainerConfig containerConfig) {
|
||||
DatabaseFactory.initialiseContainer(containerConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using ebean.properties to configure the database.
|
||||
*/
|
||||
public static EbeanServer create(String name) {
|
||||
return (EbeanServer)DatabaseFactory.create(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using the ServerConfig object to configure the database.
|
||||
*/
|
||||
public static EbeanServer create(ServerConfig config) {
|
||||
return (EbeanServer)DatabaseFactory.create(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using the ServerConfig additionally specifying a classLoader to use as the context class loader.
|
||||
*/
|
||||
public static EbeanServer createWithContextClassLoader(ServerConfig config, ClassLoader classLoader) {
|
||||
return (EbeanServer)DatabaseFactory.createWithContextClassLoader(config, classLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown gracefully all EbeanServers cleaning up any resources as required.
|
||||
* <p>
|
||||
* This is typically invoked via JVM shutdown hook and not explicitly called.
|
||||
* </p>
|
||||
*/
|
||||
public static void shutdown() {
|
||||
DatabaseFactory.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,15 @@
|
||||
package io.ebean;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import io.avaje.applog.AppLog;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.util.Properties;
|
||||
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
|
||||
/**
|
||||
* Class to determine the ebean version.
|
||||
*
|
||||
@@ -14,7 +17,7 @@ import java.util.Properties;
|
||||
*/
|
||||
public final class EbeanVersion {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger("io.ebean");
|
||||
public static final System.Logger log = AppLog.getLogger("io.ebean");
|
||||
|
||||
/**
|
||||
* Maintain the minimum ebean-agent version manually based on required ebean-agent bug fixes.
|
||||
@@ -22,6 +25,7 @@ public final class EbeanVersion {
|
||||
private static final int MIN_AGENT_MAJOR_VERSION = 12;
|
||||
private static final int MIN_AGENT_MINOR_VERSION = 12;
|
||||
private static String version = "unknown";
|
||||
|
||||
static {
|
||||
readVersion();
|
||||
checkAgentVersion();
|
||||
@@ -29,14 +33,16 @@ public final class EbeanVersion {
|
||||
|
||||
private static void readVersion() {
|
||||
try {
|
||||
try (InputStream in = ClassLoader.getSystemResourceAsStream("META-INF/maven/io.ebean/ebean-api/pom.properties")) {
|
||||
try (InputStream in = ClassLoader.getSystemResourceAsStream("META-INF/ebean-maven-version.txt")) {
|
||||
if (in != null) {
|
||||
version = readVersion(in);
|
||||
try (LineNumberReader reader = new LineNumberReader(new InputStreamReader(in))) {
|
||||
version = reader.readLine();
|
||||
log.log(INFO, "ebean version: {0}", version);
|
||||
}
|
||||
}
|
||||
}
|
||||
log.info("ebean version: {}", version);
|
||||
} catch (IOException e) {
|
||||
log.warn("Could not determine ebean version: {}", e.getMessage());
|
||||
log.log(WARNING, "Could not determine ebean version: {0}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,13 +54,13 @@ public final class EbeanVersion {
|
||||
String agentVersion = readVersion(in);
|
||||
if (agentVersion != null) {
|
||||
if (checkMinAgentVersion(agentVersion)) {
|
||||
log.error("Expected minimum ebean-agent version {}.{}.0 but we have {}, please update the ebean-agent", MIN_AGENT_MAJOR_VERSION, MIN_AGENT_MINOR_VERSION, agentVersion);
|
||||
log.log(ERROR, "Expected minimum ebean-agent version {0}.{1}.0 but we have {2}, please update the ebean-agent", MIN_AGENT_MAJOR_VERSION, MIN_AGENT_MINOR_VERSION, agentVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.warn("Could not check minimum ebean-agent version {}.{}.0 required due to - {}", MIN_AGENT_MAJOR_VERSION, MIN_AGENT_MINOR_VERSION, e.getMessage());
|
||||
log.log(WARNING, "Could not check minimum ebean-agent version {0}.{1}.0 required due to - {2}", MIN_AGENT_MAJOR_VERSION, MIN_AGENT_MINOR_VERSION, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +94,7 @@ public final class EbeanVersion {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ebean version (read from /META-INF/maven/io.ebean/ebean/pom.properties)
|
||||
* Returns the ebean version (read from META-INF/ebean-maven-version.txt)
|
||||
*/
|
||||
public static String getVersion() {
|
||||
return version;
|
||||
|
||||
@@ -383,6 +383,15 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
<A> List<A> findSingleAttributeList();
|
||||
|
||||
/**
|
||||
* Executes the query returning a set of values for a single property.
|
||||
* <p>
|
||||
* This can be used to cache sets.
|
||||
*
|
||||
* @return a HashSet of values for the selegted property
|
||||
*/
|
||||
<A> Set<A> findSingleAttributeSet();
|
||||
|
||||
/**
|
||||
* Execute a query returning a single value of a single property/column.
|
||||
* <pre>{@code
|
||||
@@ -826,6 +835,20 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
ExpressionList<T> eq(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Is EQUAL TO if value is non-null and otherwise no expression is added to the query.
|
||||
* <p>
|
||||
* This is the EQUAL TO equivalent to {@link #inOrEmpty(String, Collection)} where the expression/predicate
|
||||
* is only added when the value is non-null.
|
||||
* <p>
|
||||
* This is effectively a helper method that allows a query to be built in fluid style where some predicates are
|
||||
* effectively optional. We can use <code>eqIfPresent()</code> rather than having a separate if block.
|
||||
* <p>
|
||||
* Another option is to instead globally use {@link io.ebean.config.DatabaseConfig#setExpressionEqualsWithNullAsNoop(boolean)}
|
||||
* but that is not always desirable.
|
||||
*/
|
||||
ExpressionList<T> eqIfPresent(String propertyName, @Nullable Object value);
|
||||
|
||||
/**
|
||||
* Equal To or Null - property is equal to a given value or null.
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@ package io.ebean;
|
||||
|
||||
import io.avaje.lang.Nullable;
|
||||
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import java.time.Clock;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -15,465 +14,182 @@ import java.util.stream.Stream;
|
||||
/**
|
||||
* The extended API for Database.
|
||||
* <p>
|
||||
* Deprecated in favour of using {@link Query#usingTransaction(Transaction)} instead.
|
||||
* <p>
|
||||
* This provides the finder methods that take an explicit transaction rather than obtaining
|
||||
* the transaction from the usual mechanism (which is ThreadLocal based).
|
||||
* </p>
|
||||
* <p>
|
||||
* In general we only want to use this ExtendedServer API when we want to avoid / bypass
|
||||
* the use of the mechanism to get the current transaction and instead explicitly supply
|
||||
* the transaction to use.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that in all cases the transaction supplied can be null and in this case the Database
|
||||
* will use the normal mechanism to obtain the transaction to use.
|
||||
* </p>
|
||||
*/
|
||||
public interface ExtendedServer {
|
||||
|
||||
/**
|
||||
* Return the NOW time from the Clock.
|
||||
*/
|
||||
long clockNow();
|
||||
|
||||
/**
|
||||
* Deprecated but no yet determined suitable replacement (to support testing only change of clock).
|
||||
* <p>
|
||||
* Set the Clock to use for <code>@WhenCreated</code> and <code>@WhenModified</code>.
|
||||
* <p>
|
||||
* Note that we only expect to change the Clock for testing purposes.
|
||||
* </p>
|
||||
*/
|
||||
@Deprecated
|
||||
void setClock(Clock clock);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* <h2>Example:</h2>
|
||||
* <pre>{@code
|
||||
*
|
||||
* boolean userExists = query().where().eq("email", "rob@foo.com").exists();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <h2>Example using a query bean:</h2>
|
||||
* <pre>{@code
|
||||
*
|
||||
* boolean userExists = new QContact().email.equalTo("rob@foo.com").exists();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @return True if the query finds a matching row in the database
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> boolean exists(Query<T> ormQuery, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Return the number of 'top level' or 'root' entities this query should return.
|
||||
*
|
||||
* @see Query#findCount()
|
||||
* @see Query#findFutureCount()
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> int findCount(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Return the Id values of the query as a List.
|
||||
*
|
||||
* @see Query#findIds()
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<A, T> List<A> findIds(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Return a QueryIterator for the query.
|
||||
* <p>
|
||||
* Generally using {@link #findEach(Query, Consumer, Transaction)} or
|
||||
* {@link #findEachWhile(Query, Predicate, Transaction)} is preferred
|
||||
* to findIterate(). The reason is that those methods automatically take care of
|
||||
* closing the queryIterator (and the underlying jdbc statement and resultSet).
|
||||
* <p>
|
||||
* This is similar to findEach in that not all the result beans need to be held
|
||||
* in memory at the same time and as such is good for processing large queries.
|
||||
*
|
||||
* @see Query#findIterate()
|
||||
* @see Query#findEach(Consumer)
|
||||
* @see Query#findEachWhile(Predicate)
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* 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>
|
||||
* Note that the stream needs to be closed so use with try with resources.
|
||||
* </p>
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> Stream<T> findStream(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query visiting the each bean one at a time.
|
||||
* <p>
|
||||
* Unlike findList() this is suitable for processing a query that will return
|
||||
* a very large resultSet. The reason is that not all the result beans need to be
|
||||
* held in memory at the same time and instead processed one at a time.
|
||||
* </p>
|
||||
* <p>
|
||||
* Internally this query using a PersistenceContext scoped to each bean (and the
|
||||
* beans associated object graph).
|
||||
* </p>
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* DB.find(Order.class)
|
||||
* .where().eq("status", Order.Status.NEW)
|
||||
* .order().asc("id")
|
||||
* .findEach((Order order) -> {
|
||||
*
|
||||
* // do something with the order bean
|
||||
* System.out.println(" -- processing order ... " + order);
|
||||
* });
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @see Query#findEach(Consumer)
|
||||
* @see Query#findEachWhile(Predicate)
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> void findEach(Query<T> query, Consumer<T> consumer, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute findEach with batch consumer.
|
||||
*
|
||||
* @see Query#findEach(int, Consumer)
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> void findEach(Query<T> query, int batch, Consumer<List<T>> consumer, Transaction t);
|
||||
|
||||
/**
|
||||
* Execute the query visiting the each bean one at a time.
|
||||
* <p>
|
||||
* Compared to findEach() this provides the ability to stop processing the query
|
||||
* results early by returning false for the Predicate.
|
||||
* </p>
|
||||
* <p>
|
||||
* Unlike findList() this is suitable for processing a query that will return
|
||||
* a very large resultSet. The reason is that not all the result beans need to be
|
||||
* held in memory at the same time and instead processed one at a time.
|
||||
* </p>
|
||||
* <p>
|
||||
* Internally this query using a PersistenceContext scoped to each bean (and the
|
||||
* beans associated object graph).
|
||||
* </p>
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* DB.find(Order.class)
|
||||
* .where().eq("status", Order.Status.NEW)
|
||||
* .order().asc("id")
|
||||
* .findEachWhile((Order order) -> {
|
||||
*
|
||||
* // do something with the order bean
|
||||
* System.out.println(" -- processing order ... " + order);
|
||||
*
|
||||
* boolean carryOnProcessing = ...
|
||||
* return carryOnProcessing;
|
||||
* });
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @see Query#findEach(Consumer)
|
||||
* @see Query#findEachWhile(Predicate)
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> void findEachWhile(Query<T> query, Predicate<T> consumer, Transaction transaction);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* </p>
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> List<Version<T>> findVersions(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute a query returning a list of beans.
|
||||
* <p>
|
||||
* Generally you are able to use {@link Query#findList()} rather than
|
||||
* explicitly calling this method. You could use this method if you wish to
|
||||
* explicitly control the transaction used for the query.
|
||||
* </p>
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* List<Customer> customers = DB.find(Customer.class)
|
||||
* .where().ilike("name", "rob%")
|
||||
* .findList();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param <T> the type of entity bean to fetch.
|
||||
* @param query the query to execute.
|
||||
* @param transaction the transaction to use (can be null).
|
||||
* @return the list of fetched beans.
|
||||
* @see Query#findList()
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> List<T> findList(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* </p>
|
||||
*
|
||||
* @param query the query to execute the row count on
|
||||
* @param transaction the transaction (can be null).
|
||||
* @return a Future object for the row count query
|
||||
* @see Query#findFutureCount()
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> FutureRowCount<T> findFutureCount(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* </p>
|
||||
*
|
||||
* @param query the query to execute the fetch Id's on
|
||||
* @param transaction the transaction (can be null).
|
||||
* @return a Future object for the list of Id's
|
||||
* @see Query#findFutureIds()
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> FutureIds<T> findFutureIds(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute find list query in a background thread returning a FutureList object.
|
||||
* <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).
|
||||
* <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.
|
||||
*
|
||||
* @param query the query to execute in the background
|
||||
* @param transaction the transaction (can be null).
|
||||
* @return a Future object for the list result of the query
|
||||
* @see Query#findFutureList()
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> FutureList<T> findFutureList(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* 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>
|
||||
* <p>
|
||||
* If maxRows is not set on the query prior to calling findPagedList() then a
|
||||
* PersistenceException is thrown.
|
||||
* </p>
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* PagedList<Order> pagedList = DB.find(Order.class)
|
||||
* .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
|
||||
* @see Query#findPagedList()
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> PagedList<T> findPagedList(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query returning a set of entity beans.
|
||||
* <p>
|
||||
* Generally you are able to use {@link Query#findSet()} rather than
|
||||
* explicitly calling this method. You could use this method if you wish to
|
||||
* explicitly control the transaction used for the query.
|
||||
* </p>
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* Set<Customer> customers = DB.find(Customer.class)
|
||||
* .where().ilike("name", "rob%")
|
||||
* .findSet();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param <T> the type of entity bean to fetch.
|
||||
* @param query the query to execute
|
||||
* @param transaction the transaction to use (can be null).
|
||||
* @return the set of fetched beans.
|
||||
* @see Query#findSet()
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> Set<T> findSet(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query returning the entity beans in a Map.
|
||||
* <p>
|
||||
* Generally you are able to use {@link Query#findMap()} rather than
|
||||
* explicitly calling this method. You could use this method if you wish to
|
||||
* explicitly control the transaction used for the query.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of entity bean to fetch.
|
||||
* @param query the query to execute.
|
||||
* @param transaction the transaction to use (can be null).
|
||||
* @return the map of fetched beans.
|
||||
* @see Query#findMap()
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<K, T> Map<K, T> findMap(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query returning a list of values for a single property.
|
||||
* <p>
|
||||
* <h3>Example 1:</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* List<String> names =
|
||||
* DB.find(Customer.class)
|
||||
* .select("name")
|
||||
* .order().asc("name")
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
* }</pre>
|
||||
* <h3>Example 2:</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* List<String> names =
|
||||
* DB.find(Customer.class)
|
||||
* .setDistinct(true)
|
||||
* .select("name")
|
||||
* .where().eq("status", Customer.Status.NEW)
|
||||
* .order().asc("name")
|
||||
* .setMaxRows(100)
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @return the list of values for the selected property
|
||||
* @see Query#findSingleAttributeList()
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<A, T> List<A> findSingleAttributeList(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query returning at most one entity bean or null (if no matching
|
||||
* bean is found).
|
||||
* <p>
|
||||
* This will throw a NonUniqueResultException if the query finds more than one result.
|
||||
* </p>
|
||||
* <p>
|
||||
* Generally you are able to use {@link Query#findOne()} rather than
|
||||
* explicitly calling this method. You could use this method if you wish to
|
||||
* explicitly control the transaction used for the query.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of entity bean to fetch.
|
||||
* @param query the query to execute.
|
||||
* @param transaction the transaction to use (can be null).
|
||||
* @return the list of fetched beans.
|
||||
* @throws NonUniqueResultException if more than one result was found
|
||||
* @see Query#findOne()
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<A, T> Set<A> findSingleAttributeSet(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
<T> T findOne(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Similar to findOne() but returns an Optional (rather than nullable).
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> Optional<T> findOneOrEmpty(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* @param query the query used for the delete
|
||||
* @param transaction the transaction to use (can be null)
|
||||
* @param <T> the type of entity bean to fetch.
|
||||
* @return the number of beans/rows that were deleted
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> int delete(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the update query returning the number of rows updated.
|
||||
* <p>
|
||||
* The update query must be created using {@link Database#update(Class)}.
|
||||
* </p>
|
||||
*
|
||||
* @param query the update query to execute
|
||||
* @param transaction the optional transaction to use for the update (can be null)
|
||||
* @param <T> the type of entity bean
|
||||
* @return The number of rows updated
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
<T> int update(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the sql query returning a list of MapBean.
|
||||
* <p>
|
||||
* Generally you are able to use {@link SqlQuery#findList()} rather than
|
||||
* explicitly calling this method. You could use this method if you wish to
|
||||
* explicitly control the transaction used for the query.
|
||||
* </p>
|
||||
*
|
||||
* @param query the query to execute.
|
||||
* @param transaction the transaction to use (can be null).
|
||||
* @return the list of fetched MapBean.
|
||||
* @see SqlQuery#findList()
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
List<SqlRow> findList(SqlQuery query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the SqlQuery iterating a row at a time.
|
||||
* <p>
|
||||
* This streaming type query is useful for large query execution as only 1 row needs to be held in memory.
|
||||
* </p>
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
void findEach(SqlQuery query, Consumer<SqlRow> consumer, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the SqlQuery iterating a row at a time with the ability to stop consuming part way through.
|
||||
* <p>
|
||||
* Returning false after processing a row stops the iteration through the query results.
|
||||
* </p>
|
||||
* <p>
|
||||
* This streaming type query is useful for large query execution as only 1 row needs to be held in memory.
|
||||
* </p>
|
||||
* Deprecated migrate to using {@link Query#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
void findEachWhile(SqlQuery query, Predicate<SqlRow> consumer, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the sql query returning a single MapBean or null.
|
||||
* <p>
|
||||
* This will throw a PersistenceException if the query found more than one
|
||||
* result.
|
||||
* </p>
|
||||
* <p>
|
||||
* Generally you are able to use {@link SqlQuery#findOne()} rather than
|
||||
* explicitly calling this method. You could use this method if you wish to
|
||||
* explicitly control the transaction used for the query.
|
||||
* </p>
|
||||
*
|
||||
* @param query the query to execute.
|
||||
* @param transaction the transaction to use (can be null).
|
||||
* @return the fetched MapBean or null if none was found.
|
||||
* @see SqlQuery#findOne()
|
||||
* Deprecated migrate to using {@link SqlQuery#usingTransaction(Transaction)}.
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
SqlRow findOne(SqlQuery query, Transaction transaction);
|
||||
|
||||
|
||||
@@ -13,8 +13,7 @@ import java.io.Serializable;
|
||||
* }</pre>
|
||||
* <p>
|
||||
* Example: Using a "query join" instead of a "fetch join" we instead use 2 SQL queries
|
||||
* </p>
|
||||
* <p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* // This will use 2 SQL queries to build this object graph
|
||||
@@ -27,9 +26,6 @@ import java.io.Serializable;
|
||||
* // query 2) find orderDetails where order.id in (?,?...) // first 100 order id's
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @author mario
|
||||
* @author rbygrave
|
||||
*/
|
||||
public final class FetchConfig implements Serializable {
|
||||
|
||||
@@ -40,21 +36,9 @@ public final class FetchConfig implements Serializable {
|
||||
private static final int LAZY_MODE = 2;
|
||||
private static final int CACHE_MODE = 3;
|
||||
|
||||
private int mode;
|
||||
private int batchSize;
|
||||
private int hashCode;
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to one of the static factory methods like {@link FetchConfig#ofQuery()}
|
||||
* <p>
|
||||
* Construct using default JOIN mode.
|
||||
*/
|
||||
@Deprecated
|
||||
public FetchConfig() {
|
||||
//this.mode = JOIN_MODE;
|
||||
this.batchSize = 100;
|
||||
this.hashCode = 1000;
|
||||
}
|
||||
private final int mode;
|
||||
private final int batchSize;
|
||||
private final int hashCode;
|
||||
|
||||
private FetchConfig(int mode, int batchSize) {
|
||||
this.mode = mode;
|
||||
@@ -106,94 +90,6 @@ public final class FetchConfig implements Serializable {
|
||||
return new FetchConfig(JOIN_MODE, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* We want to migrate away from mutating FetchConfig to a fully immutable FetchConfig.
|
||||
*/
|
||||
private FetchConfig mutate(int mode, int batchSize) {
|
||||
if (batchSize < 0) {
|
||||
throw new IllegalArgumentException("batch size " + batchSize + " must be > 0");
|
||||
}
|
||||
this.mode = mode;
|
||||
this.batchSize = batchSize;
|
||||
this.hashCode = mode + 10 * batchSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to FetchConfig.ofLazy().
|
||||
*/
|
||||
@Deprecated
|
||||
public FetchConfig lazy() {
|
||||
return mutate(LAZY_MODE, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to FetchConfig.ofLazy(batchSize).
|
||||
*/
|
||||
@Deprecated
|
||||
public FetchConfig lazy(int batchSize) {
|
||||
return mutate(LAZY_MODE, batchSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to FetchConfig.ofQuery().
|
||||
* <p>
|
||||
* Eagerly fetch the beans in this path as a separate query (rather than as
|
||||
* part of the main query).
|
||||
* <p>
|
||||
* This will use the default batch size for separate query which is 100.
|
||||
*/
|
||||
@Deprecated
|
||||
public FetchConfig query() {
|
||||
return mutate(QUERY_MODE, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to FetchConfig.ofQuery(batchSize).
|
||||
* <p>
|
||||
* Eagerly fetch the beans in this path as a separate query (rather than as
|
||||
* part of the main query).
|
||||
* <p>
|
||||
* The queryBatchSize is the number of parent id's that this separate query
|
||||
* will load per batch.
|
||||
* <p>
|
||||
* This will load all beans on this path eagerly unless a {@link #lazy(int)}
|
||||
* is also used.
|
||||
*
|
||||
* @param batchSize the batch size used to load beans on this path
|
||||
*/
|
||||
@Deprecated
|
||||
public FetchConfig query(int batchSize) {
|
||||
return mutate(QUERY_MODE, batchSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to FetchConfig.ofQuery(batchSize).
|
||||
* <p>
|
||||
* Eagerly fetch the first batch of beans on this path.
|
||||
* This is similar to {@link #query(int)} but only fetches the first batch.
|
||||
* <p>
|
||||
* If there are more parent beans than the batch size then they will not be
|
||||
* loaded eagerly but instead use lazy loading.
|
||||
*
|
||||
* @param batchSize the number of parent beans this path is populated for
|
||||
*/
|
||||
@Deprecated
|
||||
public FetchConfig queryFirst(int batchSize) {
|
||||
return query(batchSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to FetchConfig.ofCache().
|
||||
* <p>
|
||||
* Eagerly fetch the beans fetching the beans from the L2 bean cache
|
||||
* and using the DB for beans not in the cache.
|
||||
*/
|
||||
@Deprecated
|
||||
public FetchConfig cache() {
|
||||
return mutate(CACHE_MODE, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the batch size for fetching.
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,9 @@ import java.util.List;
|
||||
* Intended to be used as a base class for 'Finder' implementations that can then
|
||||
* be injected or used as public static fields on the associated entity bean.
|
||||
* <p>
|
||||
* When using dependency injection {@link BeanRepository} and {@link BeanFinder}
|
||||
* are expected to be used rather than this Finder.
|
||||
* <p>
|
||||
* These 'finders' are a place to organise all the finder methods for that bean type
|
||||
* and specific finder methods are expected to be added (find by unique properties etc).
|
||||
* </p>
|
||||
@@ -54,6 +57,8 @@ import java.util.List;
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @see BeanRepository
|
||||
* @see BeanFinder
|
||||
*/
|
||||
@NonNullApi
|
||||
public class Finder<I, T> {
|
||||
|
||||
@@ -10,11 +10,10 @@ import java.util.Objects;
|
||||
* <p>
|
||||
* This feature is to enable use of L2 cache with complex natural keys with findList() queries in cases where the
|
||||
* IN clause is not a single property but instead a pair of properties.
|
||||
* </p>
|
||||
* <p>
|
||||
* These queries can have predicates that can be translated into a list of complex natural keys such that the L2
|
||||
* cache can be hit with these keys to obtain some or all of the beans from L2 cache rather than the DB.
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* // where a bean is annotated with a complex
|
||||
@@ -45,11 +44,10 @@ import java.util.Objects;
|
||||
* pairs are a unique key/index or part of a unique key/index and highly selective). Currently we know we can do this
|
||||
* on any DB that supports expression/formula based indexes.
|
||||
* using a DB string concatenation formula
|
||||
* </p>
|
||||
* <p>
|
||||
* This means, the implementation converts the list of pairs into a list of strings via concatenation and we use a
|
||||
* DB concatenation formula to match. We see SQL like:
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code sql
|
||||
*
|
||||
* ...
|
||||
@@ -60,7 +58,7 @@ import java.util.Objects;
|
||||
* }</pre>
|
||||
* <p>
|
||||
* We often create a DB expression index to match the DB concat formula like:
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code sql
|
||||
*
|
||||
* create index ix_name on table_name (sku || '-' || code);
|
||||
@@ -144,14 +142,6 @@ public final class Pairs {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated migrate to concatSeparator()
|
||||
*/
|
||||
@Deprecated
|
||||
public Pairs setConcatSeparator(String concatSeparator) {
|
||||
return concatSeparator(concatSeparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a suffix used with DB varchar concatenation to combine the 2 values.
|
||||
*/
|
||||
@@ -167,14 +157,6 @@ public final class Pairs {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated migrate to concatSuffix()
|
||||
*/
|
||||
@Deprecated
|
||||
public Pairs setConcatSuffix(String concatSuffix) {
|
||||
return concatSuffix(concatSuffix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "p0:" + property0 + " p1:" + property1 + " entries:" + entries;
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.ebean;
|
||||
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Timestamp;
|
||||
@@ -925,7 +926,12 @@ public interface Query<T> extends CancelableQuery {
|
||||
<A> List<A> findSingleAttributeList();
|
||||
|
||||
/**
|
||||
* Execute a query returning a single value of a single property/column.
|
||||
* Execute the query returning a hashset of values for a single property.
|
||||
*/
|
||||
<A> Set<A> findSingleAttributeSet();
|
||||
|
||||
/**
|
||||
* Execute a query returning a single value or null for a single property/column.
|
||||
* <p>
|
||||
* <pre>{@code
|
||||
*
|
||||
@@ -937,6 +943,7 @@ public interface Query<T> extends CancelableQuery {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Nullable
|
||||
<A> A findSingleAttribute();
|
||||
|
||||
/**
|
||||
@@ -1372,18 +1379,9 @@ public interface Query<T> extends CancelableQuery {
|
||||
* optional asc and desc keywords representing ascending and descending order
|
||||
* respectively.
|
||||
*/
|
||||
Query<T> order(String orderByClause);
|
||||
|
||||
/**
|
||||
* Return the OrderBy so that you can append an ascending or descending
|
||||
* property to the order by clause.
|
||||
* <p>
|
||||
* This will never return a null. If no order by clause exists then an 'empty'
|
||||
* OrderBy object is returned.
|
||||
* <p>
|
||||
* This is the same as <code>orderBy()</code>
|
||||
*/
|
||||
OrderBy<T> order();
|
||||
default Query<T> order(String orderByClause) {
|
||||
return orderBy(orderByClause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the OrderBy so that you can append an ascending or descending
|
||||
@@ -1397,15 +1395,30 @@ public interface Query<T> extends CancelableQuery {
|
||||
OrderBy<T> orderBy();
|
||||
|
||||
/**
|
||||
* Set an OrderBy object to replace any existing OrderBy clause.
|
||||
* Return the OrderBy so that you can append an ascending or descending
|
||||
* property to the order by clause.
|
||||
* <p>
|
||||
* This will never return a null. If no order by clause exists then an 'empty'
|
||||
* OrderBy object is returned.
|
||||
* <p>
|
||||
* This is the same as <code>orderBy()</code>
|
||||
*/
|
||||
Query<T> setOrder(OrderBy<T> orderBy);
|
||||
default OrderBy<T> order() {
|
||||
return orderBy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an OrderBy object to replace any existing OrderBy clause.
|
||||
*/
|
||||
Query<T> setOrderBy(OrderBy<T> orderBy);
|
||||
|
||||
/**
|
||||
* Set an OrderBy object to replace any existing OrderBy clause.
|
||||
*/
|
||||
default Query<T> setOrder(OrderBy<T> orderBy) {
|
||||
return setOrderBy(orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this query uses DISTINCT.
|
||||
* <p>
|
||||
@@ -1567,10 +1580,11 @@ public interface Query<T> extends CancelableQuery {
|
||||
Query<T> setReadOnly(boolean readOnly);
|
||||
|
||||
/**
|
||||
* Will be deprecated - migrate to use setBeanCacheMode(CacheMode.RECACHE).
|
||||
* Deprecated - migrate to use setBeanCacheMode(CacheMode.PUT) or other CacheMode.
|
||||
* <p>
|
||||
* When set to true all the beans from this query are loaded into the bean cache.
|
||||
*/
|
||||
@Deprecated
|
||||
Query<T> setLoadBeanCache(boolean loadBeanCache);
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,8 +2,8 @@ package io.ebean;
|
||||
|
||||
import io.avaje.lang.NonNullApi;
|
||||
import io.avaje.lang.Nullable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
@@ -40,6 +40,11 @@ import java.util.function.Predicate;
|
||||
@NonNullApi
|
||||
public interface SqlQuery extends Serializable, CancelableQuery {
|
||||
|
||||
/**
|
||||
* Execute the query using the given transaction.
|
||||
*/
|
||||
SqlQuery usingTransaction(Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query returning a list.
|
||||
*/
|
||||
@@ -298,6 +303,11 @@ public interface SqlQuery extends Serializable, CancelableQuery {
|
||||
*/
|
||||
interface TypeQuery<T> {
|
||||
|
||||
/**
|
||||
* Execute the query using the given transaction.
|
||||
*/
|
||||
TypeQuery<T> usingTransaction(Transaction transaction);
|
||||
|
||||
/**
|
||||
* Return the single value.
|
||||
*/
|
||||
|
||||
@@ -440,14 +440,6 @@ public interface Transaction extends AutoCloseable {
|
||||
*/
|
||||
void setGetGeneratedKeys(boolean getGeneratedKeys);
|
||||
|
||||
/**
|
||||
* Deprecated renamed to setGetGeneratedKeys().
|
||||
*/
|
||||
@Deprecated
|
||||
default void setBatchGetGeneratedKeys(boolean getGeneratedKeys) {
|
||||
setGetGeneratedKeys(getGeneratedKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* By default when mixing UpdateSql (or CallableSql) with Beans the batch is
|
||||
* automatically flushed when you change (between persisting beans and
|
||||
@@ -463,14 +455,6 @@ public interface Transaction extends AutoCloseable {
|
||||
*/
|
||||
void setFlushOnMixed(boolean batchFlushOnMixed);
|
||||
|
||||
/**
|
||||
* Deprecated renamed to setFlushOnMixed().
|
||||
*/
|
||||
@Deprecated
|
||||
default void setBatchFlushOnMixed(boolean batchFlushOnMixed) {
|
||||
setFlushOnMixed(batchFlushOnMixed);
|
||||
}
|
||||
|
||||
/**
|
||||
* By default executing a query will automatically flush any batched
|
||||
* statements (persisted beans, executed UpdateSql etc).
|
||||
@@ -480,14 +464,6 @@ public interface Transaction extends AutoCloseable {
|
||||
*/
|
||||
void setFlushOnQuery(boolean batchFlushOnQuery);
|
||||
|
||||
/**
|
||||
* Deprecated renamed to setFlushOnQuery().
|
||||
*/
|
||||
@Deprecated
|
||||
default void setBatchFlushOnQuery(boolean batchFlushOnQuery) {
|
||||
setFlushOnQuery(batchFlushOnQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the batch (of persisted beans or executed UpdateSql etc)
|
||||
* should be flushed prior to executing a query.
|
||||
@@ -496,14 +472,6 @@ public interface Transaction extends AutoCloseable {
|
||||
*/
|
||||
boolean isFlushOnQuery();
|
||||
|
||||
/**
|
||||
* Deprecated renamed to isFlushOnQuery().
|
||||
*/
|
||||
@Deprecated
|
||||
default boolean isBatchFlushOnQuery() {
|
||||
return isFlushOnQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* The batch will be flushing automatically but you can use this to explicitly
|
||||
* flush the batch if you like.
|
||||
@@ -519,14 +487,6 @@ public interface Transaction extends AutoCloseable {
|
||||
*/
|
||||
void flush() throws PersistenceException;
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to flush().
|
||||
* <p>
|
||||
* flush() is preferred as it matches the JPA flush() method.
|
||||
*/
|
||||
@Deprecated
|
||||
void flushBatch() throws PersistenceException;
|
||||
|
||||
/**
|
||||
* Return the underlying Connection object.
|
||||
* <p>
|
||||
@@ -540,14 +500,6 @@ public interface Transaction extends AutoCloseable {
|
||||
*/
|
||||
Connection connection();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to connection().
|
||||
*/
|
||||
@Deprecated
|
||||
default Connection getConnection() {
|
||||
return connection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add table modification information to the TransactionEvent.
|
||||
* <p>
|
||||
|
||||
@@ -34,6 +34,13 @@ public interface EntityBean extends Serializable, ToStringAware {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new entity bean instance optimised for read only no interception use.
|
||||
*/
|
||||
default Object _ebean_newInstanceReadOnly() {
|
||||
throw new NotEnhancedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generated method that sets the loaded state on all the embedded beans on
|
||||
* this entity bean by using EntityBeanIntercept.setEmbeddedLoaded(Object o);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,546 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
import io.ebean.ValuePair;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* EntityBeanIntercept optimised for read only use.
|
||||
* <p>
|
||||
* For the read only use this intercept doesn't need to hold any state that is normally
|
||||
* required for updates such as per property changed, loaded, dirty state, original values
|
||||
* bean state etc.
|
||||
*/
|
||||
public class InterceptReadOnly implements EntityBeanIntercept {
|
||||
|
||||
private final EntityBean owner;
|
||||
|
||||
/**
|
||||
* Create with a given entity.
|
||||
*/
|
||||
public InterceptReadOnly(Object ownerBean) {
|
||||
this.owner = (EntityBean) ownerBean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityBean getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistenceContext getPersistenceContext() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPersistenceContext(PersistenceContext persistenceContext) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNodeUsageCollector(NodeUsageCollector usageCollector) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOwnerId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOwnerId(Object ownerId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getEmbeddedOwner() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEmbeddedOwnerIndex() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearGetterCallback() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerGetterCallback(PreGetterCallback getterCallback) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEmbeddedOwner(EntityBean parentBean, int embeddedOwnerIndex) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanLoader(BeanLoader beanLoader, PersistenceContext ctx) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanLoader(BeanLoader beanLoader) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullyLoadedBean() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFullyLoadedBean(boolean fullyLoadedBean) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPartial() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEmbeddedDirty(int embeddedProperty) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirty(boolean dirty) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNew() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNewOrDirty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasIdOnly(int idIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReference() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReference(int idPos) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoadedFromCache(boolean loadedFromCache) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoadedFromCache() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadOnly(boolean readOnly) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setForceUpdate(boolean forceUpdate) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoaded() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNew() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoaded() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoadedLazy() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLazyLoadFailure(Object ownerId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLazyLoadFailure() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisableLazyLoad() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisableLazyLoad(boolean disableLazyLoad) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEmbeddedLoaded(Object embeddedBean) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmbeddedNewOrDirty(Object embeddedBean) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getOrigValue(int propertyIndex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findProperty(String propertyName) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProperty(int propertyIndex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPropertyLength() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPropertyLoaded(String propertyName, boolean loaded) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPropertyUnloaded(int propertyIndex) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoadedProperty(int propertyIndex) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoadedPropertyAll() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoadedProperty(int propertyIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChangedProperty(int propertyIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirtyProperty(int propertyIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markPropertyAsChanged(int propertyIndex) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChangedProperty(int propertyIndex) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChangeLoaded(int propertyIndex) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEmbeddedPropertyDirty(int propertyIndex) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOriginalValue(int propertyIndex, Object value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOriginalValueForce(int propertyIndex, Object value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNewBeanForUpdate() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getLoadedPropertyNames() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] getDirtyProperties() {
|
||||
return new boolean[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDirtyPropertyNames() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDirtyPropertyNames(Set<String> props, String prefix) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDirtyProperty(Set<String> propertyNames) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ValuePair> getDirtyValues() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDirtyPropertyValues(Map<String, ValuePair> dirtyValues, String prefix) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDirtyPropertyValues(BeanDiffVisitor visitor) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder getDirtyPropertyKey() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDirtyPropertyKey(StringBuilder sb) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder getLoadedPropertyKey() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] getLoaded() {
|
||||
return new boolean[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLazyLoadPropertyIndex() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLazyLoadProperty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadBean(int loadProperty) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadBeanInternal(int loadProperty, BeanLoader loader) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialisedMany(int propertyIndex) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preGetterCallback(int propertyIndex) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preGetId() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preGetter(int propertyIndex) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSetterMany(boolean interceptField, int propertyIndex, Object oldValue, Object newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChangedPropertyValue(int propertyIndex, boolean setDirtyState, Object origValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirtyStatus() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSetter(boolean intercept, int propertyIndex, Object oldValue, Object newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSetter(boolean intercept, int propertyIndex, boolean oldValue, boolean newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSetter(boolean intercept, int propertyIndex, int oldValue, int newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSetter(boolean intercept, int propertyIndex, long oldValue, long newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSetter(boolean intercept, int propertyIndex, double oldValue, double newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSetter(boolean intercept, int propertyIndex, float oldValue, float newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSetter(boolean intercept, int propertyIndex, short oldValue, short newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSetter(boolean intercept, int propertyIndex, char oldValue, char newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSetter(boolean intercept, int propertyIndex, byte oldValue, byte newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSetter(boolean intercept, int propertyIndex, char[] oldValue, char[] newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSetter(boolean intercept, int propertyIndex, byte[] oldValue, byte[] newValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOldValue(int propertyIndex, Object oldValue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSortOrder() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSortOrder(int sortOrder) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeletedFromCollection(boolean deletedFromCollection) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOrphanDelete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoadError(int propertyIndex, Exception t) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Exception> getLoadErrors() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChangedProp(int i) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableValueInfo mutableInfo(int propertyIndex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mutableInfo(int propertyIndex, MutableValueInfo info) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mutableNext(int propertyIndex, MutableValueNext next) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mutableNext(int propertyIndex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.ref.Cleaner;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -8,120 +8,102 @@ import java.util.Set;
|
||||
* Collects profile information for a bean (or reference/proxy bean) at a given node.
|
||||
* <p>
|
||||
* The node identifies the location of the bean in the object graph.
|
||||
* </p>
|
||||
* <p>
|
||||
* It has to use a weak reference so as to ensure that it does not stop the
|
||||
* associated bean from being garbage collected.
|
||||
* </p>
|
||||
*/
|
||||
public final class NodeUsageCollector {
|
||||
|
||||
/**
|
||||
* The point in the object graph for a specific query and call stack point.
|
||||
*/
|
||||
private final ObjectGraphNode node;
|
||||
private final static Cleaner cleaner = Cleaner.create();
|
||||
|
||||
public static final class State implements Runnable {
|
||||
|
||||
private final NodeUsageListener listener;
|
||||
/**
|
||||
* The properties used at this profile point.
|
||||
*/
|
||||
private final Set<String> used = new LinkedHashSet<>();
|
||||
/**
|
||||
* The point in the object graph for a specific query and call stack point.
|
||||
*/
|
||||
private final ObjectGraphNode node;
|
||||
/**
|
||||
* set to true if the bean is modified (setter called)
|
||||
*/
|
||||
private boolean modified;
|
||||
|
||||
private State(ObjectGraphNode node, NodeUsageListener listener) {
|
||||
this.node = node;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return node + " read:" + used + " modified:" + modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
listener.collectNodeUsage(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if no properties where used.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return used.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the associated node which identifies the location in the object
|
||||
* graph of the bean/reference.
|
||||
*/
|
||||
public ObjectGraphNode node() {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the set of used properties.
|
||||
*/
|
||||
public Set<String> used() {
|
||||
return used;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the bean was modified by a setter.
|
||||
*/
|
||||
public boolean isModified() {
|
||||
return modified;
|
||||
}
|
||||
}
|
||||
|
||||
private final State state;
|
||||
|
||||
public NodeUsageCollector(ObjectGraphNode node, NodeUsageListener listener) {
|
||||
this.state = new State(node, listener);
|
||||
cleaner.register(this, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Weak to allow garbage collection.
|
||||
* Return the underlying state.
|
||||
*/
|
||||
private final WeakReference<NodeUsageListener> managerRef;
|
||||
|
||||
/**
|
||||
* The properties used at this profile point.
|
||||
*/
|
||||
private final Set<String> used = new LinkedHashSet<>();
|
||||
|
||||
/**
|
||||
* set to true if the bean is modified (setter called)
|
||||
*/
|
||||
private boolean modified;
|
||||
|
||||
/**
|
||||
* The property that cause a reference to lazy load.
|
||||
*/
|
||||
private String loadProperty;
|
||||
|
||||
public NodeUsageCollector(ObjectGraphNode node, WeakReference<NodeUsageListener> managerRef) {
|
||||
this.node = node;
|
||||
// weak to allow garbage collection.
|
||||
this.managerRef = managerRef;
|
||||
public State state() {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* The bean has been modified by a setter method.
|
||||
*/
|
||||
public void setModified() {
|
||||
modified = true;
|
||||
state.modified = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the name of a property that has been used.
|
||||
*/
|
||||
public void addUsed(String property) {
|
||||
used.add(property);
|
||||
}
|
||||
|
||||
/**
|
||||
* The property that invoked a lazy load.
|
||||
*/
|
||||
public void setLoadProperty(String loadProperty) {
|
||||
this.loadProperty = loadProperty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish the usage info to the manager.
|
||||
*/
|
||||
private void publishUsageInfo() {
|
||||
NodeUsageListener manager = managerRef.get();
|
||||
if (manager != null) {
|
||||
manager.collectNodeUsage(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* publish the collected usage information when garbage collection occurs.
|
||||
*/
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
publishUsageInfo();
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the associated node which identifies the location in the object
|
||||
* graph of the bean/reference.
|
||||
*/
|
||||
public ObjectGraphNode getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if no properties where used.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return used.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the set of used properties.
|
||||
*/
|
||||
public Set<String> getUsed() {
|
||||
return used;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the bean was modified by a setter.
|
||||
*/
|
||||
public boolean isModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public String getLoadProperty() {
|
||||
return loadProperty;
|
||||
state.used.add(property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return node + " read:" + used + " modified:" + modified;
|
||||
return state.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ public interface NodeUsageListener {
|
||||
* <p>
|
||||
* This is the properties that are used for a given bean in the object graph.
|
||||
* This information is used by autoTune to tune queries.
|
||||
* </p>
|
||||
*/
|
||||
void collectNodeUsage(NodeUsageCollector collector);
|
||||
void collectNodeUsage(NodeUsageCollector.State state);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
import io.ebean.common.BeanMap;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Helps build toString content taking into account recursion.
|
||||
@@ -104,6 +107,8 @@ public final class ToStringBuilder {
|
||||
}
|
||||
} else if (value instanceof Collection) {
|
||||
addCollection((Collection<?>) value);
|
||||
} else if (value instanceof Map) {
|
||||
addMap(((Map<?, ?>) value));
|
||||
} else {
|
||||
String content = String.valueOf(value);
|
||||
if (content.length() > TRIM_LENGTH) {
|
||||
@@ -117,6 +122,28 @@ public final class ToStringBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
public void addMap(Map<?,?> map) {
|
||||
if (map == null || map.isEmpty()) {
|
||||
sb.append("{}");
|
||||
} else {
|
||||
boolean firstElement = true;
|
||||
sb.append("{");
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
if (firstElement) {
|
||||
firstElement = false;
|
||||
} else {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(entry.getKey()).append(":");
|
||||
value(entry.getValue());
|
||||
if (counter > MAX) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
sb.append("}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a collection of values.
|
||||
*/
|
||||
|
||||
@@ -29,9 +29,10 @@ public final class TenantAwareCache implements ServerCache {
|
||||
/**
|
||||
* Return the underlying ServerCache that is being delegated to.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> cls) {
|
||||
return (T)delegate;
|
||||
return (T) delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,39 +17,28 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
|
||||
private static final long serialVersionUID = 3365725236140187588L;
|
||||
|
||||
protected final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
protected boolean readOnly;
|
||||
|
||||
protected boolean disableLazyLoad;
|
||||
|
||||
/**
|
||||
* The Database this is associated with. (used for lazy fetch).
|
||||
*/
|
||||
protected transient BeanCollectionLoader loader;
|
||||
|
||||
protected transient ExpressionList<?> filterMany;
|
||||
|
||||
/**
|
||||
* Flag set when registered with the batch loading context.
|
||||
*/
|
||||
protected boolean registeredWithLoadContext;
|
||||
|
||||
protected String ebeanServerName;
|
||||
|
||||
/**
|
||||
* The owning bean (used for lazy fetch).
|
||||
*/
|
||||
protected EntityBean ownerBean;
|
||||
|
||||
/**
|
||||
* The name of this property in the owning bean (used for lazy fetch).
|
||||
*/
|
||||
protected String propertyName;
|
||||
|
||||
protected ModifyHolder<E> modifyHolder;
|
||||
|
||||
protected ModifyListenMode modifyListenMode;
|
||||
|
||||
protected boolean modifyListening;
|
||||
|
||||
/**
|
||||
@@ -126,8 +115,7 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
|
||||
|
||||
void checkReadOnly() {
|
||||
if (readOnly) {
|
||||
String msg = "This collection is in ReadOnly mode";
|
||||
throw new IllegalStateException(msg);
|
||||
throw new IllegalStateException("This collection is in ReadOnly mode");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
/**
|
||||
* List capable of lazy loading.
|
||||
* List capable of lazy loading and modification awareness.
|
||||
*/
|
||||
public final class BeanList<E> extends AbstractBeanCollection<E> implements List<E>, BeanCollectionAdd {
|
||||
|
||||
@@ -150,7 +150,6 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
* Set the actual underlying list.
|
||||
* <p>
|
||||
* This is primarily for the deferred fetching function.
|
||||
* </p>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setActualList(List<?> list) {
|
||||
@@ -206,12 +205,11 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
* Specifically obj does not need to be a BeanList but any list. This does not
|
||||
* use the FindMany, fetchedMaxRows or finishedFetch properties in the equals
|
||||
* test.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean equals(Object other) {
|
||||
init();
|
||||
return list.equals(obj);
|
||||
return list.equals(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -244,40 +242,40 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(E o) {
|
||||
public boolean add(E bean) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyListening) {
|
||||
if (list.add(o)) {
|
||||
modifyAddition(o);
|
||||
if (list.add(bean)) {
|
||||
modifyAddition(bean);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return list.add(o);
|
||||
return list.add(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
public boolean addAll(Collection<? extends E> beans) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyListening) {
|
||||
// all elements in c are added (no contains checking)
|
||||
getModifyHolder().modifyAdditionAll(c);
|
||||
getModifyHolder().modifyAdditionAll(beans);
|
||||
}
|
||||
return list.addAll(c);
|
||||
return list.addAll(beans);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, Collection<? extends E> c) {
|
||||
public boolean addAll(int index, Collection<? extends E> beans) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyListening) {
|
||||
// all elements in c are added (no contains checking)
|
||||
getModifyHolder().modifyAdditionAll(c);
|
||||
getModifyHolder().modifyAdditionAll(beans);
|
||||
}
|
||||
return list.addAll(index, c);
|
||||
return list.addAll(index, beans);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -287,23 +285,23 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
// and fetch just the Id's
|
||||
initClear();
|
||||
if (modifyListening) {
|
||||
for (E aList : list) {
|
||||
getModifyHolder().modifyRemoval(aList);
|
||||
for (E element : list) {
|
||||
getModifyHolder().modifyRemoval(element);
|
||||
}
|
||||
}
|
||||
list.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
public boolean contains(Object bean) {
|
||||
init();
|
||||
return list.contains(o);
|
||||
return list.contains(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
public boolean containsAll(Collection<?> beans) {
|
||||
init();
|
||||
return list.containsAll(c);
|
||||
return list.containsAll(beans);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -313,9 +311,9 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
public int indexOf(Object bean) {
|
||||
init();
|
||||
return list.indexOf(o);
|
||||
return list.indexOf(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -327,31 +325,29 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
init();
|
||||
if (isReadOnly()) {
|
||||
if (readOnly) {
|
||||
return new ReadOnlyListIterator<>(list.listIterator());
|
||||
}
|
||||
if (modifyListening) {
|
||||
Iterator<E> it = list.iterator();
|
||||
return new ModifyIterator<>(this, it);
|
||||
return new ModifyIterator<>(this, list.iterator());
|
||||
}
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
public int lastIndexOf(Object bean) {
|
||||
init();
|
||||
return list.lastIndexOf(o);
|
||||
return list.lastIndexOf(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<E> listIterator() {
|
||||
init();
|
||||
if (isReadOnly()) {
|
||||
if (readOnly) {
|
||||
return new ReadOnlyListIterator<>(list.listIterator());
|
||||
}
|
||||
if (modifyListening) {
|
||||
ListIterator<E> it = list.listIterator();
|
||||
return new ModifyListIterator<>(this, it);
|
||||
return new ModifyListIterator<>(this, list.listIterator());
|
||||
}
|
||||
return list.listIterator();
|
||||
}
|
||||
@@ -359,12 +355,11 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
@Override
|
||||
public ListIterator<E> listIterator(int index) {
|
||||
init();
|
||||
if (isReadOnly()) {
|
||||
if (readOnly) {
|
||||
return new ReadOnlyListIterator<>(list.listIterator(index));
|
||||
}
|
||||
if (modifyListening) {
|
||||
ListIterator<E> it = list.listIterator(index);
|
||||
return new ModifyListIterator<>(this, it);
|
||||
return new ModifyListIterator<>(this, list.listIterator(index));
|
||||
}
|
||||
return list.listIterator(index);
|
||||
}
|
||||
@@ -389,17 +384,17 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
public boolean remove(Object bean) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyListening) {
|
||||
boolean isRemove = list.remove(o);
|
||||
boolean isRemove = list.remove(bean);
|
||||
if (isRemove) {
|
||||
modifyRemoval(o);
|
||||
modifyRemoval(bean);
|
||||
}
|
||||
return isRemove;
|
||||
}
|
||||
return list.remove(o);
|
||||
return list.remove(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -463,7 +458,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
@Override
|
||||
public List<E> subList(int fromIndex, int toIndex) {
|
||||
init();
|
||||
if (isReadOnly()) {
|
||||
if (readOnly) {
|
||||
return Collections.unmodifiableList(list.subList(fromIndex, toIndex));
|
||||
}
|
||||
if (modifyListening) {
|
||||
@@ -479,13 +474,13 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a) {
|
||||
public <T> T[] toArray(T[] array) {
|
||||
init();
|
||||
//noinspection SuspiciousToArrayCall
|
||||
return list.toArray(a);
|
||||
return list.toArray(array);
|
||||
}
|
||||
|
||||
private static class ReadOnlyListIterator<E> implements ListIterator<E>, Serializable {
|
||||
private static final class ReadOnlyListIterator<E> implements ListIterator<E>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3097271091406323699L;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Map capable of lazy loading.
|
||||
* Map capable of lazy loading and modification aware.
|
||||
*/
|
||||
public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Map<K, E> {
|
||||
|
||||
@@ -247,7 +247,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
|
||||
@Override
|
||||
public Set<Entry<K, E>> entrySet() {
|
||||
init();
|
||||
if (isReadOnly()) {
|
||||
if (readOnly) {
|
||||
return Collections.unmodifiableSet(map.entrySet());
|
||||
}
|
||||
return modifyListening ? new ModifyEntrySet<>(this, map.entrySet()) : map.entrySet();
|
||||
@@ -268,7 +268,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
|
||||
@Override
|
||||
public Set<K> keySet() {
|
||||
init();
|
||||
if (isReadOnly()) {
|
||||
if (readOnly) {
|
||||
return Collections.unmodifiableSet(map.keySet());
|
||||
}
|
||||
return modifyListening ? new ModifyKeySet<>(this, map.keySet()) : map.keySet();
|
||||
@@ -339,7 +339,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
|
||||
@Override
|
||||
public Collection<E> values() {
|
||||
init();
|
||||
if (isReadOnly()) {
|
||||
if (readOnly) {
|
||||
return Collections.unmodifiableCollection(map.values());
|
||||
}
|
||||
return modifyListening ? new ModifyCollection<>(this, map.values()) : map.values();
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Set capable of lazy loading.
|
||||
* Set capable of lazy loading and modification aware.
|
||||
*/
|
||||
public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E>, BeanCollectionAdd {
|
||||
|
||||
@@ -210,27 +210,27 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
// -----------------------------------------------------//
|
||||
|
||||
@Override
|
||||
public boolean add(E o) {
|
||||
public boolean add(E bean) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyListening) {
|
||||
if (set.add(o)) {
|
||||
modifyAddition(o);
|
||||
if (set.add(bean)) {
|
||||
modifyAddition(bean);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return set.add(o);
|
||||
return set.add(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends E> addCollection) {
|
||||
public boolean addAll(Collection<? extends E> beans) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyListening) {
|
||||
boolean changed = false;
|
||||
for (E bean : addCollection) {
|
||||
for (E bean : beans) {
|
||||
if (set.add(bean)) {
|
||||
// register the addition of the bean
|
||||
modifyAddition(bean);
|
||||
@@ -239,7 +239,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
return set.addAll(addCollection);
|
||||
return set.addAll(beans);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -255,15 +255,15 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
public boolean contains(Object bean) {
|
||||
init();
|
||||
return set.contains(o);
|
||||
return set.contains(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
public boolean containsAll(Collection<?> beans) {
|
||||
init();
|
||||
return set.containsAll(c);
|
||||
return set.containsAll(beans);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -275,7 +275,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
init();
|
||||
if (isReadOnly()) {
|
||||
if (readOnly) {
|
||||
return new ReadOnlyIterator<>(set.iterator());
|
||||
}
|
||||
if (modifyListening) {
|
||||
@@ -285,17 +285,17 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
public boolean remove(Object bean) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyListening) {
|
||||
if (set.remove(o)) {
|
||||
modifyRemoval(o);
|
||||
if (set.remove(bean)) {
|
||||
modifyRemoval(bean);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return set.remove(o);
|
||||
return set.remove(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -349,13 +349,13 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a) {
|
||||
public <T> T[] toArray(T[] array) {
|
||||
init();
|
||||
//noinspection SuspiciousToArrayCall
|
||||
return set.toArray(a);
|
||||
return set.toArray(array);
|
||||
}
|
||||
|
||||
private static class ReadOnlyIterator<E> implements Iterator<E>, Serializable {
|
||||
private static final class ReadOnlyIterator<E> implements Iterator<E>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 2577697326745352605L;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import io.ebean.event.changelog.ChangeLogPrepare;
|
||||
import io.ebean.event.changelog.ChangeLogRegister;
|
||||
import io.ebean.event.readaudit.ReadAuditLogger;
|
||||
import io.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import io.ebean.meta.MetricNamingMatch;
|
||||
import io.ebean.util.StringHelper;
|
||||
|
||||
import javax.persistence.EnumType;
|
||||
@@ -24,6 +25,7 @@ import java.time.Clock;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* The configuration used for creating a Database.
|
||||
@@ -115,9 +117,9 @@ public class DatabaseConfig {
|
||||
private TenantCatalogProvider tenantCatalogProvider;
|
||||
|
||||
/**
|
||||
* When true will load entity classes via ModuleInfoLoader.
|
||||
* When true will load entity classes via EntityClassRegister.
|
||||
* <p>
|
||||
* NB: ModuleInfoLoader implementations are generated by querybean generator.
|
||||
* NB: EntityClassRegister implementations are generated by querybean generator.
|
||||
* Having this on and registering entity classes means we don't need to manually
|
||||
* write that code or use classpath scanning to find entity classes.
|
||||
*/
|
||||
@@ -340,11 +342,6 @@ public class DatabaseConfig {
|
||||
*/
|
||||
private ClassLoadConfig classLoadConfig = new ClassLoadConfig();
|
||||
|
||||
/**
|
||||
* The data source JNDI name if using a JNDI DataSource.
|
||||
*/
|
||||
private String dataSourceJndiName;
|
||||
|
||||
/**
|
||||
* The naming convention.
|
||||
*/
|
||||
@@ -392,12 +389,12 @@ public class DatabaseConfig {
|
||||
* Note: It is possible that multiple servers are sharing the same state file as
|
||||
* long as they are in the <b>same</b> JVM/ClassLoader scope. In this case it is
|
||||
* recommended to use the same uuidNodeId configuration.
|
||||
*
|
||||
*
|
||||
* If you have multiple servers in different JVMs, do <b>not</b> share the state
|
||||
* files!
|
||||
*/
|
||||
private String uuidNodeId;
|
||||
|
||||
|
||||
/**
|
||||
* The clock used for setting the timestamps (e.g. @UpdatedTimestamp) on objects.
|
||||
*/
|
||||
@@ -551,6 +548,8 @@ public class DatabaseConfig {
|
||||
|
||||
private String dumpMetricsOptions;
|
||||
|
||||
private Function<String, String> metricNaming = MetricNamingMatch.INSTANCE;
|
||||
|
||||
/**
|
||||
* Construct a Database Configuration for programmatically creating an Database.
|
||||
*/
|
||||
@@ -1761,24 +1760,6 @@ public class DatabaseConfig {
|
||||
this.readOnlyDataSourceConfig = readOnlyDataSourceConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JNDI name of the DataSource to use.
|
||||
*/
|
||||
public String getDataSourceJndiName() {
|
||||
return dataSourceJndiName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the JNDI name of the DataSource to use.
|
||||
* <p>
|
||||
* By default a prefix of "java:comp/env/jdbc/" is used to lookup the
|
||||
* DataSource. This prefix is not used if dataSourceJndiName starts with
|
||||
* "java:".
|
||||
*/
|
||||
public void setDataSourceJndiName(String dataSourceJndiName) {
|
||||
this.dataSourceJndiName = dataSourceJndiName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a value used to represent TRUE in the database.
|
||||
* <p>
|
||||
@@ -2061,14 +2042,14 @@ public class DatabaseConfig {
|
||||
public void setUuidStateFile(String uuidStateFile) {
|
||||
this.uuidStateFile = uuidStateFile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the V1-UUID-NodeId
|
||||
* Returns the V1-UUID-NodeId
|
||||
*/
|
||||
public String getUuidNodeId() {
|
||||
return uuidNodeId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the V1-UUID-NodeId.
|
||||
*/
|
||||
@@ -2937,7 +2918,6 @@ public class DatabaseConfig {
|
||||
asOfViewSuffix = p.get("asOfViewSuffix", asOfViewSuffix);
|
||||
asOfSysPeriod = p.get("asOfSysPeriod", asOfSysPeriod);
|
||||
historyTableSuffix = p.get("historyTableSuffix", historyTableSuffix);
|
||||
dataSourceJndiName = p.get("dataSourceJndiName", dataSourceJndiName);
|
||||
jdbcFetchSizeFindEach = p.getInt("jdbcFetchSizeFindEach", jdbcFetchSizeFindEach);
|
||||
jdbcFetchSizeFindList = p.getInt("jdbcFetchSizeFindList", jdbcFetchSizeFindList);
|
||||
databasePlatformName = p.get("databasePlatformName", databasePlatformName);
|
||||
@@ -3400,7 +3380,7 @@ public class DatabaseConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if entity classes should be loaded and registered via ModuleInfoLoader.
|
||||
* Return true if entity classes should be loaded and registered via EntityClassRegister.
|
||||
* <p>
|
||||
* When false we either register entity classes via application code or use classpath
|
||||
* scanning to find and register entity classes.
|
||||
@@ -3420,6 +3400,20 @@ public class DatabaseConfig {
|
||||
this.loadModuleInfo = loadModuleInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the naming convention to apply to metrics names.
|
||||
*/
|
||||
public Function<String, String> getMetricNaming() {
|
||||
return metricNaming;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the naming convention to apply to metrics names.
|
||||
*/
|
||||
public void setMetricNaming(Function<String, String> metricNaming) {
|
||||
this.metricNaming = metricNaming;
|
||||
}
|
||||
|
||||
public enum UuidVersion {
|
||||
VERSION4,
|
||||
VERSION1,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import java.util.List;
|
||||
/**
|
||||
* Loads and returns entity classes to register with Ebean databases.
|
||||
*/
|
||||
public interface ModuleInfoLoader {
|
||||
public interface EntityClassRegister {
|
||||
|
||||
/**
|
||||
* Return entity classes to register for a named DB (not default DB).
|
||||
@@ -1,47 +0,0 @@
|
||||
package io.ebean.config;
|
||||
|
||||
import io.ebean.DatabaseFactory;
|
||||
|
||||
/**
|
||||
* Deprecated - please migrate to <code>io.ebean.DatabaseConfig</code>.
|
||||
*
|
||||
* The configuration used for creating a Database.
|
||||
* <p>
|
||||
* Used to programmatically construct a Database and optionally register it
|
||||
* with the DB singleton.
|
||||
* </p>
|
||||
* <p>
|
||||
* If you just use DB without this programmatic configuration DB will read
|
||||
* the application.properties file and take the configuration from there. This usually
|
||||
* includes searching the class path and automatically registering any entity
|
||||
* classes and listeners etc.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* ServerConfig config = new ServerConfig();
|
||||
*
|
||||
* // read the ebean.properties and load
|
||||
* // those settings into this serverConfig object
|
||||
* config.loadFromProperties();
|
||||
*
|
||||
* // explicitly register the entity beans to avoid classpath scanning
|
||||
* config.addClass(Customer.class);
|
||||
* config.addClass(User.class);
|
||||
*
|
||||
* Database database = DatabaseFactory.create(config);
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* Note that ServerConfigProvider provides a standard Java ServiceLoader mechanism that can
|
||||
* be used to apply configuration to the ServerConfig.
|
||||
* </p>
|
||||
*
|
||||
* @author emcgreal
|
||||
* @author rbygrave
|
||||
* @see DatabaseFactory
|
||||
*/
|
||||
@Deprecated
|
||||
public class ServerConfig extends DatabaseConfig {
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package io.ebean.config;
|
||||
|
||||
/**
|
||||
* Deprecated - migrate to DatabaseConfigProvider.
|
||||
* <p>
|
||||
* Provides a ServiceLoader based mechanism to configure a ServerConfig.
|
||||
* <p>
|
||||
* Provide an implementation and register it via the standard Java ServiceLoader mechanism
|
||||
* via a file at <code>META-INF/services/io.ebean.config.ServerConfigProvider</code>.
|
||||
* <p>
|
||||
* If you are using a DI container like Spring or Guice you are unlikely to use this but instead use a
|
||||
* spring specific configuration. When we are not using a DI container we may use this mechanism to
|
||||
* explicitly register the entity beans and avoid classpath scanning.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* public class EbeanConfigProvider implements ServerConfigProvider {
|
||||
*
|
||||
* @Override
|
||||
* public void apply(ServerConfig config) {
|
||||
*
|
||||
* // register the entity bean classes explicitly
|
||||
* config.addClass(Customer.class);
|
||||
* config.addClass(User.class);
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Deprecated
|
||||
public interface ServerConfigProvider {
|
||||
|
||||
/**
|
||||
* Apply the configuration to the ServerConfig.
|
||||
* <p>
|
||||
* Typically we explicitly register entity bean classes and thus avoid classpath scanning.
|
||||
* </p>
|
||||
*/
|
||||
void apply(ServerConfig config);
|
||||
}
|
||||
@@ -1,32 +1,26 @@
|
||||
package io.ebean.config.dbplatform;
|
||||
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.EbeanVersion;
|
||||
import io.ebean.Query;
|
||||
import io.ebean.annotation.PartitionMode;
|
||||
import io.ebean.annotation.PersistBatch;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.CustomDbTypeMapping;
|
||||
import io.ebean.config.PlatformConfig;
|
||||
import io.ebean.util.JdbcClose;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Types;
|
||||
import java.sql.*;
|
||||
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
|
||||
/**
|
||||
* Database platform specific settings.
|
||||
*/
|
||||
public class DatabasePlatform {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger("io.ebean");
|
||||
private static final System.Logger log = EbeanVersion.log;
|
||||
|
||||
/**
|
||||
* Behavior used when ending a query only transaction (at read committed isolation level).
|
||||
@@ -60,7 +54,7 @@ public class DatabasePlatform {
|
||||
* Can we use native java time API objects in
|
||||
* {@link ResultSet#getObject(int, Class)} and
|
||||
* {@link PreparedStatement#setObject(int, Object)}.
|
||||
*
|
||||
* <p>
|
||||
* Not all drivers (DB2 e.g.) will support this.
|
||||
*/
|
||||
protected boolean supportsNativeJavaTime = true;
|
||||
@@ -146,11 +140,6 @@ public class DatabasePlatform {
|
||||
*/
|
||||
protected int clobDbType = Types.CLOB;
|
||||
|
||||
/**
|
||||
* For Oracle treat empty strings as null.
|
||||
*/
|
||||
protected boolean treatEmptyStringsAsNull;
|
||||
|
||||
/**
|
||||
* The database platform name.
|
||||
*/
|
||||
@@ -165,7 +154,7 @@ public class DatabasePlatform {
|
||||
* want to use quoted identifiers for. The backticks get converted to the
|
||||
* appropriate characters in convertQuotedIdentifiers
|
||||
*/
|
||||
private static final char[] QUOTED_IDENTIFIERS = new char[] { '"', '\'', '[', ']', '`' };
|
||||
private static final char[] QUOTED_IDENTIFIERS = new char[]{'"', '\'', '[', ']', '`'};
|
||||
|
||||
/**
|
||||
* The non-escaped like clause (to stop slash being escaped on some platforms).
|
||||
@@ -548,15 +537,6 @@ public class DatabasePlatform {
|
||||
return clobDbType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if empty strings should be treated as null.
|
||||
*
|
||||
* @return true, if checks if is treat empty strings as null
|
||||
*/
|
||||
public boolean isTreatEmptyStringsAsNull() {
|
||||
return treatEmptyStringsAsNull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if a compound ID in (...) type expression needs to be in
|
||||
* expanded form of (a=? and b=?) or (a=? and b=?) or ... rather than (a,b) in
|
||||
@@ -666,7 +646,7 @@ public class DatabasePlatform {
|
||||
if (isQuote(dbName.charAt(dbName.length() - 1))) {
|
||||
return openQuote + dbName.substring(1, dbName.length() - 1) + closeQuote;
|
||||
} else {
|
||||
log.error("Missing backquote on [" + dbName + "]");
|
||||
log.log(ERROR, "Missing backquote on [" + dbName + "]");
|
||||
}
|
||||
} else if (allQuotedIdentifiers) {
|
||||
return openQuote + dbName + closeQuote;
|
||||
@@ -676,8 +656,8 @@ public class DatabasePlatform {
|
||||
}
|
||||
|
||||
private boolean isQuote(char ch) {
|
||||
for (char identifer : QUOTED_IDENTIFIERS) {
|
||||
if (identifer == ch) {
|
||||
for (char identifier : QUOTED_IDENTIFIERS) {
|
||||
if (identifier == ch) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -729,7 +709,7 @@ public class DatabasePlatform {
|
||||
|
||||
protected String withForUpdate(String sql, Query.LockWait lockWait, Query.LockType lockType) {
|
||||
// silently assume the database does not support the "for update" clause.
|
||||
log.info("it seems your database does not support the 'for update' clause");
|
||||
log.log(INFO, "it seems your database does not support the 'for update' clause");
|
||||
return sql;
|
||||
}
|
||||
|
||||
@@ -763,7 +743,7 @@ public class DatabasePlatform {
|
||||
if (!schemaExists(dbSchema, connection)) {
|
||||
Statement query = connection.createStatement();
|
||||
try {
|
||||
log.debug("create schema:{}", dbSchema);
|
||||
log.log(DEBUG, "create schema:{0}", dbSchema);
|
||||
query.executeUpdate("create schema " + dbSchema);
|
||||
} finally {
|
||||
JdbcClose.close(query);
|
||||
@@ -802,20 +782,6 @@ public class DatabasePlatform {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if partitions exist for the given table.
|
||||
*/
|
||||
public boolean tablePartitionsExist(Connection connection, String table) throws SQLException {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the SQL to create an initial partition for the given table.
|
||||
*/
|
||||
public String tablePartitionInit(String tableName, PartitionMode mode, String property, String singlePrimaryKey) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes the like string for this DB-Platform
|
||||
*/
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package io.ebean.config.dbplatform;
|
||||
|
||||
import io.avaje.applog.AppLog;
|
||||
import io.ebean.BackgroundExecutor;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.util.JdbcClose;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.sql.DataSource;
|
||||
@@ -19,12 +18,15 @@ import java.util.TreeSet;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
import static java.lang.System.Logger.Level.ERROR;
|
||||
|
||||
/**
|
||||
* Database sequence based IdGenerator.
|
||||
*/
|
||||
public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
|
||||
protected static final Logger log = LoggerFactory.getLogger("io.ebean.SEQ");
|
||||
protected static final System.Logger log = AppLog.getLogger("io.ebean.SEQ");
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
protected final String seqName;
|
||||
@@ -120,7 +122,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
protected void loadInBackground(final int requestSize) {
|
||||
if (currentlyBackgroundLoading.get()) {
|
||||
// skip as already background loading
|
||||
log.debug("... skip background sequence load (another load in progress)");
|
||||
log.log(DEBUG, "... skip background sequence load (another load in progress)");
|
||||
return;
|
||||
}
|
||||
currentlyBackgroundLoading.set(true);
|
||||
@@ -152,9 +154,6 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
resultSet = statement.executeQuery();
|
||||
|
||||
List<Long> newIds = readIds(resultSet, requestSize);
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("seq:{} loaded:{} sql:{}", seqName, newIds.size(), sql);
|
||||
}
|
||||
if (newIds.isEmpty()) {
|
||||
throw new PersistenceException("Always expecting more than 1 row from " + sql);
|
||||
}
|
||||
@@ -164,7 +163,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
|
||||
} catch (SQLException e) {
|
||||
if (e.getMessage().contains("Database is already closed")) {
|
||||
String msg = "Error getting SEQ when DB shutting down " + e.getMessage();
|
||||
log.error(msg);
|
||||
log.log(ERROR, msg);
|
||||
System.out.println(msg);
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
|
||||
@@ -32,7 +32,12 @@ public class SqlCodeTranslator implements SqlExceptionTranslator {
|
||||
}
|
||||
|
||||
private DataErrorType getErrorType(SQLException e) {
|
||||
DataErrorType errorType = map.get(e.getSQLState());
|
||||
String sqlState = e.getSQLState();
|
||||
while (sqlState == null && e.getCause() instanceof SQLException) {
|
||||
e = (SQLException)e.getCause();
|
||||
sqlState = e.getSQLState();
|
||||
}
|
||||
DataErrorType errorType = map.get(sqlState);
|
||||
if (errorType == null) {
|
||||
// fall back to error code
|
||||
errorType = map.get(String.valueOf(e.getErrorCode()));
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.ebean.event;
|
||||
|
||||
import io.ebean.Database;
|
||||
import io.ebean.EbeanServer;
|
||||
import io.ebean.Transaction;
|
||||
|
||||
/**
|
||||
@@ -9,63 +8,24 @@ import io.ebean.Transaction;
|
||||
*/
|
||||
public interface BeanDeleteIdRequest {
|
||||
|
||||
/**
|
||||
* Deprecated migrate to database().
|
||||
*/
|
||||
@Deprecated
|
||||
EbeanServer getEbeanServer();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to database().
|
||||
*/
|
||||
@Deprecated
|
||||
default Database getDatabase() {
|
||||
return getEbeanServer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DB processing the request.
|
||||
*/
|
||||
default Database database() {
|
||||
return getEbeanServer();
|
||||
}
|
||||
Database database();
|
||||
|
||||
/**
|
||||
* Return the Transaction associated with this request.
|
||||
*/
|
||||
Transaction transaction();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to transaction().
|
||||
*/
|
||||
@Deprecated
|
||||
default Transaction getTransaction() {
|
||||
return transaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bean type of the bean being deleted.
|
||||
*/
|
||||
Class<?> beanType();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to beanType().
|
||||
*/
|
||||
@Deprecated
|
||||
default Class<?> getBeanType() {
|
||||
return beanType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Id value of the bean being deleted.
|
||||
*/
|
||||
Object id();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to id().
|
||||
*/
|
||||
@Deprecated
|
||||
default Object getId() {
|
||||
return id();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.ebean.event;
|
||||
|
||||
import io.ebean.Database;
|
||||
import io.ebean.EbeanServer;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.ValuePair;
|
||||
|
||||
@@ -20,29 +19,13 @@ public interface BeanPersistRequest<T> {
|
||||
/**
|
||||
* Return the DB processing the request.
|
||||
*/
|
||||
default Database database() {
|
||||
return getEbeanServer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated migrate to database().
|
||||
*/
|
||||
@Deprecated
|
||||
EbeanServer getEbeanServer();
|
||||
Database database();
|
||||
|
||||
/**
|
||||
* Return the Transaction associated with this request.
|
||||
*/
|
||||
Transaction transaction();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to transaction().
|
||||
*/
|
||||
@Deprecated
|
||||
default Transaction getTransaction() {
|
||||
return transaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this request is due to cascading persist.
|
||||
* False implies this is a "top level" request.
|
||||
@@ -55,14 +38,6 @@ public interface BeanPersistRequest<T> {
|
||||
*/
|
||||
Set<String> loadedProperties();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to loadedProperties().
|
||||
*/
|
||||
@Deprecated
|
||||
default Set<String> getLoadedProperties() {
|
||||
return loadedProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* For an update this is the set of properties that where updated.
|
||||
* <p>
|
||||
@@ -72,27 +47,11 @@ public interface BeanPersistRequest<T> {
|
||||
*/
|
||||
Set<String> updatedProperties();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to updatedProperties().
|
||||
*/
|
||||
@Deprecated
|
||||
default Set<String> getUpdatedProperties() {
|
||||
return updatedProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags set for dirty properties (used by ElasticSearch integration).
|
||||
*/
|
||||
boolean[] dirtyProperties();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to updatedProperties().
|
||||
*/
|
||||
@Deprecated
|
||||
default boolean[] getDirtyProperties() {
|
||||
return dirtyProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true for an update request if at least one of dirty properties is contained
|
||||
* in the given set of property names.
|
||||
@@ -115,25 +74,9 @@ public interface BeanPersistRequest<T> {
|
||||
*/
|
||||
T bean();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to bean().
|
||||
*/
|
||||
@Deprecated
|
||||
default T getBean() {
|
||||
return bean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of the properties that have changed and their new and old values.
|
||||
*/
|
||||
Map<String, ValuePair> updatedValues();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to updatedValues().
|
||||
*/
|
||||
@Deprecated
|
||||
default Map<String, ValuePair> getUpdatedValues() {
|
||||
return updatedValues();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.ebean.event;
|
||||
|
||||
import io.ebean.Database;
|
||||
import io.ebean.EbeanServer;
|
||||
import io.ebean.Query;
|
||||
import io.ebean.Transaction;
|
||||
|
||||
@@ -13,42 +12,18 @@ public interface BeanQueryRequest<T> {
|
||||
/**
|
||||
* Return the DB processing the request.
|
||||
*/
|
||||
default Database database() {
|
||||
return getEbeanServer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated migrate to database().
|
||||
*/
|
||||
@Deprecated
|
||||
EbeanServer getEbeanServer();
|
||||
Database database();
|
||||
|
||||
/**
|
||||
* Return the Transaction associated with this request.
|
||||
*/
|
||||
Transaction transaction();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to transaction().
|
||||
*/
|
||||
@Deprecated
|
||||
default Transaction getTransaction() {
|
||||
return transaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the query.
|
||||
*/
|
||||
Query<T> query();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to query().
|
||||
*/
|
||||
@Deprecated
|
||||
default Query<T> getQuery() {
|
||||
return query();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if an Id IN expression should have the bind parameters padded.
|
||||
*/
|
||||
|
||||
@@ -10,14 +10,6 @@ public interface BulkTableEvent {
|
||||
*/
|
||||
String tableName();
|
||||
|
||||
/**
|
||||
* Deprecated migrate to tableName().
|
||||
*/
|
||||
@Deprecated
|
||||
default String getTableName() {
|
||||
return tableName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if rows were inserted.
|
||||
*/
|
||||
|
||||
@@ -10,10 +10,9 @@ class ClassUtil {
|
||||
* Return a new instance of the class using the default constructor.
|
||||
*/
|
||||
static Object newInstance(String className) {
|
||||
|
||||
try {
|
||||
Class<?> cls = forName(className);
|
||||
return cls.newInstance();
|
||||
return cls.getDeclaredConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
String msg = "Error constructing " + className;
|
||||
throw new IllegalArgumentException(msg, e);
|
||||
@@ -27,7 +26,6 @@ class ClassUtil {
|
||||
return new ClassLoadContext().forName(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to wrap the context and caller classLoaders (to use/try both).
|
||||
*/
|
||||
@@ -48,7 +46,6 @@ class ClassUtil {
|
||||
}
|
||||
|
||||
public Class<?> forName(String name) throws ClassNotFoundException {
|
||||
|
||||
try {
|
||||
return Class.forName(name, true, contextLoader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
@@ -59,7 +56,6 @@ class ClassUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package io.ebean.event;
|
||||
|
||||
import io.ebean.Database;
|
||||
import io.ebean.EbeanVersion;
|
||||
import io.ebean.service.SpiContainer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.Driver;
|
||||
import java.sql.DriverManager;
|
||||
@@ -13,6 +12,8 @@ import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
|
||||
/**
|
||||
* Manages the shutdown of Ebean.
|
||||
* <p>
|
||||
@@ -20,13 +21,14 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
*/
|
||||
public final class ShutdownManager {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger("io.ebean");
|
||||
private static final System.Logger log = EbeanVersion.log;
|
||||
private static final ReentrantLock lock = new ReentrantLock();
|
||||
private static final List<Database> databases = new ArrayList<>();
|
||||
private static final ShutdownHook shutdownHook = new ShutdownHook();
|
||||
|
||||
private static boolean stopping;
|
||||
private static SpiContainer container;
|
||||
|
||||
static {
|
||||
// Register the Shutdown hook
|
||||
registerShutdownHook();
|
||||
@@ -120,8 +122,8 @@ public final class ShutdownManager {
|
||||
// Already run shutdown...
|
||||
return;
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Ebean shutting down");
|
||||
if (log.isLoggable(DEBUG)) {
|
||||
log.log(DEBUG, "Ebean shutting down");
|
||||
}
|
||||
stopping = true;
|
||||
deregisterShutdownHook();
|
||||
@@ -133,7 +135,7 @@ public final class ShutdownManager {
|
||||
Runnable r = (Runnable) ClassUtil.newInstance(shutdownRunner);
|
||||
r.run();
|
||||
} catch (Exception e) {
|
||||
log.error("Error running custom shutdown runnable", e);
|
||||
log.log(ERROR, "Error running custom shutdown runnable", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +149,7 @@ public final class ShutdownManager {
|
||||
try {
|
||||
server.shutdown();
|
||||
} catch (Exception ex) {
|
||||
log.error("Error executing shutdown runnable", ex);
|
||||
log.log(ERROR, "Error executing shutdown runnable", ex);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -165,10 +167,10 @@ public final class ShutdownManager {
|
||||
while (drivers.hasMoreElements()) {
|
||||
Driver driver = drivers.nextElement();
|
||||
try {
|
||||
log.info("De-registering jdbc driver: " + driver);
|
||||
log.log(INFO, "De-registering jdbc driver: " + driver);
|
||||
DriverManager.deregisterDriver(driver);
|
||||
} catch (SQLException e) {
|
||||
log.error("Error de-registering driver " + driver, e);
|
||||
log.log(ERROR, "Error de-registering driver " + driver, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,6 +206,7 @@ public final class ShutdownManager {
|
||||
private ShutdownHook() {
|
||||
super("EbeanHook");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ShutdownManager.shutdown();
|
||||
|
||||
@@ -2,28 +2,57 @@ package io.ebean.meta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* A simple MetricVisitor that can collect the desired metrics into lists.
|
||||
*/
|
||||
public class BasicMetricVisitor extends AbstractMetricVisitor implements ServerMetrics {
|
||||
|
||||
private final String name;
|
||||
private final Function<String,String> naming;
|
||||
private final List<MetaTimedMetric> timed = new ArrayList<>();
|
||||
private final List<MetaQueryMetric> query = new ArrayList<>();
|
||||
private final List<MetaCountMetric> count = new ArrayList<>();
|
||||
|
||||
public BasicMetricVisitor() {
|
||||
this("db", MetricNamingMatch.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct to reset and collect everything.
|
||||
*/
|
||||
public BasicMetricVisitor() {
|
||||
super(true, true, true, true);
|
||||
public BasicMetricVisitor(String name, Function<String,String> naming) {
|
||||
this(name, naming, true, true, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct specifying reset and what to collect.
|
||||
*/
|
||||
public BasicMetricVisitor(boolean reset, boolean collectTransactionMetrics, boolean collectQueryMetrics, boolean collectL2Metrics) {
|
||||
public BasicMetricVisitor(String name, Function<String,String> naming, boolean reset, boolean collectTransactionMetrics, boolean collectQueryMetrics, boolean collectL2Metrics) {
|
||||
super(reset, collectTransactionMetrics, collectQueryMetrics, collectL2Metrics);
|
||||
this.name = name;
|
||||
this.naming = naming;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<String, String> namingConvention() {
|
||||
return naming;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerMetricsAsJson asJson() {
|
||||
return new MetricsAsJson(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetricData> asData() {
|
||||
return new MetricsAsData(this).data();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,21 +17,20 @@ public interface MetaInfoManager {
|
||||
ServerMetrics collectMetrics();
|
||||
|
||||
/**
|
||||
* Collect the metrics in raw JSON form.
|
||||
* <pre>{@code
|
||||
*
|
||||
* String metricsJson = database.getMetaInfoManager()
|
||||
* .collectMetricsAsJson()
|
||||
* .json();
|
||||
*
|
||||
* }</pre>
|
||||
* Deprecated migrate to collectMetrics().asJson().
|
||||
*/
|
||||
ServerMetricsAsJson collectMetricsAsJson();
|
||||
@Deprecated
|
||||
default ServerMetricsAsJson collectMetricsAsJson() {
|
||||
return collectMetrics().asJson();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the metrics as a list of MetricData.
|
||||
* Deprecated migrate to collectMetrics().asData().
|
||||
*/
|
||||
List<MetricData> collectMetricsAsData();
|
||||
@Deprecated
|
||||
default List<MetricData> collectMetricsAsData() {
|
||||
return collectMetrics().asData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Visit the metrics resetting and collecting/reporting as desired.
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package io.ebean.meta;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Metric naming convention that is exact match.
|
||||
*/
|
||||
public final class MetricNamingMatch implements Function<String, String> {
|
||||
|
||||
public static final Function<String, String> INSTANCE = new MetricNamingMatch();
|
||||
|
||||
@Override
|
||||
public String apply(String name) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,17 @@
|
||||
package io.ebean.meta;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Defines visitor to read and report the transaction and query metrics.
|
||||
*/
|
||||
public interface MetricVisitor {
|
||||
|
||||
/**
|
||||
* Return the naming convention that should be applied to the reported metric names.
|
||||
*/
|
||||
Function<String, String> namingConvention();
|
||||
|
||||
/**
|
||||
* Return true if the metrics should be reset.
|
||||
*/
|
||||
|
||||
+9
-25
@@ -1,12 +1,4 @@
|
||||
package io.ebeaninternal.server.core;
|
||||
|
||||
import io.ebean.Database;
|
||||
import io.ebean.meta.MetaCountMetric;
|
||||
import io.ebean.meta.MetaMetric;
|
||||
import io.ebean.meta.MetaQueryMetric;
|
||||
import io.ebean.meta.MetaTimedMetric;
|
||||
import io.ebean.meta.MetricData;
|
||||
import io.ebean.meta.ServerMetrics;
|
||||
package io.ebean.meta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -14,34 +6,26 @@ import java.util.List;
|
||||
/**
|
||||
* Dump the metrics into a list of MetricData.
|
||||
*/
|
||||
final class DumpMetricsData {
|
||||
final class MetricsAsData {
|
||||
|
||||
private final Database database;
|
||||
private final ServerMetrics metrics;
|
||||
private final List<MetricData> list = new ArrayList<>();
|
||||
|
||||
DumpMetricsData(Database database) {
|
||||
this.database = database;
|
||||
MetricsAsData(ServerMetrics metrics) {
|
||||
this.metrics = metrics;
|
||||
}
|
||||
|
||||
List<MetricData> data() {
|
||||
collect(database.metaInfo().collectMetrics());
|
||||
return list;
|
||||
}
|
||||
|
||||
private void collect(ServerMetrics serverMetrics) {
|
||||
final List<MetaTimedMetric> timedMetrics = serverMetrics.timedMetrics();
|
||||
final List<MetaCountMetric> countMetrics = serverMetrics.countMetrics();
|
||||
final List<MetaQueryMetric> queryMetrics = serverMetrics.queryMetrics();
|
||||
|
||||
for (MetaTimedMetric metric : timedMetrics) {
|
||||
for (MetaTimedMetric metric : metrics.timedMetrics()) {
|
||||
add(metric);
|
||||
}
|
||||
for (MetaCountMetric metric : countMetrics) {
|
||||
for (MetaCountMetric metric : metrics.countMetrics()) {
|
||||
addCount(metric);
|
||||
}
|
||||
for (MetaQueryMetric metric : queryMetrics) {
|
||||
for (MetaQueryMetric metric : metrics.queryMetrics()) {
|
||||
addQuery(metric);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private MetricData create(MetaMetric metric) {
|
||||
+13
-22
@@ -1,25 +1,16 @@
|
||||
package io.ebeaninternal.server.core;
|
||||
|
||||
import io.ebean.Database;
|
||||
import io.ebean.meta.MetaCountMetric;
|
||||
import io.ebean.meta.MetaMetric;
|
||||
import io.ebean.meta.MetaQueryMetric;
|
||||
import io.ebean.meta.MetaTimedMetric;
|
||||
import io.ebean.meta.ServerMetrics;
|
||||
import io.ebean.meta.ServerMetricsAsJson;
|
||||
import io.ebean.meta.SortMetric;
|
||||
package io.ebean.meta;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
final class DumpMetricsJson implements ServerMetricsAsJson {
|
||||
final class MetricsAsJson implements ServerMetricsAsJson {
|
||||
|
||||
private final Database database;
|
||||
private final ServerMetrics metrics;
|
||||
private Appendable writer;
|
||||
/**
|
||||
* By default include sql and location attributes for the initial collection only.
|
||||
* By default, include sql and location attributes for the initial collection only.
|
||||
*/
|
||||
private int includeExtraAttributes = 1;
|
||||
private boolean withHeader = true;
|
||||
@@ -29,8 +20,8 @@ final class DumpMetricsJson implements ServerMetricsAsJson {
|
||||
private int listCounter;
|
||||
private int objKeyCounter;
|
||||
|
||||
DumpMetricsJson(Database database) {
|
||||
this.database = database;
|
||||
MetricsAsJson(ServerMetrics metrics) {
|
||||
this.metrics = metrics;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,24 +57,24 @@ final class DumpMetricsJson implements ServerMetricsAsJson {
|
||||
@Override
|
||||
public String json() {
|
||||
writer = new StringWriter();
|
||||
collect(database.metaInfo().collectMetrics());
|
||||
collect();
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Appendable buffer) {
|
||||
writer = buffer;
|
||||
collect(database.metaInfo().collectMetrics());
|
||||
collect();
|
||||
}
|
||||
|
||||
private void collect(ServerMetrics serverMetrics) {
|
||||
private void collect() {
|
||||
try {
|
||||
start();
|
||||
for (MetaTimedMetric metric : serverMetrics.timedMetrics()) {
|
||||
for (MetaTimedMetric metric : metrics.timedMetrics()) {
|
||||
logTimed(metric);
|
||||
}
|
||||
|
||||
List<MetaCountMetric> countMetrics = serverMetrics.countMetrics();
|
||||
List<MetaCountMetric> countMetrics = metrics.countMetrics();
|
||||
if (!countMetrics.isEmpty()) {
|
||||
if (sortBy != null) {
|
||||
countMetrics.sort(SortMetric.COUNT_NAME);
|
||||
@@ -93,7 +84,7 @@ final class DumpMetricsJson implements ServerMetricsAsJson {
|
||||
}
|
||||
}
|
||||
|
||||
List<MetaQueryMetric> queryMetrics = serverMetrics.queryMetrics();
|
||||
List<MetaQueryMetric> queryMetrics = metrics.queryMetrics();
|
||||
if (!queryMetrics.isEmpty()) {
|
||||
if (sortBy != null) {
|
||||
queryMetrics.sort(sortBy);
|
||||
@@ -112,7 +103,7 @@ final class DumpMetricsJson implements ServerMetricsAsJson {
|
||||
if (withHeader) {
|
||||
objStart();
|
||||
key("db");
|
||||
val(database.name());
|
||||
val(metrics.name());
|
||||
key("metrics");
|
||||
listStart();
|
||||
}
|
||||
@@ -7,6 +7,21 @@ import java.util.List;
|
||||
*/
|
||||
public interface ServerMetrics {
|
||||
|
||||
/**
|
||||
* Return the name of the database these metrics were obtained for.
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* Return ServerMetricsAsJson to build the metrics as JSON content.
|
||||
*/
|
||||
ServerMetricsAsJson asJson();
|
||||
|
||||
/**
|
||||
* Return the metrics as a list of MetricData.
|
||||
*/
|
||||
List<MetricData> asData();
|
||||
|
||||
/**
|
||||
* Return timed metrics for Transactions, labelled SqlQuery, labelled SqlUpdate.
|
||||
*/
|
||||
|
||||
@@ -18,79 +18,31 @@ public interface SpiServer extends Database {
|
||||
*/
|
||||
DatabaseConfig config();
|
||||
|
||||
/**
|
||||
* Migrate to config().
|
||||
*/
|
||||
@Deprecated
|
||||
default DatabaseConfig getServerConfig() {
|
||||
return config();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DatabasePlatform for this database.
|
||||
*/
|
||||
DatabasePlatform databasePlatform();
|
||||
|
||||
/**
|
||||
* Migrate to config().
|
||||
*/
|
||||
@Deprecated
|
||||
default DatabasePlatform getDatabasePlatform() {
|
||||
return databasePlatform();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the bean types registered on this server instance.
|
||||
*/
|
||||
List<? extends BeanType<?>> beanTypes();
|
||||
|
||||
/**
|
||||
* Migrate to beanTypes().
|
||||
*/
|
||||
@Deprecated
|
||||
default List<? extends BeanType<?>> getBeanTypes() {
|
||||
return beanTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bean type for a given entity bean class.
|
||||
*/
|
||||
<T> BeanType<T> beanType(Class<T> beanClass);
|
||||
|
||||
/**
|
||||
* Migrate to beanType().
|
||||
*/
|
||||
@Deprecated
|
||||
default <T> BeanType<T> getBeanType(Class<T> beanClass) {
|
||||
return beanType(beanClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bean types mapped to the given base table.
|
||||
*/
|
||||
List<? extends BeanType<?>> beanTypes(String baseTableName);
|
||||
|
||||
/**
|
||||
* Migrate to beanTypes().
|
||||
*/
|
||||
@Deprecated
|
||||
default List<? extends BeanType<?>> getBeanTypes(String baseTableName) {
|
||||
return beanTypes(baseTableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bean type for a given doc store queueId.
|
||||
*/
|
||||
BeanType<?> beanTypeForQueueId(String queueId);
|
||||
|
||||
/**
|
||||
* Migrate to beanTypes().
|
||||
*/
|
||||
@Deprecated
|
||||
default BeanType<?> getBeanTypeForQueueId(String queueId) {
|
||||
return beanTypeForQueueId(queueId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a BeanLoader.
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package io.ebean.text.csv;
|
||||
|
||||
import io.ebean.Database;
|
||||
import io.ebean.EbeanVersion;
|
||||
import io.ebean.Transaction;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
import static java.lang.System.Logger.Level.INFO;
|
||||
|
||||
/**
|
||||
* Provides the default implementation of CsvCallback.
|
||||
@@ -20,7 +22,7 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
public class DefaultCsvCallback<T> implements CsvCallback<T> {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DefaultCsvCallback.class);
|
||||
private static final System.Logger log = EbeanVersion.log;
|
||||
|
||||
/**
|
||||
* The transaction to use (if not using CsvCallback).
|
||||
@@ -128,7 +130,7 @@ public class DefaultCsvCallback<T> implements CsvCallback<T> {
|
||||
// related beans (e.g. customer -> customer.billingAddress
|
||||
server.save(bean, transaction);
|
||||
if (logInfoFrequency > 0 && (row % logInfoFrequency == 0)) {
|
||||
log.debug("processed {} rows", row);
|
||||
log.log(DEBUG, "processed {0} rows", row);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +141,7 @@ public class DefaultCsvCallback<T> implements CsvCallback<T> {
|
||||
public void end(int row) {
|
||||
commitTransactionIfCreated();
|
||||
exeTime = System.currentTimeMillis() - startTime;
|
||||
log.info("Csv finished, rows[{}] exeMillis[{}]", row, exeTime);
|
||||
log.log(INFO, "Csv finished, rows[{0}] exeMillis[{1}]", row, exeTime);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,7 +162,6 @@ public class DefaultCsvCallback<T> implements CsvCallback<T> {
|
||||
transaction = server.beginTransaction();
|
||||
createdTransaction = true;
|
||||
if (persistBatchSize > 1) {
|
||||
log.debug("Creating transaction, batchSize[{}]", persistBatchSize);
|
||||
transaction.setBatchMode(true);
|
||||
transaction.setBatchSize(persistBatchSize);
|
||||
transaction.setGetGeneratedKeys(false);
|
||||
@@ -168,7 +169,6 @@ public class DefaultCsvCallback<T> implements CsvCallback<T> {
|
||||
// explicitly turn off JDBC batching in case
|
||||
// is has been turned on globally
|
||||
transaction.setBatchMode(false);
|
||||
log.debug("Creating transaction with no JDBC batching");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -180,7 +180,6 @@ public class DefaultCsvCallback<T> implements CsvCallback<T> {
|
||||
protected void commitTransactionIfCreated() {
|
||||
if (createdTransaction) {
|
||||
transaction.commit();
|
||||
log.debug("Committed transaction");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +190,6 @@ public class DefaultCsvCallback<T> implements CsvCallback<T> {
|
||||
protected void rollbackTransactionIfCreated(Throwable e) {
|
||||
if (createdTransaction) {
|
||||
transaction.rollback(e);
|
||||
log.debug("Rolled back transaction");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
package io.ebean.util;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import io.ebean.EbeanVersion;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import static java.lang.System.Logger.Level.WARNING;
|
||||
|
||||
/**
|
||||
* Utility for closing raw Jdbc resources.
|
||||
*/
|
||||
public final class JdbcClose {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger("io.ebean");
|
||||
private static final System.Logger log = EbeanVersion.log;
|
||||
|
||||
/**
|
||||
* Close the resultSet logging if an error occurs.
|
||||
@@ -24,7 +25,7 @@ public final class JdbcClose {
|
||||
statement.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.warn("Error closing statement", e);
|
||||
log.log(WARNING, "Error closing statement", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +38,7 @@ public final class JdbcClose {
|
||||
resultSet.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.warn("Error closing resultSet", e);
|
||||
log.log(WARNING, "Error closing resultSet", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +51,7 @@ public final class JdbcClose {
|
||||
connection.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.warn("Error closing connection", e);
|
||||
log.log(WARNING, "Error closing connection", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +64,7 @@ public final class JdbcClose {
|
||||
connection.rollback();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.warn("Error on connection rollback", e);
|
||||
log.log(WARNING, "Error on connection rollback", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +77,7 @@ public final class JdbcClose {
|
||||
stmt.cancel();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.warn("Error on cancelling statement", e);
|
||||
log.log(WARNING, "Error on cancelling statement", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@ public final class SplitName {
|
||||
}
|
||||
|
||||
private static String[] split(String name, boolean last) {
|
||||
|
||||
int pos = last ? name.lastIndexOf('.') : name.indexOf('.');
|
||||
if (pos == -1) {
|
||||
if (last) {
|
||||
|
||||
@@ -15,10 +15,12 @@ module io.ebean.api {
|
||||
requires transitive persistence.api;
|
||||
requires transitive io.ebean.annotation;
|
||||
requires transitive io.ebean.datasource.api;
|
||||
requires transitive org.slf4j;
|
||||
requires transitive io.avaje.applog;
|
||||
|
||||
requires static org.slf4j;
|
||||
requires static io.ebean.types;
|
||||
requires static com.fasterxml.jackson.core;
|
||||
requires static com.fasterxml.jackson.databind;
|
||||
requires static javax.servlet.api;
|
||||
|
||||
exports io.ebean;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
${project.version}
|
||||
@@ -0,0 +1,42 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class NodeUsageCollectorTest {
|
||||
|
||||
private final Listener listener = new Listener();
|
||||
|
||||
private final ObjectGraphNode node = new ObjectGraphNode((ObjectGraphOrigin) null, "foo");
|
||||
|
||||
/**
|
||||
* Run this manually as we make use of explicit GC call here which is dubious.
|
||||
*/
|
||||
@Disabled
|
||||
@Test
|
||||
void test() throws InterruptedException {
|
||||
NodeUsageCollector c = new NodeUsageCollector(node, listener);
|
||||
c.addUsed("a");
|
||||
c.addUsed("b");
|
||||
c = null;
|
||||
|
||||
System.gc();
|
||||
Thread.sleep(100);
|
||||
|
||||
assertThat(listener.collectCount).isEqualTo(1);
|
||||
assertThat(node).isNotNull();
|
||||
}
|
||||
|
||||
static class Listener implements NodeUsageListener {
|
||||
|
||||
int collectCount;
|
||||
|
||||
@Override
|
||||
public void collectNodeUsage(NodeUsageCollector.State collector) {
|
||||
collectCount++;
|
||||
System.out.println("collectNodeUsage " + collector);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,12 +166,76 @@ class ToStringBuilderTest {
|
||||
assertThat(toStringFor(list)).isEqualTo("{a:Recurse@1(id:1, nm:a), b:Recurse@2(id:2, nm:b)}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void map_recurse() {
|
||||
final ParamStore paramStore = new ParamStore(1);
|
||||
|
||||
paramStore.map.put("aaa", new ParamValue(1, paramStore));
|
||||
paramStore.map.put("bbb", new ParamValue(2, paramStore));
|
||||
|
||||
assertThat(toStringFor(paramStore))
|
||||
.isEqualTo("ParamStore@0(id:1, map:{aaa:ParamValue@1(id:1, pm:ParamStore@0), bbb:ParamValue@2(id:2, pm:ParamStore@0)})");
|
||||
}
|
||||
|
||||
private String toStringFor(ToStringAware aware) {
|
||||
ToStringBuilder builder = new ToStringBuilder();
|
||||
aware.toString(builder);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
static final class ParamValue implements ToStringAware {
|
||||
|
||||
final int id;
|
||||
|
||||
final ParamStore parentModel;
|
||||
|
||||
ParamValue(final int id, final ParamStore parentModel) {
|
||||
this.id = id;
|
||||
this.parentModel = parentModel;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
ToStringBuilder builder = new ToStringBuilder();
|
||||
toString(builder);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toString(ToStringBuilder builder) {
|
||||
builder.start(this);
|
||||
builder.add("id", id);
|
||||
builder.add("pm", parentModel);
|
||||
builder.end();
|
||||
}
|
||||
}
|
||||
|
||||
static final class ParamStore implements ToStringAware {
|
||||
|
||||
final int id;
|
||||
|
||||
final Map<String, ParamValue> map = new HashMap<>();
|
||||
|
||||
|
||||
ParamStore(final int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
ToStringBuilder builder = new ToStringBuilder();
|
||||
toString(builder);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toString(ToStringBuilder builder) {
|
||||
builder.start(this);
|
||||
builder.add("id", id);
|
||||
builder.add("map", map);
|
||||
builder.end();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static final class Recurse implements ToStringAware {
|
||||
|
||||
final int id;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
<!-- <parent>-->
|
||||
<!-- <groupId>org.avaje</groupId>-->
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
|
||||
<name>ebean autotune</name>
|
||||
@@ -26,7 +26,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<tiles>
|
||||
<tile>io.ebean.tile:enhancement:13.3.0</tile>
|
||||
<tile>io.ebean.tile:enhancement:13.6.5</tile>
|
||||
</tiles>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
+1
@@ -143,6 +143,7 @@ public class BaseQueryTuner {
|
||||
switch (type) {
|
||||
case COUNT:
|
||||
case ATTRIBUTE:
|
||||
case ATTRIBUTE_SET:
|
||||
case ID_LIST:
|
||||
case UPDATE:
|
||||
case DELETE:
|
||||
|
||||
+15
-14
@@ -1,5 +1,6 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.avaje.applog.AppLog;
|
||||
import io.ebean.config.AutoTuneConfig;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
@@ -7,8 +8,6 @@ import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.autotune.AutoTuneService;
|
||||
import io.ebeaninternal.server.autotune.model.Autotune;
|
||||
import io.ebeaninternal.server.autotune.model.Origin;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -16,12 +15,14 @@ import java.io.InputStream;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static java.lang.System.Logger.Level.*;
|
||||
|
||||
/**
|
||||
* Implementation of the AutoTuneService which is comprised of profiling and query tuning.
|
||||
*/
|
||||
public class DefaultAutoTuneService implements AutoTuneService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DefaultAutoTuneService.class);
|
||||
private static final System.Logger logger = AppLog.getLogger(DefaultAutoTuneService.class);
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
@@ -111,7 +112,7 @@ public class DefaultAutoTuneService implements AutoTuneService {
|
||||
if (stream != null) {
|
||||
loadAutoTuneProfiling(AutoTuneXmlReader.read(stream));
|
||||
} else {
|
||||
logger.warn("AutoTune file {} not found - no initial automatic query tuning", tuningFile);
|
||||
logger.log(WARNING, "AutoTune file {0} not found - no initial automatic query tuning", tuningFile);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Error on auto close of " + tuningFile, e);
|
||||
@@ -120,7 +121,7 @@ public class DefaultAutoTuneService implements AutoTuneService {
|
||||
}
|
||||
|
||||
private void loadAutoTuneProfiling(Autotune profiling) {
|
||||
logger.info("AutoTune loading {} tuning entries", profiling.getOrigin().size());
|
||||
logger.log(INFO, "AutoTune loading {0} tuning entries", profiling.getOrigin().size());
|
||||
for (Origin origin : profiling.getOrigin()) {
|
||||
queryTuner.put(origin);
|
||||
}
|
||||
@@ -141,17 +142,17 @@ public class DefaultAutoTuneService implements AutoTuneService {
|
||||
event.process();
|
||||
if (event.isEmpty()) {
|
||||
long exeMillis = System.currentTimeMillis() - start;
|
||||
logger.debug("No query tuning updates for server:{} executionMillis:{}", serverName, exeMillis);
|
||||
logger.log(DEBUG, "No query tuning updates for server:{0} executionMillis:{1}", serverName, exeMillis);
|
||||
|
||||
} else {
|
||||
// report the query tuning changes that have been made
|
||||
runtimeChangeCount += event.getChangeCount();
|
||||
event.writeFile(profilingFile + "-" + serverName + "-update");
|
||||
long exeMillis = System.currentTimeMillis() - start;
|
||||
logger.info("query tuning updates - new:{} diff:{} for server:{} executionMillis:{}", event.getNewCount(), event.getDiffCount(), serverName, exeMillis);
|
||||
logger.log(INFO, "query tuning updates - new:{0} diff:{1} for server:{2} executionMillis:{3}", event.getNewCount(), event.getDiffCount(), serverName, exeMillis);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.error("Error collecting or applying automatic query tuning", e);
|
||||
logger.log(ERROR, "Error collecting or applying automatic query tuning", e);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
@@ -172,11 +173,11 @@ public class DefaultAutoTuneService implements AutoTuneService {
|
||||
AutoTuneDiffCollection event = new AutoTuneDiffCollection(profiling, queryTuner, false);
|
||||
event.process();
|
||||
if (event.isEmpty()) {
|
||||
logger.info("No new or diff entries for profiling server:{}", serverName);
|
||||
logger.log(INFO, "No new or diff entries for profiling server:{0}", serverName);
|
||||
|
||||
} else {
|
||||
event.writeFile(profilingFile + "-" + serverName);
|
||||
logger.info("writing new:{} diff:{} profiling entries for server:{}", event.getNewCount(), event.getDiffCount(), serverName);
|
||||
logger.log(INFO, "writing new:{0} diff:{1} profiling entries for server:{2}", event.getNewCount(), event.getDiffCount(), serverName);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@@ -196,7 +197,7 @@ public class DefaultAutoTuneService implements AutoTuneService {
|
||||
private void outputAllTuning() {
|
||||
|
||||
if (runtimeChangeCount == 0) {
|
||||
logger.info("no runtime query tuning changes for server:{}", serverName);
|
||||
logger.log(INFO, "no runtime query tuning changes for server:{0}", serverName);
|
||||
|
||||
} else {
|
||||
AutoTuneAllCollection event = new AutoTuneAllCollection(queryTuner);
|
||||
@@ -205,12 +206,12 @@ public class DefaultAutoTuneService implements AutoTuneService {
|
||||
if (existingTuning.exists()) {
|
||||
// rename the existing autotune.xml file (appending 'now')
|
||||
if (!existingTuning.renameTo(new File(tuningFile + "." + AutoTuneXmlWriter.now()))) {
|
||||
logger.warn("Failed to rename autotune file [{}]", tuningFile);
|
||||
logger.log(WARNING, "Failed to rename autotune file [{0}]", tuningFile);
|
||||
}
|
||||
}
|
||||
|
||||
event.writeFile(tuningFile, false);
|
||||
logger.info("query tuning detected [{}] changes, writing all [{}] tuning entries for server:{}", runtimeChangeCount, size, serverName);
|
||||
logger.log(INFO, "query tuning detected [{0}] changes, writing all [{1}] tuning entries for server:{2}", runtimeChangeCount, size, serverName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +280,7 @@ public class DefaultAutoTuneService implements AutoTuneService {
|
||||
} catch (InterruptedException e) {
|
||||
// restore the interrupted status
|
||||
Thread.currentThread().interrupt();
|
||||
logger.warn("Error while sleeping after System.gc() request.", e);
|
||||
logger.log(WARNING, "Error while sleeping after System.gc() request.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -91,8 +91,8 @@ public class ProfileManager implements ProfilingListener {
|
||||
* is called on the bean.
|
||||
*/
|
||||
@Override
|
||||
public void collectNodeUsage(NodeUsageCollector usageCollector) {
|
||||
ProfileOrigin profileOrigin = getProfileOrigin(usageCollector.getNode().getOriginQueryPoint());
|
||||
public void collectNodeUsage(NodeUsageCollector.State usageCollector) {
|
||||
ProfileOrigin profileOrigin = getProfileOrigin(usageCollector.node().getOriginQueryPoint());
|
||||
profileOrigin.collectUsageInfo(usageCollector);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -151,9 +151,9 @@ public class ProfileOrigin {
|
||||
/**
|
||||
* Collect the usage information for from a instance for this node.
|
||||
*/
|
||||
public void collectUsageInfo(NodeUsageCollector profile) {
|
||||
public void collectUsageInfo(NodeUsageCollector.State profile) {
|
||||
if (!profile.isEmpty()) {
|
||||
getNodeStats(profile.getNode().getPath()).collectUsageInfo(profile);
|
||||
getNodeStats(profile.node().getPath()).collectUsageInfo(profile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -1,5 +1,6 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.avaje.applog.AppLog;
|
||||
import io.ebean.bean.NodeUsageCollector;
|
||||
import io.ebean.text.PathProperties;
|
||||
import io.ebean.util.SplitName;
|
||||
@@ -7,19 +8,19 @@ import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssoc;
|
||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static java.lang.System.Logger.Level.WARNING;
|
||||
|
||||
/**
|
||||
* Collects usages statistics for a given node in the object graph.
|
||||
*/
|
||||
public class ProfileOriginNodeUsage {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ProfileOriginNodeUsage.class);
|
||||
private static final System.Logger logger = AppLog.getLogger(ProfileOriginNodeUsage.class);
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
@@ -45,7 +46,7 @@ public class ProfileOriginNodeUsage {
|
||||
if (path != null) {
|
||||
ElPropertyValue elGetValue = rootDesc.elGetValue(path);
|
||||
if (elGetValue == null) {
|
||||
logger.warn("AutoTune: Can't find join for path[" + path + "] for " + rootDesc.name());
|
||||
logger.log(WARNING, "AutoTune: Can't find join for path[" + path + "] for " + rootDesc.name());
|
||||
return;
|
||||
} else {
|
||||
BeanProperty beanProperty = elGetValue.beanProperty();
|
||||
@@ -61,7 +62,7 @@ public class ProfileOriginNodeUsage {
|
||||
for (String propName : aggregateUsed) {
|
||||
BeanProperty beanProp = desc.findPropertyFromPath(propName);
|
||||
if (beanProp == null) {
|
||||
logger.warn("AutoTune: Can't find property[" + propName + "] for " + desc.name());
|
||||
logger.log(WARNING, "AutoTune: Can't find property[" + propName + "] for " + desc.name());
|
||||
|
||||
} else {
|
||||
if (beanProp.isId()) {
|
||||
@@ -103,11 +104,10 @@ public class ProfileOriginNodeUsage {
|
||||
/**
|
||||
* Collect usage from a node.
|
||||
*/
|
||||
protected void collectUsageInfo(NodeUsageCollector profile) {
|
||||
protected void collectUsageInfo(NodeUsageCollector.State profile) {
|
||||
lock.lock();
|
||||
try {
|
||||
Set<String> used = profile.getUsed();
|
||||
|
||||
Set<String> used = profile.used();
|
||||
profileCount++;
|
||||
if (!used.isEmpty()) {
|
||||
profileUsedCount++;
|
||||
|
||||
+22
-12
@@ -1,6 +1,7 @@
|
||||
package io.ebeaninternal.server.autotune.service;
|
||||
|
||||
import io.ebean.bean.NodeUsageCollector;
|
||||
import io.ebean.bean.NodeUsageListener;
|
||||
import io.ebean.bean.ObjectGraphNode;
|
||||
import io.ebean.bean.ObjectGraphOrigin;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
@@ -13,6 +14,15 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ProfileOriginTest extends BaseTestCase {
|
||||
|
||||
static class Noop implements NodeUsageListener {
|
||||
@Override
|
||||
public void collectNodeUsage(NodeUsageCollector.State state) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
private final NodeUsageListener listener = new Noop();
|
||||
|
||||
private final BeanDescriptor<Order> desc = getBeanDescriptor(Order.class);
|
||||
|
||||
@Test
|
||||
@@ -23,7 +33,7 @@ public class ProfileOriginTest extends BaseTestCase {
|
||||
c.addUsed("name");
|
||||
|
||||
ProfileOrigin po = new ProfileOrigin(null, false, 1, 1);
|
||||
po.collectUsageInfo(c);
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
OrmQueryDetail detail = po.buildDetail(desc);
|
||||
|
||||
@@ -38,11 +48,11 @@ public class ProfileOriginTest extends BaseTestCase {
|
||||
c.addUsed("name");
|
||||
|
||||
ProfileOrigin po = new ProfileOrigin(null, false, 1, 1);
|
||||
po.collectUsageInfo(c);
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
c = node(null);
|
||||
c.addUsed("orderDate");
|
||||
po.collectUsageInfo(c);
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
OrmQueryDetail detail = po.buildDetail(desc);
|
||||
|
||||
@@ -56,11 +66,11 @@ public class ProfileOriginTest extends BaseTestCase {
|
||||
c.addUsed("id");
|
||||
|
||||
ProfileOrigin po = new ProfileOrigin(null, false, 1, 1);
|
||||
po.collectUsageInfo(c);
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
c = node(null);
|
||||
c.addUsed("orderDate");
|
||||
po.collectUsageInfo(c);
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
OrmQueryDetail detail = po.buildDetail(desc);
|
||||
|
||||
@@ -75,15 +85,15 @@ public class ProfileOriginTest extends BaseTestCase {
|
||||
NodeUsageCollector c = node(null);
|
||||
c.addUsed("orderDate");
|
||||
c.addUsed("customer");
|
||||
po.collectUsageInfo(c);
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
c = node("customer");
|
||||
c.addUsed("billingAddress");
|
||||
po.collectUsageInfo(c);
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
c = node("customer.billingAddress");
|
||||
c.addUsed("id");
|
||||
po.collectUsageInfo(c);
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
OrmQueryDetail detail = po.buildDetail(desc);
|
||||
|
||||
@@ -100,20 +110,20 @@ public class ProfileOriginTest extends BaseTestCase {
|
||||
|
||||
NodeUsageCollector c = node(null);
|
||||
c.addUsed("customer");
|
||||
po.collectUsageInfo(c);
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
c = node("customer");
|
||||
c.addUsed("id");
|
||||
c.addUsed("name");
|
||||
c.addUsed("note");
|
||||
c.addUsed("billingAddress");
|
||||
po.collectUsageInfo(c);
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
//fetch details.product (id,name)
|
||||
c = node("customer.billingAddress");
|
||||
c.addUsed("id");
|
||||
c.addUsed("line1");
|
||||
po.collectUsageInfo(c);
|
||||
po.collectUsageInfo(c.state());
|
||||
|
||||
OrmQueryDetail detail = po.buildDetail(desc);
|
||||
assertThat(detail.asString()).isEqualTo("fetch customer (name,note) fetch customer.billingAddress (line1)");
|
||||
@@ -121,7 +131,7 @@ public class ProfileOriginTest extends BaseTestCase {
|
||||
|
||||
private NodeUsageCollector node(String path) {
|
||||
ObjectGraphNode node = new ObjectGraphNode((ObjectGraphOrigin)null, path);
|
||||
return new NodeUsageCollector(node, null);
|
||||
return new NodeUsageCollector(node, listener);
|
||||
}
|
||||
|
||||
// @Test
|
||||
|
||||
+35
-17
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean bom</name>
|
||||
@@ -18,6 +18,24 @@
|
||||
|
||||
<!-- dependencies external to this ebean.git build -->
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>persistence-api</artifactId>
|
||||
<version>${ebean-persistence-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-annotation</artifactId>
|
||||
<version>${ebean-annotation.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-types</artifactId>
|
||||
<version>${ebean-types.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-runner</artifactId>
|
||||
@@ -62,8 +80,8 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test-docker</artifactId>
|
||||
<version>${ebean-test-docker.version}</version>
|
||||
<artifactId>ebean-test-containers</artifactId>
|
||||
<version>${ebean-test-containers.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- modules -->
|
||||
@@ -71,88 +89,88 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-xml</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-autotune</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>querybean-generator</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>kotlin-querybean-generator</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgis</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-redis</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
@@ -16,7 +16,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -16,25 +16,24 @@ import java.sql.SQLException;
|
||||
* <p>
|
||||
* Scalar in the sense that the types are not compound types. Scalar types only
|
||||
* map to a single database column.
|
||||
* </p>
|
||||
* <p>
|
||||
* These types fall into two categories. Types that are mapped natively to JDBC
|
||||
* types and the rest. Types that map to native JDBC types do not require any
|
||||
* data type conversion to be persisted to the database. These are java types
|
||||
* that map via java.sql.Types.
|
||||
* </p>
|
||||
* <p>
|
||||
* Types that are not native to JDBC require some conversion. These include some
|
||||
* common java types such as java.util.Date, java.util.Calendar,
|
||||
* java.math.BigInteger.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that Booleans may be native for some databases and require conversion on
|
||||
* other databases.
|
||||
* </p>
|
||||
*/
|
||||
public interface ScalarType<T> extends StringParser, StringFormatter, ScalarDataReader<T> {
|
||||
|
||||
/**
|
||||
* Return true for types that do mutation detection based on json content.
|
||||
*/
|
||||
default boolean isJsonMapper() {
|
||||
return false;
|
||||
}
|
||||
@@ -43,38 +42,40 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
* Return true if this is a binary type and can not support parse() and format() from/to string.
|
||||
* This allows Ebean to optimise marshalling types to string.
|
||||
*/
|
||||
boolean isBinaryType();
|
||||
default boolean isBinaryType() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this is a mutable scalar type (like hstore).
|
||||
*/
|
||||
boolean isMutable();
|
||||
default boolean isMutable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* For mutable scalarType's return true if the value is dirty.
|
||||
* Non-dirty properties may be excluded from updates.
|
||||
*/
|
||||
boolean isDirty(Object value);
|
||||
default boolean isDirty(Object value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default DB column length for this type.
|
||||
* <p>
|
||||
* If a BeanProperty has no explicit length defined then this length should
|
||||
* be assigned.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is primarily to support defining a length on Enum types (to
|
||||
* supplement defining the length on the BeanProperty directly).
|
||||
* </p>
|
||||
*/
|
||||
int getLength();
|
||||
default int getLength() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the type is native to JDBC.
|
||||
* <p>
|
||||
* If it is native to JDBC then its values/instances do not need to be
|
||||
* converted to and from an associated JDBC type.
|
||||
* </p>
|
||||
*/
|
||||
boolean isJdbcNative();
|
||||
|
||||
@@ -83,16 +84,13 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
* <p>
|
||||
* This type should be consistent with the toJdbcType() method in converting
|
||||
* the type to the appropriate type for binding to preparedStatements.
|
||||
* </p>
|
||||
*/
|
||||
int getJdbcType();
|
||||
|
||||
/**
|
||||
* Return the type that matches the bean property type.
|
||||
* <p>
|
||||
* This represents the 'logical' type rather than the JDBC type this maps
|
||||
* to.
|
||||
* </p>
|
||||
* This represents the 'logical' type rather than the JDBC type this maps to.
|
||||
*/
|
||||
Class<T> getType();
|
||||
|
||||
@@ -104,7 +102,7 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
T read(DataReader reader) throws SQLException;
|
||||
|
||||
/**
|
||||
* Ignore the reading of this value. Typically this means moving the index
|
||||
* Ignore the reading of this value. Typically, this means moving the index
|
||||
* position in the ResultSet.
|
||||
*/
|
||||
void loadIgnore(DataReader reader);
|
||||
@@ -114,20 +112,16 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
* <p>
|
||||
* value may need to be converted from the logical bean property type to the
|
||||
* JDBC type.
|
||||
* </p>
|
||||
*/
|
||||
void bind(DataBinder binder, T value) throws SQLException;
|
||||
|
||||
/**
|
||||
* Convert the value as necessary to the JDBC type.
|
||||
* <p>
|
||||
* Note that this should also match the type as per the getJdbcType()
|
||||
* method.
|
||||
* </p>
|
||||
* Note that this should also match the type as per the getJdbcType() method.
|
||||
* <p>
|
||||
* This is typically used when the matching type is used in a where clause
|
||||
* and we use this to ensure it is an appropriate jdbc type.
|
||||
* </p>
|
||||
*/
|
||||
Object toJdbcType(Object value);
|
||||
|
||||
@@ -135,19 +129,14 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
* Convert the value as necessary to the logical Bean type.
|
||||
* <p>
|
||||
* The type as per the bean property.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is used to automatically convert id values (typically from a string
|
||||
* to a int, long or UUID).
|
||||
* </p>
|
||||
*/
|
||||
T toBeanType(Object value);
|
||||
|
||||
/**
|
||||
* Convert the type into a string representation.
|
||||
* <p>
|
||||
* Reciprocal of parse().
|
||||
* </p>
|
||||
*/
|
||||
String formatValue(T value);
|
||||
|
||||
@@ -155,10 +144,8 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
* Convert the type into a string representation.
|
||||
* <p>
|
||||
* This assumes the value is of the correct type.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is so that ScalarType also implements the StringFormatter interface.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
String format(Object value);
|
||||
@@ -167,10 +154,6 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
* Convert the string value to the appropriate java object.
|
||||
* <p>
|
||||
* Mostly used to support CSV, JSON and XML parsing.
|
||||
* </p>
|
||||
* <p>
|
||||
* Reciprocal of formatValue().
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
T parse(String value);
|
||||
@@ -183,29 +166,32 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
/**
|
||||
* Return true if the type can accept long systemTimeMillis input.
|
||||
* <p>
|
||||
* This is used to determine if is is sensible to use the
|
||||
* This is used to determine if it is sensible to use the
|
||||
* {@link #convertFromMillis(long)} method.
|
||||
* </p>
|
||||
* <p>
|
||||
* This includes the Date, Calendar, sql Date, Time, Timestamp, JODA types
|
||||
* as well as Long, BigDecimal and String (although it generally is not
|
||||
* expected to parse systemTimeMillis to a String or BigDecimal).
|
||||
* </p>
|
||||
*/
|
||||
boolean isDateTimeCapable();
|
||||
default boolean isDateTimeCapable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the value into a long version value.
|
||||
*/
|
||||
long asVersion(T value);
|
||||
default long asVersion(T value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the systemTimeMillis into the appropriate java object.
|
||||
* <p>
|
||||
* For non dateTime types this will throw an exception.
|
||||
* </p>
|
||||
*/
|
||||
T convertFromMillis(long dateTime);
|
||||
default T convertFromMillis(long dateTime) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the value from binary input.
|
||||
@@ -215,7 +201,7 @@ public interface ScalarType<T> extends StringParser, StringFormatter, ScalarData
|
||||
/**
|
||||
* Write the value to binary output.
|
||||
*/
|
||||
void writeData(DataOutput dataOutput, T v) throws IOException;
|
||||
void writeData(DataOutput dataOutput, T value) throws IOException;
|
||||
|
||||
/**
|
||||
* Read the value from JsonParser.
|
||||
|
||||
+10
-10
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core</artifactId>
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>ebean-parent-13.3.0</tag>
|
||||
<tag>ebean-parent-13.8.1</tag>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
@@ -29,7 +29,7 @@
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>classpath-scanner</artifactId>
|
||||
<version>6.2</version>
|
||||
<version>7.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -41,19 +41,19 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-api</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -136,7 +136,7 @@
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.3.3</version>
|
||||
<version>42.4.1</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@@ -144,21 +144,21 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>13.3.0</version>
|
||||
<version>13.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ public interface CQueryPlanKey {
|
||||
* Used by read audit such that we can log read audit entries without the full sql
|
||||
* (which would make the read audit logs verbose).
|
||||
*/
|
||||
String getPartialKey();
|
||||
String partialKey();
|
||||
|
||||
/**
|
||||
* Return a query plan key taking into account persist cascading.
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package io.ebeaninternal.api;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import io.avaje.applog.AppLog;
|
||||
|
||||
/**
|
||||
* Common loggers used in ebean-core.
|
||||
*/
|
||||
public final class CoreLog {
|
||||
|
||||
public static final Logger log = LoggerFactory.getLogger("io.ebean.core");
|
||||
public static final Logger internal = LoggerFactory.getLogger("io.ebean.internal");
|
||||
public static final System.Logger log = AppLog.getLogger("io.ebean.core");
|
||||
public static final System.Logger internal = AppLog.getLogger("io.ebean.internal");
|
||||
}
|
||||
|
||||
@@ -7,17 +7,18 @@ import io.ebeaninternal.server.core.BindPadding;
|
||||
import io.ebeaninternal.server.core.OrmQueryRequest;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
|
||||
/**
|
||||
* Request for loading Associated Many Beans.
|
||||
*/
|
||||
public final class LoadManyRequest extends LoadRequest {
|
||||
|
||||
private static final Logger log = CoreLog.log;
|
||||
private static final System.Logger log = CoreLog.log;
|
||||
|
||||
private final List<BeanCollection<?>> batch;
|
||||
private final LoadManyBuffer loadContext;
|
||||
@@ -113,10 +114,10 @@ public final class LoadManyRequest extends LoadRequest {
|
||||
// in the +query or +lazy load due to no rows (predicates)
|
||||
for (BeanCollection<?> bc : batch) {
|
||||
if (bc.checkEmptyLazyLoad()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
if (log.isLoggable(DEBUG)) {
|
||||
EntityBean ownerBean = bc.getOwnerBean();
|
||||
Object parentId = desc.getId(ownerBean);
|
||||
log.debug("BeanCollection after lazy load was empty. type:" + ownerBean.getClass().getName() + " id:" + parentId + " owner:" + ownerBean);
|
||||
log.log(DEBUG, "BeanCollection after lazy load was empty. type:" + ownerBean.getClass().getName() + " id:" + parentId + " owner:" + ownerBean);
|
||||
}
|
||||
} else if (loadCache && many.isUseCache()) {
|
||||
desc.cacheManyPropPut(many, bc, desc.getId(bc.getOwnerBean()));
|
||||
|
||||
@@ -23,7 +23,12 @@ import java.util.stream.Stream;
|
||||
/**
|
||||
* Service Provider extension to EbeanServer.
|
||||
*/
|
||||
public interface SpiEbeanServer extends SpiServer, ExtendedServer, EbeanServer, BeanCollectionLoader {
|
||||
public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectionLoader {
|
||||
|
||||
/**
|
||||
* Return the NOW time from the Clock.
|
||||
*/
|
||||
long clockNow();
|
||||
|
||||
/**
|
||||
* Return true if the L2 cache has been disabled.
|
||||
@@ -55,7 +60,6 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, EbeanServer,
|
||||
* <p>
|
||||
* Typically used to identify the origin of queries for AutoTune and object
|
||||
* graph costing.
|
||||
* </p>
|
||||
*/
|
||||
CallOrigin createCallOrigin();
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user