mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
170
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e3d39ac1a | ||
|
|
ce19837649 | ||
|
|
11e20edb59 | ||
|
|
88b6a60feb | ||
|
|
43dac07d5b | ||
|
|
04434215d0 | ||
|
|
52e6c0c625 | ||
|
|
745fbe883e | ||
|
|
283e0b66fa | ||
|
|
523deb20f4 | ||
|
|
23d52ca192 | ||
|
|
d20d276d56 | ||
|
|
5b92ac6e02 | ||
|
|
6392f90f32 | ||
|
|
bb8f3831b8 | ||
|
|
4bb43814b7 | ||
|
|
95c1554642 | ||
|
|
2cd59c5166 | ||
|
|
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 | ||
|
|
d34da06840 | ||
|
|
8432fa1320 | ||
|
|
6b81dbbaa2 | ||
|
|
9862526352 | ||
|
|
45003b3d5f | ||
|
|
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
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
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,loom,metropolis,panama]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
@@ -36,6 +36,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
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
[](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)
|
||||
|
||||
@@ -55,9 +56,38 @@ Post questions or issues to the Ebean google group - https://groups.google.com/f
|
||||
## 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)
|
||||
|
||||
## 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.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-clickhouse</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-clickhouse</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-cockroach</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-db2</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-db2</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-h2</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-hana</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-hana</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-mariadb</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mariadb</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-mysql</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-mysql</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-nuodb</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-nuodb</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-oracle</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-oracle</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-postgres</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-sqlite</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlite</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-sqlserver</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean-yugabyte</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>composites</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean (all platforms)</name>
|
||||
@@ -16,13 +16,13 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -35,18 +35,18 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-all</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<scm>
|
||||
<tag>ebean-parent-13.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>composites</artifactId>
|
||||
|
||||
+23
-4
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean api</name>
|
||||
@@ -20,14 +20,14 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.30</version>
|
||||
<version>1.7.36</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-config</artifactId>
|
||||
<version>1.7</version>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
@@ -37,7 +37,7 @@
|
||||
<dependency>
|
||||
<groupId>io.avaje</groupId>
|
||||
<artifactId>avaje-lang</artifactId>
|
||||
<version>1.0</version>
|
||||
<version>1.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -103,4 +103,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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,8 +3,7 @@ package io.ebean;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.*;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
@@ -29,9 +28,11 @@ 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.info("ebean version: {}", version);
|
||||
@@ -88,7 +89,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.
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -368,6 +368,11 @@ public interface ExtendedServer {
|
||||
*/
|
||||
<A, T> List<A> findSingleAttributeList(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query returning a hashset of values for a single property.
|
||||
*/
|
||||
<A, T> Set<A> findSingleAttributeSet(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query returning at most one entity bean or null (if no matching
|
||||
* bean is found).
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -925,6 +925,11 @@ public interface Query<T> extends CancelableQuery {
|
||||
*/
|
||||
<A> List<A> findSingleAttributeList();
|
||||
|
||||
/**
|
||||
* Execute the query returning a hashset of values for a single property.
|
||||
*/
|
||||
<A> Set<A> findSingleAttributeSet();
|
||||
|
||||
/**
|
||||
* Execute a query returning a single value of a single property/column.
|
||||
* <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,536 @@
|
||||
package io.ebean.bean;
|
||||
|
||||
import io.ebean.ValuePair;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class InterceptReadOnly implements EntityBeanIntercept {
|
||||
|
||||
private final EntityBean owner;
|
||||
|
||||
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,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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -802,20 +802,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
|
||||
*/
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
${project.version}
|
||||
@@ -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.4.0</version>
|
||||
<version>13.6.5</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.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</tag>
|
||||
</scm>
|
||||
|
||||
<name>ebean autotune</name>
|
||||
@@ -26,7 +26,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</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:
|
||||
|
||||
+17
-17
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<name>ebean bom</name>
|
||||
@@ -62,8 +62,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 +71,88 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-ddl-generator</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-xml</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-autotune</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-querybean</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>querybean-generator</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>kotlin-querybean-generator</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-postgis</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-redis</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
@@ -16,7 +16,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</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.
|
||||
|
||||
+9
-9
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</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.4.0</tag>
|
||||
<tag>ebean-parent-13.6.5</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.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-core-type</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-externalmapping-api</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -144,21 +144,21 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-h2</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-postgres</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-platform-sqlserver</artifactId>
|
||||
<version>13.4.0</version>
|
||||
<version>13.6.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ 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 true if the L2 cache has been disabled.
|
||||
@@ -55,7 +55,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();
|
||||
|
||||
|
||||
@@ -92,6 +92,11 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
|
||||
*/
|
||||
ATTRIBUTE(FIND_ATTRIBUTE, "findAttribute", false, false),
|
||||
|
||||
/**
|
||||
* Find single attribute set.
|
||||
*/
|
||||
ATTRIBUTE_SET(FIND_ATTRIBUTE_SET, "findAttributeSet", false, false),
|
||||
|
||||
/**
|
||||
* Find rowCount.
|
||||
*/
|
||||
|
||||
@@ -28,6 +28,7 @@ public interface TxnProfileEventCodes {
|
||||
String FIND_ID_LIST = "fi";
|
||||
String FIND_EXISTS = "ex";
|
||||
String FIND_ATTRIBUTE = "fa";
|
||||
String FIND_ATTRIBUTE_SET = "fas";
|
||||
String FIND_COUNT = "fc";
|
||||
String FIND_SUBQUERY = "fs";
|
||||
|
||||
|
||||
+87
-59
@@ -13,6 +13,8 @@ import java.io.Serializable;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* The default cache implementation.
|
||||
@@ -43,10 +45,13 @@ public class DefaultServerCache implements ServerCache {
|
||||
|
||||
protected final String name;
|
||||
protected final String shortName;
|
||||
private final int maxSize;
|
||||
private final int trimFrequency;
|
||||
private final int maxIdleSecs;
|
||||
private final int maxSecsToLive;
|
||||
protected final int maxSize;
|
||||
protected final int trimFrequency;
|
||||
protected final int maxIdleSecs;
|
||||
protected final int maxSecsToLive;
|
||||
protected final long trimOnPut;
|
||||
protected final ReentrantLock lock = new ReentrantLock();
|
||||
protected final AtomicLong mutationCounter = new AtomicLong();
|
||||
|
||||
public DefaultServerCache(DefaultServerCacheConfig config) {
|
||||
this.name = config.getName();
|
||||
@@ -56,6 +61,7 @@ public class DefaultServerCache implements ServerCache {
|
||||
this.maxIdleSecs = config.getMaxIdleSecs();
|
||||
this.maxSecsToLive = config.getMaxSecsToLive();
|
||||
this.trimFrequency = config.determineTrimFrequency();
|
||||
this.trimOnPut = config.determineTrimOnPut();
|
||||
|
||||
MetricFactory factory = MetricFactory.get();
|
||||
String prefix = "l2n.";
|
||||
@@ -187,6 +193,9 @@ public class DefaultServerCache implements ServerCache {
|
||||
public void put(Object key, Object value) {
|
||||
map.put(key, new SoftReference<>(new CacheEntry(key, value)));
|
||||
putCount.increment();
|
||||
if (mutationCounter.incrementAndGet() > trimOnPut) {
|
||||
runEviction();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,62 +231,72 @@ public class DefaultServerCache implements ServerCache {
|
||||
* Run the eviction based on Idle time, Time to live and LRU last access.
|
||||
*/
|
||||
public void runEviction() {
|
||||
long trimForMaxSize;
|
||||
if (maxSize == 0) {
|
||||
trimForMaxSize = 0;
|
||||
} else {
|
||||
trimForMaxSize = size() - maxSize;
|
||||
}
|
||||
if (maxIdleSecs == 0 && maxSecsToLive == 0 && trimForMaxSize < 0) {
|
||||
// nothing to trim on this cache
|
||||
return;
|
||||
}
|
||||
long startNanos = System.nanoTime();
|
||||
long trimmedByIdle = 0;
|
||||
long trimmedByGC = 0;
|
||||
long trimmedByTTL = 0;
|
||||
long trimmedByLRU = 0;
|
||||
|
||||
List<CacheEntry> activeList = new ArrayList<>(map.size());
|
||||
long idleExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxIdleSecs);
|
||||
long ttlExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxSecsToLive);
|
||||
Iterator<SoftReference<CacheEntry>> it = map.values().iterator();
|
||||
while (it.hasNext()) {
|
||||
SoftReference<CacheEntry> ref = it.next();
|
||||
final CacheEntry cacheEntry = ref.get();
|
||||
if (cacheEntry == null) {
|
||||
it.remove();
|
||||
trimmedByGC++;
|
||||
} else if (maxIdleSecs > 0 && idleExpireNano > cacheEntry.getLastAccessTime()) {
|
||||
it.remove();
|
||||
trimmedByIdle++;
|
||||
} else if (maxSecsToLive > 0 && ttlExpireNano > cacheEntry.getCreateTime()) {
|
||||
it.remove();
|
||||
trimmedByTTL++;
|
||||
} else if (trimForMaxSize > 0) {
|
||||
activeList.add(cacheEntry);
|
||||
lock.lock();
|
||||
try {
|
||||
long trimForMaxSize;
|
||||
if (maxSize == 0) {
|
||||
trimForMaxSize = 0;
|
||||
} else {
|
||||
trimForMaxSize = size() - maxSize;
|
||||
}
|
||||
}
|
||||
if (trimForMaxSize > 0 && activeList.size() > maxSize) {
|
||||
// sort into last access time ascending
|
||||
activeList.sort(BY_LAST_ACCESS);
|
||||
int trimSize = getTrimSize();
|
||||
for (int i = trimSize; i < activeList.size(); i++) {
|
||||
// remove if still in the cache
|
||||
if (map.remove(activeList.get(i).getKey()) != null) {
|
||||
trimmedByLRU++;
|
||||
if (maxIdleSecs == 0 && maxSecsToLive == 0 && trimForMaxSize < 0) {
|
||||
// nothing to trim on this cache
|
||||
mutationCounter.set(0);
|
||||
return;
|
||||
}
|
||||
long startNanos = System.nanoTime();
|
||||
long trimmedByIdle = 0;
|
||||
long trimmedByGC = 0;
|
||||
long trimmedByTTL = 0;
|
||||
long trimmedByLRU = 0;
|
||||
|
||||
try {
|
||||
List<CacheEntry> activeList = new ArrayList<>(map.size());
|
||||
long idleExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxIdleSecs);
|
||||
long ttlExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxSecsToLive);
|
||||
Iterator<SoftReference<CacheEntry>> it = map.values().iterator();
|
||||
while (it.hasNext()) {
|
||||
SoftReference<CacheEntry> ref = it.next();
|
||||
final CacheEntry cacheEntry = ref.get();
|
||||
if (cacheEntry == null) {
|
||||
it.remove();
|
||||
trimmedByGC++;
|
||||
} else if (maxIdleSecs > 0 && idleExpireNano > cacheEntry.getLastAccessTime()) {
|
||||
it.remove();
|
||||
trimmedByIdle++;
|
||||
} else if (maxSecsToLive > 0 && ttlExpireNano > cacheEntry.getCreateTime()) {
|
||||
it.remove();
|
||||
trimmedByTTL++;
|
||||
} else if (trimForMaxSize > 0) {
|
||||
activeList.add(cacheEntry.forSort());
|
||||
}
|
||||
}
|
||||
if (trimForMaxSize > 0 && activeList.size() > maxSize) {
|
||||
// sort into last access time ascending
|
||||
activeList.sort(BY_LAST_ACCESS);
|
||||
int trimSize = getTrimSize();
|
||||
for (int i = trimSize; i < activeList.size(); i++) {
|
||||
// remove if still in the cache
|
||||
if (map.remove(activeList.get(i).getKey()) != null) {
|
||||
trimmedByLRU++;
|
||||
}
|
||||
}
|
||||
}
|
||||
mutationCounter.set(0);
|
||||
evictCount.add(trimmedByIdle);
|
||||
evictCount.add(trimmedByGC);
|
||||
evictCount.add(trimmedByTTL);
|
||||
evictCount.add(trimmedByLRU);
|
||||
if (logger.isTraceEnabled()) {
|
||||
long exeMicros = TimeUnit.MICROSECONDS.convert(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
|
||||
logger.trace("Executed trim of cache {} in [{}]millis idle[{}] timeToLive[{}] accessTime[{}] gc[{}]",
|
||||
name, exeMicros, trimmedByIdle, trimmedByTTL, trimmedByLRU, trimmedByGC);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.warn("Error during trim of DefaultServerCache [" + name + "]. Cache might be bigger than desired.", e);
|
||||
}
|
||||
}
|
||||
|
||||
evictCount.add(trimmedByIdle);
|
||||
evictCount.add(trimmedByGC);
|
||||
evictCount.add(trimmedByTTL);
|
||||
evictCount.add(trimmedByLRU);
|
||||
if (logger.isTraceEnabled()) {
|
||||
long exeMicros = TimeUnit.MICROSECONDS.convert(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
|
||||
logger.trace("Executed trim of cache {} in [{}]millis idle[{}] timeToLive[{}] accessTime[{}] gc[{}]",
|
||||
name, exeMicros, trimmedByIdle, trimmedByTTL, trimmedByLRU, trimmedByGC);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,7 +312,7 @@ public class DefaultServerCache implements ServerCache {
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparator for sorting by last access time.
|
||||
* Comparator for sorting by last access sort, a copy of last access time that should not mutate during trim processing.
|
||||
*/
|
||||
public static final class CompareByLastAccess implements Comparator<CacheEntry>, Serializable {
|
||||
|
||||
@@ -301,7 +320,7 @@ public class DefaultServerCache implements ServerCache {
|
||||
|
||||
@Override
|
||||
public int compare(CacheEntry e1, CacheEntry e2) {
|
||||
return Long.compare(e1.getLastAccessTime(), e2.getLastAccessTime());
|
||||
return Long.compare(e1.lastAccessSort, e2.lastAccessSort);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,6 +333,7 @@ public class DefaultServerCache implements ServerCache {
|
||||
private final Object value;
|
||||
private final long createTime;
|
||||
private long lastAccessTime;
|
||||
private long lastAccessSort;
|
||||
|
||||
public CacheEntry(Object key, Object value) {
|
||||
this.key = key;
|
||||
@@ -322,6 +342,14 @@ public class DefaultServerCache implements ServerCache {
|
||||
this.lastAccessTime = createTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a copy of lastAccessTime used for sorting. This value should not change during trim processing.
|
||||
*/
|
||||
public CacheEntry forSort() {
|
||||
this.lastAccessSort = lastAccessTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the entry key.
|
||||
*/
|
||||
|
||||
+10
@@ -76,4 +76,14 @@ public final class DefaultServerCacheConfig {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the number of mutations/puts required to trigger a runEviction() in the foreground.
|
||||
*/
|
||||
public long determineTrimOnPut() {
|
||||
if (maxSize > 0) {
|
||||
return maxSize / 10;
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.ebeaninternal.server.cluster;
|
||||
|
||||
import io.ebean.EbeanServer;
|
||||
import io.ebean.Database;
|
||||
import io.ebean.config.ContainerConfig;
|
||||
import io.ebeaninternal.server.transaction.RemoteTransactionEvent;
|
||||
import org.slf4j.Logger;
|
||||
@@ -20,7 +20,7 @@ public class ClusterManager implements ServerLookup {
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
private final ConcurrentHashMap<String, EbeanServer> serverMap = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, Database> serverMap = new ConcurrentHashMap<>();
|
||||
|
||||
private final Object monitor = new Object();
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ClusterManager implements ServerLookup {
|
||||
return factory;
|
||||
}
|
||||
|
||||
public void registerServer(EbeanServer server) {
|
||||
public void registerServer(Database server) {
|
||||
lock.lock();
|
||||
try {
|
||||
serverMap.put(server.name(), server);
|
||||
@@ -66,7 +66,7 @@ public class ClusterManager implements ServerLookup {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EbeanServer getServer(String name) {
|
||||
public Database getServer(String name) {
|
||||
lock.lock();
|
||||
try {
|
||||
return serverMap.get(name);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package io.ebeaninternal.server.cluster;
|
||||
|
||||
import io.ebean.EbeanServer;
|
||||
import io.ebean.Database;
|
||||
|
||||
/**
|
||||
* Returns EbeanServer instances for remote message reading.
|
||||
* Returns Database instances for remote message reading.
|
||||
*/
|
||||
public interface ServerLookup {
|
||||
|
||||
/**
|
||||
* Return the EbeanServer instance by name.
|
||||
*/
|
||||
EbeanServer getServer(String name);
|
||||
Database getServer(String name);
|
||||
}
|
||||
|
||||
@@ -93,6 +93,11 @@ public class DatabasePlatformFactory {
|
||||
return provider.create(majorVersion, minorVersion, metaData, connection);
|
||||
}
|
||||
}
|
||||
if (providers.isEmpty()) {
|
||||
throw new IllegalStateException("There are no ebean platform providers in the classpath. " +
|
||||
"Add a missing dependency like ebean-h2, ebean-postgres, ebean-mysql etc to support the database [" + dbProductName
|
||||
+ "]. Adding a dependency on io.ebean:ebean will add support for all platforms.");
|
||||
}
|
||||
throw new IllegalStateException("Unable to determine the appropriate ebean platform given database product name [" + dbProductName
|
||||
+ "] and ebean platform providers " + providers + ". With ebean 13+ we now have separate platforms (ebean-postgres, ebean-mysql etc)"
|
||||
+ " and should use database specific platform dependency like ebean-postgres. Note that we can use ebean-platform-all to include"
|
||||
|
||||
@@ -5,8 +5,6 @@ import io.ebean.config.ContainerConfig;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.DatabaseConfigProvider;
|
||||
import io.ebean.config.ModuleInfoLoader;
|
||||
import io.ebean.config.ServerConfig;
|
||||
import io.ebean.config.ServerConfigProvider;
|
||||
import io.ebean.config.TenantMode;
|
||||
import io.ebean.config.UnderscoreNamingConvention;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
@@ -124,15 +122,8 @@ public final class DefaultContainer implements SpiContainer {
|
||||
|
||||
private void applyConfigServices(DatabaseConfig config) {
|
||||
if (config.isDefaultServer()) {
|
||||
boolean appliedConfig = false;
|
||||
for (DatabaseConfigProvider configProvider : ServiceLoader.load(DatabaseConfigProvider.class)) {
|
||||
configProvider.apply(config);
|
||||
appliedConfig = true;
|
||||
}
|
||||
if (!appliedConfig && config instanceof ServerConfig) {
|
||||
for (ServerConfigProvider configProvider : ServiceLoader.load(ServerConfigProvider.class)) {
|
||||
configProvider.apply((ServerConfig)config);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.isAutoLoadModuleInfo()) {
|
||||
|
||||
@@ -1193,7 +1193,23 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
try {
|
||||
request.initTransIfRequired();
|
||||
return request.findSingleAttributeList();
|
||||
return request.findSingleAttributeCollection(new ArrayList<>());
|
||||
} finally {
|
||||
request.endTransIfRequired();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <A, T> Set<A> findSingleAttributeSet(Query<T> query, Transaction transaction) {
|
||||
SpiOrmQueryRequest<T> request = createQueryRequest(Type.ATTRIBUTE_SET, query, transaction);
|
||||
Object result = request.getFromQueryCache();
|
||||
if (result != null) {
|
||||
return (Set<A>) result;
|
||||
}
|
||||
try {
|
||||
request.initTransIfRequired();
|
||||
return request.findSingleAttributeCollection(new LinkedHashSet<>());
|
||||
} finally {
|
||||
request.endTransIfRequired();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.ebeaninternal.server.core;
|
||||
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.datasource.DataSourceAlertFactory;
|
||||
import io.ebean.datasource.DataSourceConfig;
|
||||
@@ -97,10 +98,16 @@ final class InitDataSource {
|
||||
dsConfig.setReadOnly(true);
|
||||
dsConfig.setDefaults(config.getDataSourceConfig());
|
||||
dsConfig.setIsolationLevel(config.getDataSourceConfig().getIsolationLevel());
|
||||
} else if (isPostgresAllQuotedIdentifiers()) {
|
||||
dsConfig.addProperty("quoteReturningIdentifiers", false);
|
||||
}
|
||||
return create(dsConfig, readOnly);
|
||||
}
|
||||
|
||||
boolean isPostgresAllQuotedIdentifiers() {
|
||||
return config.isAllQuotedIdentifiers() && Platform.POSTGRES == config.getDatabasePlatform().getPlatform().base();
|
||||
}
|
||||
|
||||
private DataSource create(DataSourceConfig dsConfig, boolean readOnly) {
|
||||
String poolName = config.getName() + (readOnly ? "-ro" : "");
|
||||
return DataSourceFactory.create(poolName, dsConfig);
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.ebean.bean.BeanCollection;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -29,9 +30,9 @@ public interface OrmQueryEngine {
|
||||
<T> BeanCollection<T> findMany(OrmQueryRequest<T> request);
|
||||
|
||||
/**
|
||||
* Execute the findSingleAttributeList query.
|
||||
* Execute the findSingleAttributeCollection query.
|
||||
*/
|
||||
<A> List<A> findSingleAttributeList(OrmQueryRequest<?> request);
|
||||
<A extends Collection<?>> A findSingleAttributeCollection(OrmQueryRequest<?> request, A collection);
|
||||
|
||||
/**
|
||||
* Execute the findVersions query.
|
||||
|
||||
@@ -431,8 +431,8 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A> List<A> findSingleAttributeList() {
|
||||
return queryEngine.findSingleAttributeList(this);
|
||||
public <A extends Collection<?>> A findSingleAttributeCollection(A collection) {
|
||||
return queryEngine.findSingleAttributeCollection(this, collection);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,25 +9,12 @@ import io.ebean.event.BeanPersistController;
|
||||
import io.ebean.event.BeanPersistListener;
|
||||
import io.ebean.event.BeanPersistRequest;
|
||||
import io.ebean.event.changelog.BeanChange;
|
||||
import io.ebeaninternal.api.ConcurrencyMode;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiProfileTransactionEvent;
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
import io.ebeaninternal.api.TransactionEvent;
|
||||
import io.ebeaninternal.api.*;
|
||||
import io.ebeaninternal.server.cache.CacheChangeSet;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanManager;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import io.ebeaninternal.server.deploy.*;
|
||||
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
|
||||
import io.ebeaninternal.server.deploy.id.ImportedId;
|
||||
import io.ebeaninternal.server.persist.BatchControl;
|
||||
import io.ebeaninternal.server.persist.BatchedSqlException;
|
||||
import io.ebeaninternal.server.persist.DeleteMode;
|
||||
import io.ebeaninternal.server.persist.Flags;
|
||||
import io.ebeaninternal.server.persist.PersistExecute;
|
||||
import io.ebeaninternal.server.persist.SaveMany;
|
||||
import io.ebeaninternal.server.persist.*;
|
||||
import io.ebeaninternal.server.transaction.BeanPersistIdMap;
|
||||
import io.ebeanservice.docstore.api.DocStoreUpdate;
|
||||
import io.ebeanservice.docstore.api.DocStoreUpdateContext;
|
||||
@@ -38,11 +25,7 @@ import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.io.IOException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* PersistRequest for insert update or delete of a bean.
|
||||
@@ -94,8 +77,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
*/
|
||||
private List<BeanPropertyAssocMany<?>> updatedManys;
|
||||
/**
|
||||
* Need to get and store the updated properties because the persist listener is notified
|
||||
* later on a different thread and the bean has been reset at that point.
|
||||
* Store the updated properties to notify persist listener.
|
||||
*/
|
||||
private Set<String> updatedProperties;
|
||||
/**
|
||||
@@ -139,7 +121,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
*/
|
||||
private boolean complete;
|
||||
/**
|
||||
* Many to many intersection table changes that are held for later batch processing.
|
||||
* Many-to-many intersection table changes that are held for later batch processing.
|
||||
*/
|
||||
private List<SaveMany> saveMany;
|
||||
|
||||
@@ -165,9 +147,10 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
// 'stateless update' - set loaded properties as dirty
|
||||
intercept.setNewBeanForUpdate();
|
||||
statelessUpdate = true;
|
||||
} else if (!intercept.isDirty()) {
|
||||
// check if any mutable scalar properties are dirty
|
||||
beanDescriptor.checkAnyMutableProperties(intercept);
|
||||
}
|
||||
// Mark Mutable scalar properties (like Hstore) as dirty where necessary
|
||||
beanDescriptor.checkMutableProperties(intercept);
|
||||
}
|
||||
this.concurrencyMode = beanDescriptor.concurrencyMode(intercept);
|
||||
this.publish = Flags.isPublish(flags);
|
||||
@@ -743,10 +726,6 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
executeInsert();
|
||||
return -1;
|
||||
case UPDATE:
|
||||
if (beanPersistListener != null) {
|
||||
// store the updated properties for sending later
|
||||
updatedProperties = updatedProperties();
|
||||
}
|
||||
executeUpdate();
|
||||
return -1;
|
||||
case DELETE_SOFT:
|
||||
@@ -953,7 +932,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
String name = beanDescriptor.name();
|
||||
switch (type) {
|
||||
case INSERT:
|
||||
transaction.logSummary("Inserted [" + name + "] [" + idValue + "]" + draft);
|
||||
transaction.logSummary("Inserted [" + name + "] [" + (idValue == null ? "" : idValue) + "]" + draft);
|
||||
break;
|
||||
case UPDATE:
|
||||
transaction.logSummary("Updated [" + name + "] [" + idValue + "]" + draft);
|
||||
@@ -1225,6 +1204,11 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
private void executeUpdate() {
|
||||
setTenantId();
|
||||
if (controller == null || controller.preUpdate(this)) {
|
||||
// check dirty state for all mutable scalar properties (like DbJson, Hstore)
|
||||
beanDescriptor.checkAllMutableProperties(intercept);
|
||||
if (beanPersistListener != null) {
|
||||
updatedProperties = updatedProperties();
|
||||
}
|
||||
postControllerPrepareUpdate();
|
||||
beanManager.getBeanPersister().update(this);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeanservice.docstore.api.DocQueryRequest;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -122,7 +123,7 @@ public interface SpiOrmQueryRequest<T> extends BeanQueryRequest<T>, DocQueryRequ
|
||||
/**
|
||||
* Execute the findSingleAttributeList query.
|
||||
*/
|
||||
<A> List<A> findSingleAttributeList();
|
||||
<A extends Collection<?>> A findSingleAttributeCollection(A collection);
|
||||
|
||||
/**
|
||||
* Execute returning the ResultSet.
|
||||
|
||||
@@ -13,11 +13,10 @@ public interface DataTimeZone {
|
||||
Calendar getTimeZone();
|
||||
|
||||
/**
|
||||
* Return the Calendar to use for Timezone information when reading/writing date.
|
||||
* A 'date' only value has normally no timezone information, but some platforms (like MySQL)
|
||||
* reqire this.
|
||||
* Return the Calendar to use for Timezone information when reading/writing a time component (date only/time only).
|
||||
* A time component has normally no timezone information, but some platforms (like MySQL) reqire this.
|
||||
*/
|
||||
default Calendar getDateTimeZone() {
|
||||
default Calendar getTimeComponentTimeZone() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ public class MySqlDataTimeZone implements DataTimeZone {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Calendar getDateTimeZone() {
|
||||
public Calendar getTimeComponentTimeZone() {
|
||||
return zone;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ abstract class BaseCollectionHelp<T> implements BeanCollectionHelp<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoader(BeanCollectionLoader loader) {
|
||||
public final void setLoader(BeanCollectionLoader loader) {
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ abstract class BaseCollectionHelp<T> implements BeanCollectionHelp<T> {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public Collection underlying(Object value) {
|
||||
public final Collection underlying(Object value) {
|
||||
if (value instanceof BeanCollection) {
|
||||
return ((BeanCollection)value).getActualDetails();
|
||||
} else {
|
||||
@@ -51,7 +51,7 @@ abstract class BaseCollectionHelp<T> implements BeanCollectionHelp<T> {
|
||||
}
|
||||
}
|
||||
|
||||
void jsonWriteCollection(SpiJsonWriter ctx, String name, Collection<?> list) throws IOException {
|
||||
final void jsonWriteCollection(SpiJsonWriter ctx, String name, Collection<?> list) throws IOException {
|
||||
if (!list.isEmpty() || ctx.isIncludeEmpty()) {
|
||||
ctx.beginAssocMany(name);
|
||||
for (Object bean : list) {
|
||||
|
||||
@@ -47,6 +47,11 @@ public interface BeanCollectionHelp<T> extends CQueryCollectionAdd<T> {
|
||||
*/
|
||||
BeanCollection<T> createEmpty(EntityBean bean);
|
||||
|
||||
/**
|
||||
* Create and return an empty 'vanilla' collection that does not support lazy loading.
|
||||
*/
|
||||
Object createEmptyReference();
|
||||
|
||||
/**
|
||||
* Add a bean to the List Set or Map.
|
||||
*/
|
||||
|
||||
+34
-5
@@ -1,5 +1,9 @@
|
||||
package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.common.BeanList;
|
||||
import io.ebean.common.BeanSet;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.core.OrmQueryRequest;
|
||||
import io.ebeaninternal.server.el.ElPropertyValue;
|
||||
@@ -12,18 +16,17 @@ import io.ebeaninternal.server.query.CQueryCollectionAdd;
|
||||
public final class BeanCollectionHelpFactory {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static final BeanListHelp LIST_HELP = new BeanListHelp();
|
||||
private static final CQueryCollectionAdd LIST_HELP = new ListAdd();
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static final BeanSetHelp SET_HELP = new BeanSetHelp();
|
||||
private static final CQueryCollectionAdd SET_HELP = new SetAdd();
|
||||
|
||||
/**
|
||||
* Create the helper based on the many property.
|
||||
*/
|
||||
public static <T> BeanCollectionHelp<T> create(BeanPropertyAssocMany<T> many) {
|
||||
boolean elementCollection = many.isElementCollection();
|
||||
ManyType manyType = many.manyType();
|
||||
switch (manyType) {
|
||||
switch (many.manyType()) {
|
||||
case LIST:
|
||||
return elementCollection ? new BeanListHelpElement<>(many) : new BeanListHelp<>(many);
|
||||
case SET:
|
||||
@@ -31,7 +34,7 @@ public final class BeanCollectionHelpFactory {
|
||||
case MAP:
|
||||
return elementCollection ? new BeanMapHelpElement<>(many) : new BeanMapHelp<>(many);
|
||||
default:
|
||||
throw new RuntimeException("Invalid type " + manyType);
|
||||
throw new RuntimeException("Invalid type " + many.manyType());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,4 +56,30 @@ public final class BeanCollectionHelpFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ListAdd<T> implements CQueryCollectionAdd<T> {
|
||||
|
||||
@Override
|
||||
public BeanCollection<T> createEmptyNoParent() {
|
||||
return new BeanList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(BeanCollection<?> collection, EntityBean bean, boolean withCheck) {
|
||||
collection.internalAdd(bean);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SetAdd<T> implements CQueryCollectionAdd<T> {
|
||||
|
||||
@Override
|
||||
public BeanCollection<T> createEmptyNoParent() {
|
||||
return new BeanSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(BeanCollection<?> collection, EntityBean bean, boolean withCheck) {
|
||||
collection.internalAdd(bean);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
private final ConcurrentHashMap<String, ElPropertyDeploy> elDeployCache = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, ElComparator<T>> comparatorCache = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, STreeProperty> dynamicProperty = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, Map<String,String>> pathMaps = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, Map<String, String>> pathMaps = new ConcurrentHashMap<>();
|
||||
|
||||
private final Map<String, SpiRawSql> namedRawSql;
|
||||
private final Map<String, String> namedQuery;
|
||||
@@ -1765,6 +1765,14 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
return createEntityBean(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityBean createEntityBean2(boolean readOnlyNoIntercept) {
|
||||
if (readOnlyNoIntercept) {
|
||||
return (EntityBean) prototypeEntityBean._ebean_newInstanceReadOnly();
|
||||
}
|
||||
return createEntityBean(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an entity bean for JSON marshalling (which differs for the element collection case).
|
||||
*/
|
||||
@@ -2879,7 +2887,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
for (BeanPropertyAssocMany<?> many : propertiesManySave) {
|
||||
if (ebi.isLoadedProperty(many.propertyIndex())) {
|
||||
final Object value = many.getValue(bean);
|
||||
if (value instanceof BeanCollection && ((BeanCollection<?>)value).hasModifications() || value != null) {
|
||||
if (value instanceof BeanCollection && ((BeanCollection<?>) value).hasModifications() || value != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -3132,9 +3140,9 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for mutable scalar types and mark as dirty if necessary.
|
||||
* Check all mutable scalar types and mark as dirty if necessary.
|
||||
*/
|
||||
public void checkMutableProperties(EntityBeanIntercept ebi) {
|
||||
public void checkAllMutableProperties(EntityBeanIntercept ebi) {
|
||||
for (BeanProperty beanProperty : propertiesMutable) {
|
||||
int propertyIndex = beanProperty.propertyIndex();
|
||||
if (ebi.isLoadedProperty(propertyIndex)) {
|
||||
@@ -3148,6 +3156,23 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if any mutable properties are dirty.
|
||||
*/
|
||||
public boolean checkAnyMutableProperties(EntityBeanIntercept ebi) {
|
||||
for (BeanProperty beanProperty : propertiesMutable) {
|
||||
int propertyIndex = beanProperty.propertyIndex();
|
||||
if (ebi.isLoadedProperty(propertyIndex)) {
|
||||
Object value = beanProperty.getValue(ebi.getOwner());
|
||||
if (beanProperty.checkMutable(value, ebi.isDirtyProperty(propertyIndex), ebi)) {
|
||||
ebi.markPropertyAsChanged(propertyIndex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public ConcurrencyMode concurrencyMode(EntityBeanIntercept ebi) {
|
||||
if (!hasVersionProperty(ebi)) {
|
||||
return ConcurrencyMode.NONE;
|
||||
|
||||
@@ -11,6 +11,7 @@ import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -27,8 +28,7 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) {
|
||||
|
||||
public final BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) {
|
||||
if (bc instanceof BeanList<?>) {
|
||||
BeanList<?> bl = (BeanList<?>) bc;
|
||||
if (bl.getActualList() == null) {
|
||||
@@ -42,12 +42,17 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollection<T> createEmptyNoParent() {
|
||||
public final Object createEmptyReference() {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final BeanCollection<T> createEmptyNoParent() {
|
||||
return new BeanList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollection<T> createEmpty(EntityBean parentBean) {
|
||||
public final BeanCollection<T> createEmpty(EntityBean parentBean) {
|
||||
BeanList<T> beanList = new BeanList<>(loader, parentBean, propertyName);
|
||||
if (many != null) {
|
||||
beanList.setModifyListening(many.modifyListenMode());
|
||||
@@ -56,29 +61,23 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollection<T> createReference(EntityBean parentBean) {
|
||||
|
||||
public final BeanCollection<T> createReference(EntityBean parentBean) {
|
||||
BeanList<T> beanList = new BeanList<>(loader, parentBean, propertyName);
|
||||
beanList.setModifyListening(many.modifyListenMode());
|
||||
return beanList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
|
||||
|
||||
public final void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
|
||||
BeanList<?> newBeanList = (BeanList<?>) server.findList(query, t);
|
||||
refresh(newBeanList, parentBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(BeanCollection<?> bc, EntityBean parentBean) {
|
||||
|
||||
public final void refresh(BeanCollection<?> bc, EntityBean parentBean) {
|
||||
BeanList<?> newBeanList = (BeanList<?>) bc;
|
||||
|
||||
List<?> currentList = (List<?>) many.getValue(parentBean);
|
||||
|
||||
newBeanList.setModifyListening(many.modifyListenMode());
|
||||
|
||||
if (currentList == null) {
|
||||
// the currentList is null? Not really expecting this...
|
||||
many.setValue(parentBean, newBeanList);
|
||||
@@ -96,8 +95,7 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(SpiJsonWriter ctx, String name, Object collection, boolean explicitInclude) throws IOException {
|
||||
|
||||
public final void jsonWrite(SpiJsonWriter ctx, String name, Object collection, boolean explicitInclude) throws IOException {
|
||||
List<?> list;
|
||||
if (collection instanceof BeanCollection<?>) {
|
||||
BeanList<?> beanList = (BeanList<?>) collection;
|
||||
@@ -114,7 +112,6 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
|
||||
} else {
|
||||
list = (List<?>) collection;
|
||||
}
|
||||
|
||||
jsonWriteCollection(ctx, name, list);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -36,13 +37,11 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) {
|
||||
|
||||
public final BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) {
|
||||
if (mapKey == null) {
|
||||
mapKey = many.mapKey();
|
||||
}
|
||||
BeanProperty beanProp = targetDescriptor.beanProperty(mapKey);
|
||||
|
||||
if (bc instanceof BeanMap<?, ?>) {
|
||||
BeanMap<Object, Object> bm = (BeanMap<Object, Object>) bc;
|
||||
Map<Object, Object> actualMap = bm.getActualMap();
|
||||
@@ -57,10 +56,9 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
|
||||
}
|
||||
}
|
||||
|
||||
static class Adder implements BeanCollectionAdd {
|
||||
static final class Adder implements BeanCollectionAdd {
|
||||
|
||||
private final BeanProperty beanProperty;
|
||||
|
||||
private final Map<Object, Object> map;
|
||||
|
||||
Adder(BeanProperty beanProperty, Map<Object, Object> map) {
|
||||
@@ -76,13 +74,17 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollection<T> createEmptyNoParent() {
|
||||
public final Object createEmptyReference() {
|
||||
return Collections.EMPTY_MAP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final BeanCollection<T> createEmptyNoParent() {
|
||||
return new BeanMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollection<T> createEmpty(EntityBean ownerBean) {
|
||||
|
||||
public final BeanCollection<T> createEmpty(EntityBean ownerBean) {
|
||||
BeanMap<?, T> beanMap = new BeanMap<>(loader, ownerBean, propertyName);
|
||||
if (many != null) {
|
||||
beanMap.setModifyListening(many.modifyListenMode());
|
||||
@@ -92,7 +94,6 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
|
||||
|
||||
@Override
|
||||
public void add(BeanCollection<?> collection, EntityBean bean, boolean withCheck) {
|
||||
|
||||
if (bean == null) {
|
||||
((BeanMap<?, ?>) collection).internalPutNull();
|
||||
} else {
|
||||
@@ -104,8 +105,7 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public BeanCollection<T> createReference(EntityBean parentBean) {
|
||||
|
||||
public final BeanCollection<T> createReference(EntityBean parentBean) {
|
||||
BeanMap beanMap = new BeanMap(loader, parentBean, propertyName);
|
||||
if (many != null) {
|
||||
beanMap.setModifyListening(many.modifyListenMode());
|
||||
@@ -114,14 +114,13 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
|
||||
public final void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
|
||||
BeanMap<?, ?> newBeanMap = (BeanMap<?, ?>) server.findMap(query, t);
|
||||
refresh(newBeanMap, parentBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(BeanCollection<?> bc, EntityBean parentBean) {
|
||||
|
||||
public final void refresh(BeanCollection<?> bc, EntityBean parentBean) {
|
||||
BeanMap<?, ?> newBeanMap = (BeanMap<?, ?>) bc;
|
||||
Map<?, ?> current = (Map<?, ?>) many.getValue(parentBean);
|
||||
|
||||
@@ -143,8 +142,7 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(SpiJsonWriter ctx, String name, Object collection, boolean explicitInclude) throws IOException {
|
||||
|
||||
public final void jsonWrite(SpiJsonWriter ctx, String name, Object collection, boolean explicitInclude) throws IOException {
|
||||
Map<?, ?> map;
|
||||
if (collection instanceof BeanCollection<?>) {
|
||||
BeanMap<?, ?> bc = (BeanMap<?, ?>) collection;
|
||||
|
||||
@@ -15,7 +15,6 @@ public final class BeanMapHelpElement<T> extends BeanMapHelp<T> {
|
||||
public void add(BeanCollection<?> collection, EntityBean bean, boolean withCheck) {
|
||||
Object key = bean._ebean_getField(0);
|
||||
Object val = bean._ebean_getField(1);
|
||||
|
||||
BeanMap<?, ?> map = ((BeanMap<?, ?>) collection);
|
||||
if (withCheck) {
|
||||
map.internalPutWithCheck(key, val);
|
||||
|
||||
@@ -601,6 +601,11 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
|
||||
return mapKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createEmptyReference(EntityBean localBean) {
|
||||
setValue(localBean, help.createEmptyReference());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollection<?> createReference(EntityBean localBean, boolean forceNewReference) {
|
||||
return forceNewReference ? createReference(localBean) : createReferenceIfNull(localBean);
|
||||
|
||||
@@ -10,6 +10,7 @@ import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.json.SpiJsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -33,7 +34,7 @@ public class BeanSetHelp<T> extends BaseCollectionHelp<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) {
|
||||
public final BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) {
|
||||
if (bc instanceof BeanSet<?>) {
|
||||
BeanSet<?> beanSet = (BeanSet<?>) bc;
|
||||
if (beanSet.getActualSet() == null) {
|
||||
@@ -46,12 +47,17 @@ public class BeanSetHelp<T> extends BaseCollectionHelp<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollection<T> createEmptyNoParent() {
|
||||
public final Object createEmptyReference() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final BeanCollection<T> createEmptyNoParent() {
|
||||
return new BeanSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollection<T> createEmpty(EntityBean ownerBean) {
|
||||
public final BeanCollection<T> createEmpty(EntityBean ownerBean) {
|
||||
BeanSet<T> beanSet = new BeanSet<>(loader, ownerBean, propertyName);
|
||||
if (many != null) {
|
||||
beanSet.setModifyListening(many.modifyListenMode());
|
||||
@@ -60,20 +66,20 @@ public class BeanSetHelp<T> extends BaseCollectionHelp<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanCollection<T> createReference(EntityBean parentBean) {
|
||||
public final BeanCollection<T> createReference(EntityBean parentBean) {
|
||||
BeanSet<T> beanSet = new BeanSet<>(loader, parentBean, propertyName);
|
||||
beanSet.setModifyListening(many.modifyListenMode());
|
||||
return beanSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
|
||||
public final void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
|
||||
BeanSet<?> newBeanSet = (BeanSet<?>) server.findSet(query, t);
|
||||
refresh(newBeanSet, parentBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(BeanCollection<?> bc, EntityBean parentBean) {
|
||||
public final void refresh(BeanCollection<?> bc, EntityBean parentBean) {
|
||||
BeanSet<?> newBeanSet = (BeanSet<?>) bc;
|
||||
Set<?> current = (Set<?>) many.getValue(parentBean);
|
||||
newBeanSet.setModifyListening(many.modifyListenMode());
|
||||
@@ -94,7 +100,7 @@ public class BeanSetHelp<T> extends BaseCollectionHelp<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonWrite(SpiJsonWriter ctx, String name, Object collection, boolean explicitInclude) throws IOException {
|
||||
public final void jsonWrite(SpiJsonWriter ctx, String name, Object collection, boolean explicitInclude) throws IOException {
|
||||
Set<?> set;
|
||||
if (collection instanceof BeanCollection<?>) {
|
||||
BeanSet<?> bc = (BeanSet<?>) collection;
|
||||
|
||||
@@ -6,7 +6,6 @@ import io.ebean.bean.EntityBeanIntercept;
|
||||
import io.ebean.bean.PersistenceContext;
|
||||
import io.ebean.core.type.DataReader;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.server.query.STreePropertyAssocMany;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -70,11 +69,6 @@ public interface DbReadContext {
|
||||
*/
|
||||
void register(BeanPropertyAssocMany<?> many, BeanCollection<?> bc);
|
||||
|
||||
/**
|
||||
* Return the property that is associated with the many. There can only be
|
||||
* one. This can be null.
|
||||
*/
|
||||
STreePropertyAssocMany getManyProperty();
|
||||
|
||||
/**
|
||||
* Set back the bean that has just been loaded with its id.
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.ebeaninternal.server.deploy;
|
||||
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebean.bean.EntityBeanIntercept;
|
||||
import io.ebean.bean.InterceptReadWrite;
|
||||
|
||||
final class ElementEntityBean implements EntityBean {
|
||||
|
||||
@@ -13,7 +14,7 @@ final class ElementEntityBean implements EntityBean {
|
||||
|
||||
ElementEntityBean(String[] properties) {
|
||||
this.properties = properties;
|
||||
this.intercept = new EntityBeanIntercept(this);
|
||||
this.intercept = new InterceptReadWrite(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -29,10 +29,10 @@ public final class IndexDefinition {
|
||||
/**
|
||||
* Create a unique constraint given the column names.
|
||||
*/
|
||||
public IndexDefinition(String[] columns) {
|
||||
public IndexDefinition(String name, String[] columns) {
|
||||
this.columns = columns;
|
||||
this.unique = true;
|
||||
this.name = null;
|
||||
this.name = name;
|
||||
this.platforms = null;
|
||||
this.concurrent = false;
|
||||
this.definition = null;
|
||||
|
||||
@@ -16,11 +16,17 @@ public final class PartitionMeta {
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Originally the property name but replaced with the db column.
|
||||
*/
|
||||
public String getProperty() {
|
||||
return property;
|
||||
}
|
||||
|
||||
public void setProperty(String dbColumn) {
|
||||
/**
|
||||
* Set the db column being partitioned on.
|
||||
*/
|
||||
public void setColumn(String dbColumn) {
|
||||
this.property = dbColumn;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,12 +249,12 @@ public class DeployBeanDescriptor<T> {
|
||||
if (partitionMeta != null) {
|
||||
DeployBeanProperty beanProperty = getBeanProperty(partitionMeta.getProperty());
|
||||
if (beanProperty != null) {
|
||||
partitionMeta.setProperty(beanProperty.getDbColumn());
|
||||
partitionMeta.setColumn(beanProperty.getDbColumn());
|
||||
}
|
||||
}
|
||||
return partitionMeta;
|
||||
}
|
||||
|
||||
|
||||
public void setTablespaceMeta(TablespaceMeta tablespaceMeta) {
|
||||
this.tablespaceMeta = tablespaceMeta;
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ final class AnnotationClass extends AnnotationParser {
|
||||
|
||||
UniqueConstraint uc = typeGet(cls, UniqueConstraint.class);
|
||||
if (uc != null) {
|
||||
descriptor.addIndex(new IndexDefinition(convertColumnNames(uc.columnNames())));
|
||||
descriptor.addIndex(new IndexDefinition(uc.name(), convertColumnNames(uc.columnNames())));
|
||||
}
|
||||
View view = typeGet(cls, View.class);
|
||||
if (view != null) {
|
||||
@@ -145,7 +145,7 @@ final class AnnotationClass extends AnnotationParser {
|
||||
if (table != null) {
|
||||
UniqueConstraint[] uniqueConstraints = table.uniqueConstraints();
|
||||
for (UniqueConstraint c : uniqueConstraints) {
|
||||
descriptor.addIndex(new IndexDefinition(convertColumnNames(c.columnNames())));
|
||||
descriptor.addIndex(new IndexDefinition(c.name(), convertColumnNames(c.columnNames())));
|
||||
}
|
||||
}
|
||||
StorageEngine storage = typeGet(cls, StorageEngine.class);
|
||||
|
||||
@@ -46,20 +46,29 @@ final class DtoMetaBuilder {
|
||||
}
|
||||
|
||||
static String propertyName(String methodName) {
|
||||
final String name = methodName.substring(3);
|
||||
return Character.toLowerCase(name.charAt(0)) + name.substring(1);
|
||||
if (isTraditionalSetterMethod(methodName)) {
|
||||
final String name = methodName.substring(3);
|
||||
return Character.toLowerCase(name.charAt(0)) + name.substring(1);
|
||||
} else {
|
||||
// accessor style setter method
|
||||
return methodName;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isTraditionalSetterMethod(String methodName) {
|
||||
return methodName.startsWith("set") && methodName.length() > 3 && Character.isUpperCase(methodName.charAt(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Include a public "setter" method - 1 argument, returns void.
|
||||
*/
|
||||
static boolean includeMethod(Method method) {
|
||||
String name = method.getName();
|
||||
final int modifiers = method.getModifiers();
|
||||
return Modifier.isPublic(modifiers)
|
||||
&& !Modifier.isStatic(modifiers)
|
||||
&& Void.TYPE.equals(method.getReturnType())
|
||||
&& method.getParameterTypes().length == 1
|
||||
&& method.getName().startsWith("set") && method.getName().length() > 3;
|
||||
&& (!name.equals("wait") && !name.equals("equals"));
|
||||
}
|
||||
|
||||
private void readConstructors() {
|
||||
|
||||
@@ -467,6 +467,11 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
return query.findSingleAttributeList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A> Set<A> findSingleAttributeSet() {
|
||||
return query.findSingleAttributeSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return query.exists();
|
||||
|
||||
@@ -464,6 +464,11 @@ final class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expr
|
||||
return exprList.findSingleAttributeList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A> Set<A> findSingleAttributeSet() {
|
||||
return exprList.findSingleAttributeSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PagedList<T> findPagedList() {
|
||||
return exprList.findPagedList();
|
||||
|
||||
@@ -24,7 +24,7 @@ import static io.ebeaninternal.server.persist.DmlUtil.isNullOrZero;
|
||||
/**
|
||||
* Saves the details for a OneToMany or ManyToMany relationship (entity beans).
|
||||
*/
|
||||
public final class SaveManyBeans extends SaveManyBase {
|
||||
final class SaveManyBeans extends SaveManyBase {
|
||||
|
||||
private final boolean cascade;
|
||||
private final boolean publish;
|
||||
@@ -34,7 +34,9 @@ public final class SaveManyBeans extends SaveManyBase {
|
||||
private final DeleteMode deleteMode;
|
||||
private final boolean untouchedBeanCollection;
|
||||
private final Collection<?> collection;
|
||||
private final boolean hasOrderColumn;
|
||||
private int sortOrder;
|
||||
private boolean insertAllChildren;
|
||||
|
||||
SaveManyBeans(DefaultPersister persister, boolean insertedParent, BeanPropertyAssocMany<?> many, EntityBean parentBean, PersistRequestBean<?> request) {
|
||||
super(persister, insertedParent, many, parentBean, request);
|
||||
@@ -46,6 +48,7 @@ public final class SaveManyBeans extends SaveManyBase {
|
||||
this.deleteMode = targetDescriptor.isSoftDelete() ? DeleteMode.SOFT : DeleteMode.HARD;
|
||||
this.untouchedBeanCollection = untouchedBeanCollection();
|
||||
this.collection = cascade ? BeanCollectionUtil.getActualEntries(value) : null;
|
||||
this.hasOrderColumn = many.hasOrderColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +76,7 @@ public final class SaveManyBeans extends SaveManyBase {
|
||||
resetModifyState();
|
||||
}
|
||||
} else {
|
||||
if (isModifyListenMode() || many.hasOrderColumn()) {
|
||||
if (isModifyListenMode() || hasOrderColumn) {
|
||||
// delete any removed beans / orphans
|
||||
removeAssocManyOrphans();
|
||||
}
|
||||
@@ -90,6 +93,7 @@ public final class SaveManyBeans extends SaveManyBase {
|
||||
|
||||
private boolean isSaveIntersection() {
|
||||
if (!many.isManyToMany()) {
|
||||
// OneToMany JoinTable
|
||||
return true;
|
||||
}
|
||||
return transaction.isSaveAssocManyIntersection(many.intersectionTableJoin().getTable(), many.descriptor().rootName());
|
||||
@@ -112,26 +116,22 @@ public final class SaveManyBeans extends SaveManyBase {
|
||||
|
||||
private void processDetails() {
|
||||
BeanProperty orderColumn = null;
|
||||
boolean hasOrderColumn = many.hasOrderColumn();
|
||||
if (hasOrderColumn) {
|
||||
if (!insertedParent && canSkipForOrderColumn() && saveRecurseSkippable) {
|
||||
return;
|
||||
}
|
||||
orderColumn = targetDescriptor.orderColumn();
|
||||
}
|
||||
|
||||
if (insertedParent) {
|
||||
// performance optimisation for large collections
|
||||
targetDescriptor.preAllocateIds(collection.size());
|
||||
}
|
||||
|
||||
if (!insertedParent && many.isOrphanRemoval() && request.isForcedUpdate()) {
|
||||
if (forcedUpdateOrphanRemoval()) {
|
||||
// collect the Id's (to exclude from deleteManyDetails)
|
||||
List<Object> detailIds = collectIds(collection, targetDescriptor, isMap);
|
||||
// deleting missing children - children not in our collected detailIds
|
||||
persister.deleteManyDetails(transaction, many.descriptor(), parentBean, many, detailIds, deleteMode);
|
||||
}
|
||||
|
||||
transaction.depth(+1);
|
||||
saveAllBeans(orderColumn);
|
||||
if (hasOrderColumn) {
|
||||
@@ -140,17 +140,18 @@ public final class SaveManyBeans extends SaveManyBase {
|
||||
transaction.depth(-1);
|
||||
}
|
||||
|
||||
private void saveAllBeans(BeanProperty orderColumn) {
|
||||
// if a map, then we get the key value and
|
||||
// set it to the appropriate property on the
|
||||
// detail bean before we save it
|
||||
private boolean forcedUpdateOrphanRemoval() {
|
||||
return !insertedParent && many.isOrphanRemoval() && request.isForcedUpdate();
|
||||
}
|
||||
|
||||
private void saveAllBeans(final BeanProperty orderColumn) {
|
||||
Object mapKeyValue = null;
|
||||
boolean skipSavingThisBean;
|
||||
|
||||
boolean clearedParent = false;
|
||||
for (Object detailBean : collection) {
|
||||
sortOrder++;
|
||||
if (isMap) {
|
||||
// its a map so need the key and value
|
||||
// a map so need the key and value
|
||||
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) detailBean;
|
||||
mapKeyValue = entry.getKey();
|
||||
detailBean = entry.getValue();
|
||||
@@ -169,25 +170,28 @@ public final class SaveManyBeans extends SaveManyBase {
|
||||
ebi.setDirty(true);
|
||||
}
|
||||
}
|
||||
if (targetDescriptor.isReference(ebi) && originalOrder == 0) {
|
||||
if (originalOrder == 0 && targetDescriptor.isReference(ebi)) {
|
||||
// we can skip this one
|
||||
skipSavingThisBean = true;
|
||||
} else if (ebi.isNewOrDirty()) {
|
||||
skipSavingThisBean = false;
|
||||
// set the parent bean to detailBean
|
||||
many.setJoinValuesToChild(parentBean, detail, mapKeyValue);
|
||||
} else if (insertAllChildren) {
|
||||
ebi.setNew();
|
||||
skipSavingThisBean = false;
|
||||
many.setJoinValuesToChild(parentBean, detail, mapKeyValue);
|
||||
} else {
|
||||
// unmodified so skip depending on prop.isSaveRecurseSkippable();
|
||||
skipSavingThisBean = saveRecurseSkippable;
|
||||
}
|
||||
}
|
||||
|
||||
if (!skipSavingThisBean) {
|
||||
persister.saveRecurse(detail, transaction, parentBean, request.flags());
|
||||
if (many.hasOrderColumn()) {
|
||||
// Clear the bean from the PersistenceContext (L1 cache), because the order of referenced beans might have changed
|
||||
if (hasOrderColumn && !clearedParent) {
|
||||
// Clear the parent bean from the PersistenceContext (L1 cache), because the order of referenced beans might have changed
|
||||
final BeanDescriptor<?> beanDescriptor = many.descriptor();
|
||||
beanDescriptor.contextClear(transaction.getPersistenceContext(), beanDescriptor.getId(parentBean));
|
||||
clearedParent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -340,8 +344,9 @@ public final class SaveManyBeans extends SaveManyBase {
|
||||
return;
|
||||
}
|
||||
if (!(value instanceof BeanCollection<?>)) {
|
||||
if (!insertedParent && cascade && isChangedProperty()) {
|
||||
if (!forcedUpdateOrphanRemoval() && (!insertedParent && cascade && isChangedProperty())) {
|
||||
persister.addToFlushQueue(many.deleteByParentId(request.beanId(), null), transaction, 0);
|
||||
insertAllChildren = true;
|
||||
}
|
||||
} else {
|
||||
BeanCollection<?> c = (BeanCollection<?>) value;
|
||||
@@ -351,7 +356,7 @@ public final class SaveManyBeans extends SaveManyBase {
|
||||
c.setModifyListening(many.modifyListenMode());
|
||||
}
|
||||
// We must not reset when we still have to update other entities in the collection and set their new orderColumn value
|
||||
if (!many.hasOrderColumn()) {
|
||||
if (!hasOrderColumn) {
|
||||
c.modifyReset();
|
||||
}
|
||||
if (modifyRemovals != null && !modifyRemovals.isEmpty()) {
|
||||
|
||||
@@ -605,14 +605,6 @@ public final class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfi
|
||||
return logWhereSql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the property that is associated with the many. There can only be one
|
||||
* per SqlSelect. This can be null.
|
||||
*/
|
||||
@Override
|
||||
public STreePropertyAssocMany getManyProperty() {
|
||||
return manyProperty;
|
||||
}
|
||||
|
||||
public String getBindLog() {
|
||||
return bindLog;
|
||||
|
||||
@@ -644,10 +644,12 @@ final class CQueryBuilder {
|
||||
}
|
||||
|
||||
private void appendHistoryAsOfPredicate() {
|
||||
if (query.isAsOfBaseTable() && !historySupport.isStandardsBased()) {
|
||||
appendAndOrWhere();
|
||||
sb.append(historySupport.getAsOfPredicate(request.baseTableAlias()));
|
||||
if (query.isAsOfBaseTable()) {
|
||||
query.incrementAsOfTableCount();
|
||||
if (!historySupport.isStandardsBased()){
|
||||
appendAndOrWhere();
|
||||
sb.append(historySupport.getAsOfPredicate(request.baseTableAlias()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,11 +24,7 @@ import org.slf4j.Logger;
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Handles the Object Relational fetching.
|
||||
@@ -91,16 +87,16 @@ public final class CQueryEngine {
|
||||
/**
|
||||
* Build and execute the findSingleAttributeList query.
|
||||
*/
|
||||
public <A> List<A> findSingleAttributeList(OrmQueryRequest<?> request) {
|
||||
public <A extends Collection<?>> A findSingleAttributeList(OrmQueryRequest<?> request, A collection) {
|
||||
CQueryFetchSingleAttribute rcQuery = queryBuilder.buildFetchAttributeQuery(request);
|
||||
request.setCancelableQuery(rcQuery);
|
||||
return findAttributeList(request, rcQuery);
|
||||
return findAttributeCollection(request, rcQuery, collection);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <A> List<A> findAttributeList(OrmQueryRequest<?> request, CQueryFetchSingleAttribute rcQuery) {
|
||||
private <A extends Collection<?>> A findAttributeCollection(OrmQueryRequest<?> request, CQueryFetchSingleAttribute rcQuery, A collection) {
|
||||
try {
|
||||
List<A> list = (List<A>) rcQuery.findList();
|
||||
rcQuery.findCollection(collection);
|
||||
if (request.logSql()) {
|
||||
logGeneratedSql(request, rcQuery.getGeneratedSql(), rcQuery.getBindLog(), rcQuery.micros());
|
||||
}
|
||||
@@ -109,13 +105,21 @@ public final class CQueryEngine {
|
||||
}
|
||||
if (request.isQueryCachePut()) {
|
||||
request.addDependentTables(rcQuery.getDependentTables());
|
||||
list = Collections.unmodifiableList(list);
|
||||
request.putToQueryCache(list);
|
||||
if (Boolean.FALSE.equals(request.query().isReadOnly())) {
|
||||
list = new ArrayList<>(list);
|
||||
if (collection instanceof List) {
|
||||
collection = (A) Collections.unmodifiableList((List<?>) collection);
|
||||
request.putToQueryCache(collection);
|
||||
if (Boolean.FALSE.equals(request.query().isReadOnly())) {
|
||||
collection = (A) new ArrayList<>(collection);
|
||||
}
|
||||
} else if (collection instanceof Set) {
|
||||
collection = (A) Collections.unmodifiableSet((Set<?>) collection);
|
||||
request.putToQueryCache(collection);
|
||||
if (Boolean.FALSE.equals(request.query().isReadOnly())) {
|
||||
collection = (A) new LinkedHashSet<>(collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
return collection;
|
||||
} catch (SQLException e) {
|
||||
throw translate(request, rcQuery.getBindLog(), rcQuery.getGeneratedSql(), e);
|
||||
}
|
||||
@@ -144,7 +148,7 @@ public final class CQueryEngine {
|
||||
public <A> List<A> findIds(OrmQueryRequest<?> request) {
|
||||
CQueryFetchSingleAttribute rcQuery = queryBuilder.buildFetchIdsQuery(request);
|
||||
request.setCancelableQuery(rcQuery);
|
||||
return findAttributeList(request, rcQuery);
|
||||
return findAttributeCollection(request, rcQuery, new ArrayList<>());
|
||||
}
|
||||
|
||||
private <T> void logGeneratedSql(OrmQueryRequest<T> request, String sql, String bindLog, long micros) {
|
||||
|
||||
+2
-3
@@ -16,6 +16,7 @@ import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
@@ -76,11 +77,10 @@ final class CQueryFetchSingleAttribute implements SpiProfileTransactionEvent, Ca
|
||||
/**
|
||||
* Execute the query returning the row count.
|
||||
*/
|
||||
List<Object> findList() throws SQLException {
|
||||
void findCollection(Collection result) throws SQLException {
|
||||
long startNano = System.nanoTime();
|
||||
try {
|
||||
prepareExecute();
|
||||
List<Object> result = new ArrayList<>();
|
||||
while (dataReader.next()) {
|
||||
Object value = reader.read(dataReader);
|
||||
if (containsCounts) {
|
||||
@@ -95,7 +95,6 @@ final class CQueryFetchSingleAttribute implements SpiProfileTransactionEvent, Ca
|
||||
queryPlan.captureBindForQueryPlan(predicates, executionTimeMicros);
|
||||
}
|
||||
getTransaction().profileEvent(this);
|
||||
return result;
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
|
||||
@@ -134,6 +134,9 @@ final class DefaultDbSqlContext implements DbSqlContext {
|
||||
String asOfView = historySupport.getAsOfView(table);
|
||||
appendTable(table, asOfView);
|
||||
if (asOfView != null) {
|
||||
if (historySupport.isStandardsBased()) {
|
||||
asOfTableCount++;
|
||||
}
|
||||
addAsOfOnClause = !historySupport.isStandardsBased();
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user