Compare commits

..
Author SHA1 Message Date
rob bygrave 08d241d946 #1966 Remove sequence batching - postgres opps 2020-03-05 00:34:05 +13:00
rob bygrave 1c24ebf6dc Remove Sequence batching in favour of JPA increment 50
Also remove h2sqldb in favour of always using H2
2020-03-05 00:22:20 +13:00
5832 changed files with 170124 additions and 263662 deletions
+6
View File
@@ -1,3 +1,9 @@
GITHUB ISSUES ARE STRICTLY CONTROLLED FOR THIS PROJECT.
Refer to http://ebean-orm.github.io/support for the policies controlling the use of github issues.
Please post issues to the Ebean group https://groups.google.com/forum/#!forum/ebean first.
## Expected behavior
## Actual behavior
-44
View File
@@ -1,44 +0,0 @@
name: Build
on:
workflow_dispatch:
pull_request:
push:
branches: master
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java_version }}
distribution: 'zulu'
- name: Maven cache
uses: actions/cache@v4
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: Maven version
run: mvn --version
# - 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 -T 8 clean test -Pdefault
-38
View File
@@ -1,38 +0,0 @@
name: DB2 LUW
on:
workflow_dispatch:
schedule:
- cron: '10 8 * * 2,5'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v4
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: db2
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-db2.properties
-41
View File
@@ -1,41 +0,0 @@
name: H2Database
on:
workflow_dispatch:
schedule:
- cron: '10 1 * * *'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java_version }}
distribution: 'zulu'
- name: Maven cache
uses: actions/cache@v4
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: Maven version
run: mvn --version
- name: H2Database
run: mvn -T 8 clean package
-41
View File
@@ -1,41 +0,0 @@
name: ebean EA
on:
workflow_dispatch:
schedule:
- cron: '39 6 * * 1,3,5'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [GA,EA]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: oracle-actions/setup-java@v1
with:
website: jdk.java.net
release: ${{ matrix.java_version }}
- name: Maven cache
uses: actions/cache@v4
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: Maven version
run: mvn --version
- name: Build with Maven
run: mvn test -Pea
-38
View File
@@ -1,38 +0,0 @@
name: MariaDB
on:
workflow_dispatch:
schedule:
- cron: '10 7 * * 1,4'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v4
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: mariadb 10.11
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-mariadb.properties
-51
View File
@@ -1,51 +0,0 @@
name: Multi-database platform
on: [workflow_dispatch]
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v4
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: h2database
run: mvn clean test
- name: postgres
run: mvn clean test -Dprops.file=testconfig/ebean-postgres.properties
- name: mysql
run: mvn clean test -Dprops.file=testconfig/ebean-mysql.properties
- name: mariadb
run: mvn clean test -Dprops.file=testconfig/ebean-mariadb.properties
- name: yugabyte
run: mvn clean test -Dprops.file=testconfig/ebean-yugabyte.properties
- name: sqlserver
run: mvn clean test -Dprops.file=testconfig/ebean-sqlserver17.properties
# - name: sqlserver19
# run: mvn clean test -Dprops.file=testconfig/ebean-sqlserver19.properties
# - name: db2
# run: mvn clean test -Dprops.file=testconfig/ebean-db2.properties
# - name: oracle
# run: mvn clean test -Dprops.file=testconfig/ebean-oracle.properties
-41
View File
@@ -1,41 +0,0 @@
name: Multi-JDK Build
on:
workflow_dispatch:
schedule:
- cron: '30 6 * * *'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11, 17, 21]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java_version }}
distribution: 'zulu'
- name: Maven cache
uses: actions/cache@v4
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: Maven version
run: mvn --version
- name: Build with Maven
run: mvn package
-38
View File
@@ -1,38 +0,0 @@
name: MySql
on:
workflow_dispatch:
schedule:
- cron: '20 6 * * *'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v4
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: mysql
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-mysql.properties
-38
View File
@@ -1,38 +0,0 @@
name: Oracle
on:
workflow_dispatch:
schedule:
- cron: '10 6 * * 1,4'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java_version }}
distribution: 'zulu'
- name: Maven cache
uses: actions/cache@v4
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: oracle
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-oracle.properties
-38
View File
@@ -1,38 +0,0 @@
name: Postgres
on:
workflow_dispatch:
schedule:
- cron: '10 6 * * *'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v4
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: postgres
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-postgres.properties
-35
View File
@@ -1,35 +0,0 @@
name: SqlServer 2019
on: [workflow_dispatch]
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v4
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: sqlserver 2019 latest
run: mvn clean test -Dprops.file=testconfig/ebean-sqlserver19.properties
-38
View File
@@ -1,38 +0,0 @@
name: SqlServer
on:
workflow_dispatch:
schedule:
- cron: '10 7 * * 2,5'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v4
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: sqlserver 2022
run: mvn -T 8 clean test -Dprops.file=testconfig/ebean-sqlserver.properties
-41
View File
@@ -1,41 +0,0 @@
name: Valhalla EA
on:
workflow_dispatch:
schedule:
- cron: '39 2 * * 3'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [valhalla]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: oracle-actions/setup-java@v1
with:
website: jdk.java.net
release: ${{ matrix.java_version }}
- name: Maven cache
uses: actions/cache@v4
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: Maven version
run: mvn --version
# - name: Prepare
# run: ./jakarta-to-valhalla.sh
- name: Build with Maven
run: mvn package
-38
View File
@@ -1,38 +0,0 @@
name: Yugabyte
on:
workflow_dispatch:
schedule:
- cron: '10 3 * * 3'
jobs:
build:
runs-on: ${{ matrix.os }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
java_version: [11]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v4
env:
cache-name: maven-cache
with:
path:
~/.m2
key: build-${{ env.cache-name }}
- name: yugabyte
run: mvn clean test -Dprops.file=testconfig/ebean-yugabyte.properties
+4 -2
View File
@@ -1,4 +1,6 @@
*.autofetch
*create-all.sql
*drop-all.sql
*.orig
.classpath
.project
@@ -10,12 +12,12 @@ ebean-autotune.xml
ebean-profiling*.xml
/db
/mydb.db
!src/test/ddl-review/*.sql
profiling/
.DS_Store
# Intellij project files
*.iml
*.ipr
*.iws
.idea/
*uuid.state
*uuid.state
+1 -1
View File
@@ -34,7 +34,7 @@ env:
install: true
script:
- mvn -T 1C clean test
- mvn clean test
after_failure:
- ./.travis/print_surefire_reports
+1 -8
View File
@@ -7,11 +7,4 @@ do
echo ${file}
cat ${file}
echo
done
for file in ebean-autotune/target/surefire-reports/*.txt
do
echo ${file}
cat ${file}
echo
done
done
+13 -12
View File
@@ -4,13 +4,13 @@ Overview of ebean.properties file
### DbMigration options
You can set individual values for different platforms when generating migrations.
You can set individual values for different platforms when generating migrations
`dbmigration.platform.<PLATFORM>.databaseSequenceBatchSize`
For DB's using sequences this is the number of sequence values prefetched.
`dbmigration.platform.<PLATFORM>.dbuuid`
Control, how UUID generation should work - it affects which column type is generated in DDL. Possible values:
Control, how UUID generation should work - it affects DDL which column type is generated. Possible values:
- BINARY enforces binary UUID
- VARCHAR enforces varchar UUID
- BINARY_OPTIMIZED enforces binary-optimized UUID (makes sense only with Type1 ID)
@@ -19,7 +19,7 @@ Control, how UUID generation should work - it affects which column type is gener
- AUTO_VARCHAR (default) use varchar when platform does not support UUID
`dbmigration.platform.<PLATFORM>.uuidStoreAsBinary`
Same as setting dbuuid to BINARY.
Same as setting dbuuid to BINARY
`dbmigration.platform.<PLATFORM>.geometrySRID`
The Geometry SRID value (default 4326).
@@ -30,6 +30,7 @@ The ID type (IDENTITY, SEQUENCE, GENERATOR, EXTERNAL)
`dbmigration.platform.<PLATFORM>.mapping`
Adjust the mapping. For example `BOOLEAN=integer(32);BIT=tinyint(3)`
`ebean.migration.applyPrefix`
Set this to "V" to be compatible with FlywayDB.
@@ -49,7 +50,7 @@ Set to true if the DB migration should be generated on server start.
The version of a pending drop that should be generated as the next migration.
`ebean.migration.includeGeneratedFileComment`
Adds the header about the migration files being generated when true. Reading 'THIS IS A GENERATED FILE - DO NOT MODIFY'
TODO
`ebean.migration.metaTable`
For running migration the DB table that holds migration execution status. Default 'db_migration'
@@ -64,17 +65,17 @@ Subdirectory the model xml files go into. Default 'model'
Suffix. Default '.model.xml'
`ebean.migration.name`
Description text that can be appended to the version to become the ddl script file name.
Description text that can be appended to the version to become the ddl script file name
`ebean.migration.patchInsertOn`
Migration versions that should be added to history without running.
migration versions that should be added to history without running.
`ebean.migration.patchResetChecksumOn`
migration versions that should have their checksum reset and not run.
Use this if you get a 'Checksum mismatch' error.
`ebean.migration.placeholders`
A comma and equals delimited map of placeholders that are substituted in SQL scripts when running migration (used by DB Migration runner only).
A comma and equals delimited placeholders that are substituted in SQL scripts when running migration (used by DB Migration runner only).
`ebean.migration.platform`
The database platform to generate migration DDL for.
@@ -89,7 +90,7 @@ The migration version name (typically FlywayDb compatible). Example: 1.1.1_2
### Ebean UUID options
`ebean.uuidVersion`
Controls how the UUIDs are generated. Possible values:
Controls, how the UUIDs are generated. Possible values
- VERSION4 (default) generate random V4 UUIDs,
- VERSION1 generate rfc4122 compliant Type 1 UUIDs (requires a state file)
- VERSION1RND generate fake Type 1 UUIDs
@@ -97,7 +98,7 @@ Controls how the UUIDs are generated. Possible values:
Note, that V1 UUIDs in conjunction with AUTO_BINARY_OPTIMIZED will give you the best index performance, but you MUST understand how this works to avoid collisions.
`ebean.uuidStateFile`
The state file that is required to generate V1 UUIDs.
The state file that is Required to generate V1 UUIDs
### DocStoreConfig
@@ -106,7 +107,7 @@ The state file that is required to generate V1 UUIDs.
True when the Document store integration is active/on.
`ebean.docstore.allowAllCertificates`
Set to true such that the client allows connections to invalid/self-signed SSL certificates.
Set to true such that the client allows connections to invalid/self signed SSL certificates.
`ebean.docstore.bulkBatchSize`
The default batch size to use for the Bulk API calls.
@@ -191,7 +192,7 @@ Suffix appended to the base table to derive the view that contains the union of
Set to true if the DataSource uses autoCommit. Indicates that Ebean should use autoCommit friendly Transactions and TransactionManager.
`ebean.autoReadOnlyDataSource`
When true create a read only DataSource using readOnlyDataSourceConfig defaulting values from dataSourceConfig.
When true create a read only DataSource using readOnlyDataSourceConfig defaulting values from dataSourceConfig
`ebean.autostart`
Should the server start all
@@ -292,6 +293,6 @@ ebean.tenant.schemaProvider
ebean.updateAllPropertiesInBatch
ebean.updateChangesOnly
ebean.updatesDeleteMissingChildren
ebean.useValidationNotNull
ebean.useJavaxValidationNotNull
ebean.useJtaTransactionManager
-201
View File
@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2012 Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+15
View File
@@ -0,0 +1,15 @@
EbeanORM
Copyright 2012 Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+16 -99
View File
@@ -1,63 +1,18 @@
[![Build](https://github.com/ebean-orm/ebean/actions/workflows/build.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/build.yml)
[![Build Status](https://travis-ci.org/ebean-orm/ebean.svg?branch=master)](https://travis-ci.org/ebean-orm/ebean)
[![Maven Central : ebean](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/ebean-orm/ebean/blob/master/LICENSE)
[![Multi-JDK Build](https://github.com/ebean-orm/ebean/actions/workflows/multi-jdk-build.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/multi-jdk-build.yml)
[![GraalVM Native Image](https://img.shields.io/badge/GraalVM-Native%20Image%20Ready-darkgreen?logo=graalvm)](https://www.graalvm.org/)
##### Build with database platforms
[![H2Database](https://github.com/ebean-orm/ebean/actions/workflows/h2database.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/h2database.yml)
[![Postgres](https://github.com/ebean-orm/ebean/actions/workflows/postgres.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/postgres.yml)
[![MySql](https://github.com/ebean-orm/ebean/actions/workflows/mysql.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/mysql.yml)
[![MariaDB](https://github.com/ebean-orm/ebean/actions/workflows/mariadb.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/mariadb.yml)
[![Oracle](https://github.com/ebean-orm/ebean/actions/workflows/oracle.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/oracle.yml)
[![SqlServer](https://github.com/ebean-orm/ebean/actions/workflows/sqlserver.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/sqlserver.yml)
[![DB2 LUW](https://github.com/ebean-orm/ebean/actions/workflows/db2luw.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/db2luw.yml)
[![Yugabyte](https://github.com/ebean-orm/ebean/actions/workflows/yugabyte.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/yugabyte.yml)
##### Build with Java Early Access versions
[![ebean EA](https://github.com/ebean-orm/ebean/actions/workflows/jdk-ea.yml/badge.svg)](https://github.com/ebean-orm/ebean/actions/workflows/jdk-ea.yml)
[![datasource EA](https://github.com/ebean-orm/ebean-datasource/actions/workflows/jdk-ea.yml/badge.svg)](https://github.com/ebean-orm/ebean-datasource/actions/workflows/jdk-ea.yml)
[![migration EA](https://github.com/ebean-orm/ebean-migration/actions/workflows/jdk-ea.yml/badge.svg)](https://github.com/ebean-orm/ebean-migration/actions/workflows/jdk-ea.yml)
[![test-docker EA](https://github.com/ebean-orm/ebean-test-docker/actions/workflows/jdk-ea.yml/badge.svg)](https://github.com/ebean-orm/ebean-test-docker/actions/workflows/jdk-ea.yml)
[![ebean-agent EA](https://github.com/ebean-orm/ebean-agent/actions/workflows/jdk-ea.yml/badge.svg)](https://github.com/ebean-orm/ebean-agent/actions/workflows/jdk-ea.yml)
----------------------
# Ebean ORM for Java & Kotlin
**Multiple abstraction levels**: Ebean provides multiple levels of query abstraction [ORM Queries, mixed with SQL](https://ebean.io/docs/intro/queries/orm-query), [DTO Queries](https://ebean.io/docs/intro/queries/dto-query), [SqlQuery and JDBC](https://ebean.io/docs/intro/queries/sql-query).
Work at the highest level of abstraction and drop down levels as needed.
**Database migrations**: Built in [DB migration](https://ebean.io/docs/db-migrations/) generation and running. Support for "rebase" migrations as well as repeatable, init and 'normal' migrations.
**Awesome SQL**: Ebean produces SQL that you would hand craft yourself. Use great SQL, never generate SQL cartesian product, always honor relational limit/offset.
**Automated query tuning**: For ORM queries Ebean can profile the object graph being used and either [automatically tune the query](https://ebean.io/docs/query/background/autotune).
**Docker test containers**: [Docker test containers](https://ebean.io/docs/testing/) for all the supported databases. Get 100% test coverage on all the features of the database we use.
**Type safe queries**: We can build queries using type safe [query beans](https://ebean.io/docs/query/query-beans). IDE auto-complete when writing queries, compile time checking and it's FUN.
**Performance isn't optional**: Optimise queries to only fetch what we need (partial objects). Automatically avoid N+1 via a smart load context.
#### Benefits of ORM
* Automatically avoid N+1
* L2 caching to reduce database load
* Queries mixing database and L2 cache
* Automatically tune ORM queries
* Elasticsearch for search or L3 cache
----------------------
# Sponsors
<table>
<tbody>
<tr>
<td align="center" valign="middle">
<a href="https://www.foconis.de/" target="_blank">
<img width="222px" src="https://group.foconis.com/download/ci/logo/png-72dpi/logo-quer/foconis-analytics-quer.png">
<img width="222px" src="https://www.foconis.de/templates/yootheme/cache/foconis_logo_322-709da1de.png">
</a>
</td>
<td align="center" valign="middle">
<a href="https://www.payintech.com/" target="_blank">
<img width="222px" src="https://ebean.io/images/sponsor_PayinTech-logo-noir.png">
</a>
</td>
<td align="center" valign="middle">
@@ -74,56 +29,18 @@ Work at the highest level of abstraction and drop down levels as needed.
</tbody>
</table>
## Need help?
Post questions or issues to the [Ebean google group](https://groups.google.com/forum/#!forum/ebean)
or [github discussions](https://github.com/ebean-orm/ebean/discussions)
# Need help?
Post questions or issues to the Ebean google group - https://groups.google.com/forum/#!forum/ebean
## Documentation
# Documentation
Goto [https://ebean.io/docs/](https://ebean.io/docs/)
## Guides
Step-by-step guides for common tasks: [docs/guides/](docs/guides/README.md)
Available guides:
- [Maven POM setup](docs/guides/add-ebean-postgres-maven-pom.md)
- [Database configuration](docs/guides/add-ebean-postgres-database-config.md)
- [Test container setup](docs/guides/add-ebean-postgres-test-container.md)
- [DB migration generation](docs/guides/add-ebean-db-migration-generation.md)
- [Lombok with Ebean entity beans](docs/guides/lombok-with-ebean-entity-beans.md)
## Maven cental links:
[Maven central - ebean](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22io.ebean%22%20AND%20a%3A%22ebean%22 "maven central ebean")
## Maven central
[Maven central - g:io.ebean](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22io.ebean%22%20)
[Maven central - all related projects](http://search.maven.org/#search%7Cga%7C1%7Cebean "maven central all related projects")
## 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`
end
## Other versions
* [![Maven Central : ebean-agent](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-agent/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-agent) - ebean-agent
* [![Maven Central : ebean-maven-plugin](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-maven-plugin/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-maven-plugin) - ebean-maven-plugin
-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-clickhouse</name>
<description>ebean-clickhouse composite</description>
<artifactId>ebean-clickhouse</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>16.5.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.clickhouse.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.clickhouse {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.clickhouse;
}
-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-cockroach</name>
<description>ebean-cockroach composite</description>
<artifactId>ebean-cockroach</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>16.5.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.cockroach.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.cockroach {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.postgres;
}
-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-db2</name>
<description>ebean-db2 composite</description>
<artifactId>ebean-db2</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>16.5.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.db2.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.db2 {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.db2;
}
-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-h2</name>
<description>ebean-h2 composite</description>
<artifactId>ebean-h2</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>16.5.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.h2.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.h2 {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.h2;
}
-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-hana</name>
<description>ebean-hana composite</description>
<artifactId>ebean-hana</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>16.5.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.hana.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.hana {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.hana;
}
-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-mariadb</name>
<description>ebean-mariadb composite</description>
<artifactId>ebean-mariadb</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>16.5.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.mariadb.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.mariadb {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.mariadb;
}
-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-mysql</name>
<description>ebean-mysql composite</description>
<artifactId>ebean-mysql</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>16.5.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.mysql.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.mysql {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.mysql;
}
-85
View File
@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-net-postgis</name>
<description>ebean-net-postgis composite</description>
<artifactId>ebean-net-postgis</artifactId>
<properties>
<postgis.jdbc.version>2023.1.0</postgis.jdbc.version>
<postgres.jdbc.version>42.7.2</postgres.jdbc.version>
</properties>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-net-postgis-types</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgres.jdbc.version}</version>
<exclusions>
<!-- exclude unnecessary checker framework -->
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.postgis</groupId>
<artifactId>postgis-jdbc</artifactId>
<version>${postgis.jdbc.version}</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.postgis.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,10 +0,0 @@
module io.ebean.postgis {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.postgres;
// requires transitive io.ebean.postgis.types;
}
-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-nuodb</name>
<description>ebean-nuodb composite</description>
<artifactId>ebean-nuodb</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>16.5.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.nuodb.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.nuodb {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.nuodb;
}
-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-oracle</name>
<description>ebean-oracle composite</description>
<artifactId>ebean-oracle</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>16.5.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.oracle.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.oracle {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.oracle;
}
-85
View File
@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-pgvector</name>
<description>ebean-pgvector composite</description>
<artifactId>ebean-pgvector</artifactId>
<properties>
<pgvector.version>0.1.6</pgvector.version>
<postgres.jdbc.version>42.7.2</postgres.jdbc.version>
</properties>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-pgvector-types</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgres.jdbc.version}</version>
<exclusions>
<!-- exclude unnecessary checker framework -->
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.pgvector</groupId>
<artifactId>pgvector</artifactId>
<version>${pgvector.version}</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.pgvector.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.pgvector {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.postgres;
}
-85
View File
@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-postgis</name>
<description>ebean-postgis composite</description>
<artifactId>ebean-postgis</artifactId>
<properties>
<postgis.jdbc.version>2.5.1</postgis.jdbc.version>
<postgres.jdbc.version>42.7.2</postgres.jdbc.version>
</properties>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis-types</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgres.jdbc.version}</version>
<exclusions>
<!-- exclude unnecessary checker framework -->
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.postgis</groupId>
<artifactId>postgis-jdbc</artifactId>
<version>${postgis.jdbc.version}</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.postgis.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,10 +0,0 @@
module io.ebean.postgis {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.postgres;
// requires transitive io.ebean.postgis.types;
}
-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-postgres</name>
<description>ebean-postgres composite</description>
<artifactId>ebean-postgres</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>16.5.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.postgres.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.postgres {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.postgres;
}
-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-sqlite</name>
<description>ebean-sqlite composite</description>
<artifactId>ebean-sqlite</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>16.5.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.sqlite.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.sqlite {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.sqlite;
}
-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-sqlserver</name>
<description>ebean-sqlserver composite</description>
<artifactId>ebean-sqlserver</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>16.5.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.sqlserver.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.sqlserver {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.sqlserver;
}
-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean-yugabyte</name>
<description>ebean-yugabyte composite</description>
<artifactId>ebean-yugabyte</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>16.5.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.yugabyte.assembly;
/**
* Nothing interesting here - required placeholder for javadoc.
*/
public class Assembly {
}
@@ -1,9 +0,0 @@
module io.ebean.yugabyte {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.postgres;
}
-73
View File
@@ -1,73 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
<relativePath>../..</relativePath>
</parent>
<name>ebean (all platforms)</name>
<description>composite of common runtime dependencies for all platforms</description>
<artifactId>ebean</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.5.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>16.5.0</version>
</dependency>
</dependencies>
</project>
@@ -1,7 +0,0 @@
package io.ebean.assembly;
/**
* Nothing interesting here - look at ebean-api.
*/
public class Assembly {
}
@@ -1,8 +0,0 @@
module io.ebean {
requires transitive io.ebean.api;
requires transitive io.ebean.core;
requires transitive io.ebean.datasource;
requires transitive io.ebean.querybean;
requires transitive io.ebean.platform.all;
}
-35
View File
@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
</parent>
<artifactId>composites</artifactId>
<packaging>pom</packaging>
<modules>
<module>ebean</module>
<module>ebean-clickhouse</module>
<module>ebean-cockroach</module>
<module>ebean-db2</module>
<module>ebean-h2</module>
<module>ebean-hana</module>
<!-- <module>hsqldb</module>-->
<module>ebean-mariadb</module>
<module>ebean-mysql</module>
<module>ebean-nuodb</module>
<module>ebean-oracle</module>
<module>ebean-postgres</module>
<module>ebean-postgis</module>
<module>ebean-net-postgis</module>
<module>ebean-pgvector</module>
<!-- <module>sqlanywhere</module>-->
<module>ebean-sqlite</module>
<module>ebean-sqlserver</module>
<module>ebean-yugabyte</module>
</modules>
</project>
-109
View File
@@ -1,109 +0,0 @@
# Guides
Step-by-step guides written as instructions for AI agents and developers.
## Adding Ebean ORM with PostgreSQL to an existing Maven project
A three-part guide covering everything needed to wire Ebean + PostgreSQL into an
existing Maven project. Complete the steps in order.
| Step | Guide | Description |
|------|-------|-------------|
| 1 | [Maven POM setup](add-ebean-postgres-maven-pom.md) | Add Ebean dependencies, the enhancement plugin, and the querybean-generator annotation processor to `pom.xml` |
| 2 | [Database configuration](add-ebean-postgres-database-config.md) | Configure the Ebean `Database` bean using `DataSourceBuilder` and `DatabaseBuilder` with Avaje Inject |
| 3 | [Test container setup](add-ebean-postgres-test-container.md) | Start a PostgreSQL (or PostGIS) Docker container for tests using `@TestScope @Factory` with Avaje Inject; covers image mirror, read-only datasource, and PostGIS variant |
## Entity beans
| Guide | Description |
|-------|-------------|
| [Lombok with Ebean entity beans](lombok-with-ebean-entity-beans.md) | Which Lombok annotations to use and avoid on entity beans; why `@Data` is incompatible with Ebean; how to use `@Getter` + `@Setter` + `@Accessors(chain = true)` |
## Database migrations
| Guide | Description |
|-------|-------------|
| [DB migration generation](add-ebean-db-migration-generation.md) | Add `GenerateDbMigration.java` to generate schema diff migrations offline; configure the migration runner; understand `.sql` and `.model.xml` output files; workflow for pending drops |
## Connection Pooling & DataSource Configuration
The [ebean-datasource](https://github.com/ebean-orm/ebean-datasource) project provides
comprehensive guides on connection pool configuration and best practices. These are particularly
useful for production deployments, especially in Kubernetes or AWS environments:
| Guide | Description |
|-------|-------------|
| [Creating DataSource Pools](https://github.com/ebean-orm/ebean-datasource/blob/master/docs/guides/create-datasource-pool.md) | Step-by-step guide for basic, read-only, Kubernetes, and AWS Lambda datasource configurations |
| [AWS Aurora Read-Write Split](https://github.com/ebean-orm/ebean-datasource/blob/master/docs/guides/aws-aurora-read-write-split.md) | Setting up dual DataSources with Aurora read and write endpoints for Ebean integration |
| [Connection Validation Best Practices](https://github.com/ebean-orm/ebean-datasource/blob/master/docs/guides/connection-validation-best-practices.md) | Understanding connection heartbeat strategies and why `Connection.isValid()` is the recommended approach |
---
## Helping AI agents find these guides
AI coding agents can only follow these guides if they know they exist. Below are
copy-paste snippets for the most common AI tooling configurations. Add whichever
applies to your project.
### Project `README.md` (universal — works with all AI tools)
Add a section near the top of your project README:
```markdown
## AI Agent Instructions
This project uses [Ebean ORM](https://ebean.io). Step-by-step guides for common
Ebean tasks (Maven setup, database configuration, test containers, DB migrations,
Lombok) are at:
**https://github.com/ebean-orm/ebean/tree/main/docs/guides/**
AI agents should fetch and follow the relevant guide before performing Ebean-related
tasks.
```
### Why README is important
Many AI agents (Copilot, Claude, Cursor, Aider) read the project `README.md`
automatically as part of understanding the codebase. A visible link in README is the
most universally effective way to ensure any agent working on your project will
discover the guides without requiring tool-specific configuration files.
------
### GitHub Copilot — `.github/copilot-instructions.md`
```markdown
## Ebean ORM
This project uses [Ebean ORM](https://ebean.io). Step-by-step guides for common
tasks are at: https://github.com/ebean-orm/ebean/tree/main/docs/guides/
Key guides (fetch and follow these when performing the relevant task):
- Maven POM setup: https://raw.githubusercontent.com/ebean-orm/ebean/main/docs/guides/add-ebean-postgres-maven-pom.md
- Database configuration: https://raw.githubusercontent.com/ebean-orm/ebean/main/docs/guides/add-ebean-postgres-database-config.md
- Test container setup: https://raw.githubusercontent.com/ebean-orm/ebean/main/docs/guides/add-ebean-postgres-test-container.md
- DB migration generation: https://raw.githubusercontent.com/ebean-orm/ebean/main/docs/guides/add-ebean-db-migration-generation.md
- Lombok with entity beans: https://raw.githubusercontent.com/ebean-orm/ebean/main/docs/guides/lombok-with-ebean-entity-beans.md
```
### Claude Code — `CLAUDE.md`
Same content as above — Claude Code reads `CLAUDE.md` at the project root.
### Cursor — `.cursor/rules/ebean.mdc`
```markdown
---
description: Ebean ORM task guidance
globs: ["**/*.java", "**/pom.xml"]
alwaysApply: false
---
## Ebean ORM
This project uses Ebean ORM. Before performing any Ebean-related task, fetch and
follow the relevant step-by-step guide from:
https://github.com/ebean-orm/ebean/tree/main/docs/guides/
```
@@ -1,366 +0,0 @@
# Guide: Add Ebean Database Migration Generation to an Existing Maven Project
## Purpose
This guide provides step-by-step instructions for adding Ebean DB migration generation
to an existing Maven project that already uses Ebean ORM. Ebean generates migrations by
performing a diff of the current entity model against the previously recorded model state,
producing platform-specific DDL SQL scripts.
These instructions are designed for AI agents and developers to follow precisely.
---
## Prerequisites
- An existing Maven project with Ebean ORM configured (entity beans present)
- `ebean-test` is already a test-scoped dependency (from POM setup guide)
- The project targets PostgreSQL (adjust `Platform.POSTGRES` for other databases)
---
## Step 1 — Verify migration dependencies
### Generation tooling (`ebean-ddl-generator`)
`ebean-test` (already present as a test dependency) transitively includes
`ebean-ddl-generator`, which provides the `DbMigration` class. No additional dependency
is required for generation.
### Runtime migration runner (`ebean-migration`)
`ebean-migration` is the library that runs migrations on application startup.
It is typically included **transitively** via `io.ebean:ebean-postgres` (or the
equivalent platform dependency). Verify it is on the classpath by running:
```bash
mvn dependency:tree | grep ebean-migration
```
If it is **not** present transitively, add it explicitly as a compile-scope dependency:
```xml
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean.version}</version>
</dependency>
```
---
## Step 2 — Create `GenerateDbMigration.java`
Create the following class in `src/test/java/main/`. This `main` method is run manually
by a developer (or AI agent) whenever entity beans change and a new migration is needed.
```java
package main;
import io.ebean.annotation.Platform;
import io.ebean.dbmigration.DbMigration;
import java.io.IOException;
/**
* Generate the next database migration based on a diff of the entity model.
* Run this main method after making entity bean changes to produce the migration SQL.
*/
public class GenerateDbMigration {
public static void main(String[] args) throws IOException {
DbMigration migration = DbMigration.create();
migration.setPlatform(Platform.POSTGRES);
migration.setVersion("1.1"); // set to the next migration version
migration.setName("add-customer"); // short description of the change
migration.generateMigration();
}
}
```
### Version naming convention
Ebean supports two common version formats — choose one and apply it consistently:
| Format | Example | Notes |
|--------|---------|-------|
| **Date-based** | `20240820` | `YYYYMMDD`; used when changes are tied to dates; easily sortable |
| **Semantic** | `1.1`, `1.2`, `2.0` | Traditional versioning; useful for release-based workflows |
The version controls execution order — Ebean runs migrations in ascending version order.
### Name convention
The `name` should be a short, lowercase, hyphenated description of the change:
- `add-customer-email`
- `rename-machine-type`
- `drop-unused-columns`
---
## Step 3 — Configure the output path (if needed)
By default, migration files are written to `src/main/resources/dbmigration/` relative
to the **current working directory** when `generateMigration()` is called. This is
usually the module root, which is correct for single-module projects.
For **multi-module projects** where `GenerateDbMigration` is in a submodule but the
resources directory is at a different relative path, specify it explicitly:
```java
// Relative path from the working directory (project root) to the module's resources
migration.setPathToResources("my-module/src/main/resources");
```
---
## Step 4 — Run `GenerateDbMigration` to produce the first migration
Run the `main` method via the IDE or Maven:
```bash
# Run via Maven exec plugin (or use IDE run configuration)
mvn test-compile exec:java \
-Dexec.mainClass="main.GenerateDbMigration" \
-Dexec.classpathScope="test" \
-pl <your-module>
```
Ebean migration generation runs in **offline mode** — no database connection is required.
### Expected output files
After running, two files are created per migration in `src/main/resources/dbmigration/`:
```
src/main/resources/dbmigration/
1.1__add-customer.sql ← DDL SQL to apply (commit this)
model/
1.1__add-customer.model.xml ← logical model diff XML (commit this)
```
Both files must be committed to source control. The `.model.xml` file records the
logical state of the diff and is used by subsequent migration generations to determine
what has changed.
If **no entity beans have changed** since the last migration, the command outputs:
```
DbMigration - no changes detected - no migration written
```
---
## Step 5 — Enable the migration runner
Configure Ebean to run pending migrations automatically on application startup.
### Preferred approach — programmatic via `DatabaseBuilder`
Set `runMigration(true)` directly on the `DatabaseBuilder` when constructing
the `Database` bean. This is the preferred approach as it is explicit, co-located with
the database configuration, and does not rely on external property files.
In the `@Factory` class that builds the `Database` bean (see the database configuration
guide), add `.runMigration(true)` to the builder chain:
```java
@Bean
Database database(ConfigWrapper config) {
var dataSource = DataSourceBuilder.create()
.url(config.getDatabaseUrl())
.username(config.getDatabaseUser())
.password(config.getDatabasePassword())
// ... other datasource settings ...
;
return Database.builder()
.name("db")
.dataSourceBuilder(dataSource)
.runMigration(true) // run pending migrations on startup
.build();
}
```
If migrations should only run in certain environments (e.g., not in production, or
only when a config flag is set), make it conditional:
```java
.runMigration(config.isRunMigrations()) // driven by config value
```
### Alternative — via application properties
If programmatic configuration is not available or not preferred, set the property
in `src/main/resources/application.properties`:
```properties
ebean.migration.run=true
```
Or in `src/main/resources/application.yaml`:
```yaml
ebean:
migration:
run: true
```
For a **named database** (i.e., `Database.builder().name("mydb")`), use the database
name in the property key:
```properties
ebean.mydb.migration.run=true
```
### What the runner does at startup
When migration running is enabled, Ebean will on each application start:
1. Look at the migrations in `src/main/resources/dbmigration/`
2. Compare against the `db_migration` table (created automatically on first run)
3. Apply any migrations that have not yet been executed, in version order
4. Record each successfully applied migration in `db_migration`
---
## Step 6 — Commit the migration files
Add both generated files to source control:
```bash
git add src/main/resources/dbmigration/1.1__add-customer.sql
git add src/main/resources/dbmigration/model/1.1__add-customer.model.xml
git commit -m "Add db migration 1.1: add-customer"
```
---
## Ongoing workflow — generating subsequent migrations
For each future set of entity bean changes:
1. Make changes to the entity bean classes
2. Update `GenerateDbMigration.java` with the **new version** and **new name**:
```java
migration.setVersion("1.2");
migration.setName("add-address-table");
```
3. Run the `main` method — a new `.sql` and `.model.xml` pair is written
4. Review the generated `.sql` to confirm it reflects the intended changes
5. Commit both files
---
## Understanding the output files
### Apply SQL (`.sql`)
The apply SQL file contains the DDL that will be executed against the database:
```sql
-- apply changes
alter table customer add column email varchar(255);
```
### Model XML (`.model.xml`)
The model XML records the logical diff in a database-agnostic format. Ebean uses
this file on the next generation run to determine what has already been captured.
It is not executed against the database.
```xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
<changeSet type="apply">
<addColumn tableName="customer">
<column name="email" type="varchar(255)"/>
</addColumn>
</changeSet>
</migration>
```
---
## Optional configurations
### Multiple database platforms
To generate migrations for multiple platforms simultaneously, use `addPlatform()`
instead of `setPlatform()`:
```java
migration.addPlatform(Platform.POSTGRES);
migration.addPlatform(Platform.SQLSERVER17);
migration.addPlatform(Platform.MYSQL);
```
Each platform gets its own subdirectory under `dbmigration/`.
### Include index
When enabled the migration generation also generates a file that contains
all the migrations and their associated hashes. This is a performance
optimisation (that will become the default) and means that the migration
runner just needs to read the one resource and has the pre-computed hash
values (so does not need to read each migration resource and compute the
hash for each of those at runtime).
```java
migration.setIncludeIndex(true);
```
### Strict mode
Strict mode (on by default) errors if there are any pending drops not yet applied.
Set to `false` to allow generation to proceed regardless:
```java
migration.setStrictMode(false);
```
### Applying pending drops
Destructive changes (drop column, drop table) are **not** included in the apply
SQL by default — they are recorded as `pendingDrops` in the model XML. This allows
the application to be deployed without immediately dropping columns (important for
rolling deployments).
The migration runner logs a message when pending drops exist:
```
INFO DbMigration - Pending un-applied drops in versions [1.1]
```
When ready to apply the drops, set `setGeneratePendingDrop` to the version that
contains the pending drops:
```java
migration.setVersion("1.3");
migration.setName("drop-pending-from-1.1");
migration.setGeneratePendingDrop("1.1"); // apply drops recorded in version 1.1
migration.generateMigration();
```
### Custom dbSchema
If the project uses a named Postgres schema (set via `ebean.dbSchema` in
`application.properties`), no additional configuration is needed in
`GenerateDbMigration` — Ebean picks up the schema from the application config
automatically when running in offline mode.
```properties
# application.properties
ebean.dbSchema=myschema
```
---
## Troubleshooting
| Symptom | Likely cause | Fix |
|---------|-------------|-----|
| `no changes detected - no migration written` | Entity beans unchanged since last migration | Make entity bean changes first, then re-run |
| `DbMigration - Pending un-applied drops` | A previous migration has drops not yet applied | Either suppress with `setStrictMode(false)` or apply drops with `setGeneratePendingDrop(...)` |
| Generated SQL is empty or wrong | Wrong working directory path | Set `setPathToResources(...)` to the correct module-relative path |
| `ClassNotFoundException` for entity classes | Test classpath not including main classes | Ensure `exec.classpathScope=test` or run via IDE with test classpath |
| Migrations not running on startup | Property key wrong or `ebean-migration` missing | Verify `ebean[.name].migration.run=true` and that `ebean-migration` is on the classpath |
@@ -1,282 +0,0 @@
# Guide: Add Ebean ORM (PostgreSQL) to an Existing Maven Project — Step 2: Database Configuration
## Purpose
This guide provides step-by-step instructions for configuring an Ebean `Database` bean
using **Avaje Inject** (`@Factory` / `@Bean`), backed by a PostgreSQL datasource built
with Ebean's `DataSourceBuilder`. Follow every step in order. This is Step 2 of 2.
---
## Prerequisites
- **Step 1 complete**: `pom.xml` already includes `ebean-postgres`, `ebean-maven-plugin`,
and `querybean-generator` (see `add-ebean-postgres-maven-pom.md`)
- **Avaje Inject** is on the classpath (e.g. `io.avaje:avaje-inject`)
- A configuration source is available at runtime (e.g. `avaje-config` reading
`application.yml` or environment variables)
- The following configuration keys are resolvable at runtime (adapt names to your project):
| Key | Description |
|-----|-------------|
| `db_url` | JDBC URL for the master/write connection |
| `db_user` | Database username |
| `db_pass` | Database password |
| `db_master_min_connections` | Minimum pool size (default: 1) |
| `db_master_initial_connections` | Initial pool size at startup — set high to pre-warm on pod start (see K8s note below) |
| `db_master_max_connections` | Maximum pool size (default: 200) |
---
## Step 1 — Locate or create the `@Factory` class
Look for an existing Avaje Inject `@Factory`-annotated class in the project
(often named `AppConfig`, `DatabaseConfig`, or similar). If one exists, add the new
`@Bean` method to it. If none exists, create one:
```java
package com.example.configuration;
import io.avaje.inject.Bean;
import io.avaje.inject.Factory;
@Factory
class DatabaseConfig {
// beans will be added in the steps below
}
```
---
## Step 2 — Add the `Database` bean method (minimal — master datasource only)
Add the following `@Bean` method to the `@Factory` class. This creates an Ebean
`Database` backed by a single master (read-write) PostgreSQL datasource.
```java
import io.ebean.Database;
import io.ebean.datasource.DataSourceBuilder;
@Bean
Database database() {
var dataSource = DataSourceBuilder.create()
.url(/* resolve from config, e.g.: */ Config.get("db_url"))
.username(Config.get("db_user"))
.password(Config.get("db_pass"))
.driver("org.postgresql.Driver")
.schema("myschema") // set to your target schema
.applicationName("my-app") // visible in pg_stat_activity
.minConnections(Config.getInt("db_master_min_connections", 1))
.initialConnections(Config.getInt("db_master_initial_connections", 10))
.maxConnections(Config.getInt("db_master_max_connections", 200));
return Database.builder()
.name("db") // logical name for this Database instance
.dataSourceBuilder(dataSource)
.build();
}
```
### Field guidance
| Field | Notes |
|-------|-------|
| `url` | Full JDBC URL, e.g. `jdbc:postgresql://host:5432/dbname` |
| `schema` | The Postgres schema Ebean should use (omit if using `public`) |
| `applicationName` | Shown in `pg_stat_activity.application_name`; helps with DB-side diagnostics |
| `name("db")` | Logical Ebean database name; relevant if multiple Database instances exist |
| `minConnections` | Connections kept open at all times; pool will not shrink below this |
| `initialConnections` | Connections opened at startup; see K8s warm-up note below |
| `maxConnections` | Hard upper limit on concurrent connections |
### Connection pool sizing for Kubernetes (and similar orchestrated environments)
When a pod starts in Kubernetes it will receive live traffic as soon as it passes
readiness checks — often before the connection pool has had a chance to grow to handle
the load. This can cause latency spikes on the first wave of requests while the pool
expands one connection at a time.
Use `initialConnections` to **pre-warm the pool at startup** so it is already sized
for peak load when the pod goes live:
```
minConnections: 2 ← floor; pool will shrink back here when idle
initialConnections: 20 ← opened at pod start, before first request arrives
maxConnections: 50 ← hard ceiling
```
The lifecycle is:
1. **Pod starts** — pool opens `initialConnections` connections immediately.
2. **Pod receives traffic** — pool is already at capacity; no growth latency.
3. **Traffic drops** — idle connections are closed; pool trims back toward `minConnections`.
4. **Next traffic spike** — pool grows again up to `maxConnections` on demand.
Set `initialConnections` to a value high enough that the pool does not need to grow
during the first minute of live traffic. A common starting point is 5075% of
`maxConnections`.
---
## Step 3 — Inject configuration via a constructor or config helper (recommended)
Rather than calling `Config.get(...)` inline, inject a typed config helper or the
Avaje `Configuration` bean if one is available. This makes the factory testable and
keeps the wiring explicit. For example:
```java
@Bean
Database database(Configuration config) {
String url = config.get("db_url");
String user = config.get("db_user");
String pass = config.get("db_pass");
int min = config.getInt("db_master_min_connections", 1);
int init = config.getInt("db_master_initial_connections", 10);
int max = config.getInt("db_master_max_connections", 200);
var dataSource = DataSourceBuilder.create()
.url(url)
.username(user)
.password(pass)
.driver("org.postgresql.Driver")
.schema("myschema")
.applicationName("my-app")
.minConnections(min)
.initialConnections(init)
.maxConnections(max);
return Database.builder()
.name("db")
.dataSourceBuilder(dataSource)
.skipDataSourceCheck(true)
.build();
}
```
If the project has a dedicated config-wrapper class (a `@Component` that reads config
keys), accept it as a parameter instead of `Configuration`.
---
## Step 4 (Optional) — Add a read-only datasource
For production services that have a separate read-replica, add a second
`DataSourceBuilder` for read-only queries and wire it via
`readOnlyDataSourceBuilder(...)`. The read-only datasource:
- Uses `readOnly(true)` and `autoCommit(true)` (Ebean routes read queries there automatically)
- Typically has a higher max connection count than the master
- Benefits from a prepared-statement cache (`pstmtCacheSize`)
```java
@Bean
Database database(Configuration config) {
String masterUrl = config.get("db_url");
String readOnlyUrl = config.get("db_url_readonly");
String user = config.get("db_user");
String pass = config.get("db_pass");
var masterDataSource = buildDataSource(user, pass)
.url(masterUrl)
.minConnections(config.getInt("db_master_min_connections", 1))
.initialConnections(config.getInt("db_master_initial_connections", 10))
.maxConnections(config.getInt("db_master_max_connections", 50));
var readOnlyDataSource = buildDataSource(user, pass)
.url(readOnlyUrl)
.readOnly(true)
.autoCommit(true)
.pstmtCacheSize(250) // cache up to 250 prepared statements per connection
.maxInactiveTimeSecs(600) // close idle connections after 10 minutes
.minConnections(config.getInt("db_readonly_min_connections", 2))
.initialConnections(config.getInt("db_readonly_initial_connections", 10))
.maxConnections(config.getInt("db_readonly_max_connections", 200));
return Database.builder()
.name("db")
.dataSourceBuilder(masterDataSource)
.readOnlyDataSourceBuilder(readOnlyDataSource)
.build();
}
private static DataSourceBuilder buildDataSource(String user, String pass) {
return DataSourceBuilder.create()
.username(user)
.password(pass)
.driver("org.postgresql.Driver")
.schema("myschema")
.applicationName("my-app")
.addProperty("prepareThreshold", "2"); // PostgreSQL: server-side prepared statements
}
```
### Additional configuration keys for the read-only datasource
| Key | Description | Default |
|-----|-------------|---------|
| `db_url_readonly` | JDBC URL for the read replica | — |
| `db_master_initial_connections` | Initial master pool size at startup | 10 |
| `db_readonly_min_connections` | Minimum pool size | 2 |
| `db_readonly_initial_connections` | Initial pool size at startup | same as min |
| `db_readonly_max_connections` | Maximum pool size | 20 |
---
## Step 5 (Optional) — Enable the migration runner
If the project uses Ebean's built-in DB migration runner to apply SQL migrations on
startup, enable it on the `DatabaseBuilder`:
```java
return Database.builder()
.name("db")
.dataSourceBuilder(dataSource)
.runMigration(true) // run pending migrations on startup
.build();
```
This is equivalent to setting `ebean.migration.run=true` in `application.properties`
but is preferred because it keeps all database configuration in one place. To make it
conditional (e.g. only in non-production environments):
```java
.runMigration(config.getBoolean("db.runMigrations", false))
```
See the DB migration generation guide (`add-ebean-db-migration-generation.md`) for
full details on generating and managing migration files.
---
## See Also
For advanced connection pool configuration, production deployment patterns, and connection
validation best practices, see the [ebean-datasource guides](https://github.com/ebean-orm/ebean-datasource/tree/master/docs/guides/):
- **[Creating DataSource Pools](https://github.com/ebean-orm/ebean-datasource/blob/master/docs/guides/create-datasource-pool.md)** — Covers read-only pools (`readOnly(true)` + `autoCommit(true)`), Kubernetes deployment strategies using `initialConnections`, and AWS Lambda optimization
- **[AWS Aurora Read-Write Split](https://github.com/ebean-orm/ebean-datasource/blob/master/docs/guides/aws-aurora-read-write-split.md)** — Setting up dual DataSources with Aurora reader and writer endpoints, including Ebean secondary datasource routing
- **[Connection Validation Best Practices](https://github.com/ebean-orm/ebean-datasource/blob/master/docs/guides/connection-validation-best-practices.md)** — Why `Connection.isValid()` is the recommended default and when (rarely) explicit `heartbeatSql` is needed
---
## Verification
1. Start the application (or run `mvn test -pl <your-module>`).
2. Look for log output similar to:
```
INFO o.a.datasource.pool.ConnectionPool - DataSourcePool [db] autoCommit[false] min[1] max[5]
INFO io.ebean.internal.DefaultContainer - DatabasePlatform name:db platform:postgres
```
3. If you see `DataSourcePool` and `DatabasePlatform` log lines, Ebean is connected and
the database bean is wired correctly.
---
## Troubleshooting
| Symptom | Likely cause | Fix |
|---------|-------------|-----|
| `ClassNotFoundException: org.postgresql.Driver` | PostgreSQL JDBC driver missing | Add `org.postgresql:postgresql` dependency (see Step 1 guide) |
| `Cannot connect to database` at startup | DB unreachable but `skipDataSourceCheck` is `false` | Set `.skipDataSourceCheck(true)` |
| Ebean enhancement warnings in logs | `ebean-maven-plugin` not configured | Complete Step 1 guide |
| `NullPointerException` reading config key | Config key not defined | Add the key to `application.yml` or environment |
-175
View File
@@ -1,175 +0,0 @@
# Guide: Add Ebean ORM (PostgreSQL) to an Existing Maven Project — Step 1: POM Setup
## Purpose
This guide provides step-by-step instructions for modifying an existing Maven `pom.xml`
to add Ebean ORM with PostgreSQL support. Follow every step in order. This is Step 1 of 2.
---
## Prerequisites
- An existing Maven project (`pom.xml` already exists)
- Java 11 or higher
- The project does **not** yet include any Ebean dependencies
---
## Step 1 — Define the Ebean version property
Open the module's `pom.xml` (the one that will use Ebean directly, i.e. the module
containing the database configuration and entity classes).
Inside the `<properties>` block, add the `ebean.version` property if it does not
already exist:
```xml
<properties>
<!-- add this line; use latest stable from https://github.com/ebean-orm/ebean/releases -->
<ebean.version>17.2.0</ebean.version>
</properties>
```
> If the project has a parent POM that already defines `ebean.version`, skip this step.
---
## Step 2 — Add the PostgreSQL JDBC driver dependency
Inside the `<dependencies>` block, add the PostgreSQL JDBC driver:
```xml
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.8</version>
</dependency>
```
> Check [Maven Central](https://central.sonatype.com/artifact/org.postgresql/postgresql)
> for the latest version. If the parent POM manages the PostgreSQL version, omit the
> `<version>` tag.
---
## Step 3 — Add the Ebean PostgreSQL platform dependency
Inside the `<dependencies>` block, add the Ebean Postgres platform dependency:
```xml
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgres</artifactId>
<version>${ebean.version}</version>
</dependency>
```
This single artifact pulls in the Ebean core, the datasource connection pool
(`ebean-datasource`), and all Postgres-specific support.
---
## Step 4 — Add the ebean-test dependency (test scope)
`ebean-test` configures Ebean for tests and enables automatic Docker container management
for Postgres test instances:
```xml
<!-- test dependencies -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>${ebean.version}</version>
<scope>test</scope>
</dependency>
```
---
## Step 5 — Add the ebean-maven-plugin (bytecode enhancement)
Ebean requires bytecode enhancement to provide dirty-checking and lazy-loading.
The `ebean-maven-plugin` performs this enhancement at build time.
Inside the `<build><plugins>` block, add:
```xml
<plugin> <!-- perform ebean enhancement -->
<groupId>io.ebean</groupId>
<artifactId>ebean-maven-plugin</artifactId>
<version>${ebean.version}</version>
<extensions>true</extensions>
</plugin>
```
---
## Step 6 — Add the querybean-generator annotation processor
The `querybean-generator` annotation processor generates type-safe query bean classes
at compile time. It must be registered as an `annotationProcessorPath` inside
`maven-compiler-plugin`.
### Case A — No existing `maven-compiler-plugin` configuration
Add the full plugin entry to `<build><plugins>`:
```xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.15.0</version>
<configuration>
<annotationProcessorPaths>
<path> <!-- generate ebean query beans -->
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>${ebean.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
```
### Case B — `maven-compiler-plugin` already exists with `<annotationProcessorPaths>`
Locate the existing `<annotationProcessorPaths>` block inside the existing
`maven-compiler-plugin` entry and add the new `<path>` inside it. Do **not** add a
second `<configuration>` block or a second `<annotationProcessorPaths>` block.
Example — if the existing block already has a path for, say, `avaje-nima-generator`:
```xml
<annotationProcessorPaths>
<path>
<groupId>io.avaje</groupId>
<artifactId>avaje-nima-generator</artifactId>
<version>${avaje-nima.version}</version>
</path>
<!-- ADD the new path here, inside the existing block -->
<path>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>${ebean.version}</version>
</path>
</annotationProcessorPaths>
```
---
## Verification
Run the following to confirm the POM is valid and the project compiles:
```bash
mvn compile -pl <your-module-name>
```
Expected result: `BUILD SUCCESS` with no errors from Ebean or the annotation processor.
---
## Next Step
Proceed to **Step 2: Configure the Datasource and Ebean Database bean**
(`add-ebean-postgres-database-config.md`).
@@ -1,293 +0,0 @@
# Guide: Add Ebean ORM (PostgreSQL) to an Existing Maven Project — Step 3: Test Container Setup
## Purpose
This guide provides step-by-step instructions for setting up a PostgreSQL Docker
container for tests using `ebean-test-containers`, exposing an `io.ebean.Database`
bean via an Avaje Inject `@TestScope @Factory` class. This is Step 3 of 3.
Two variants are covered:
- **Variant A** — plain PostgreSQL
- **Variant B** — PostgreSQL with PostGIS extension
---
## Prerequisites
- **Step 1 complete**: `pom.xml` includes `ebean-postgres`, `ebean-maven-plugin`,
`querybean-generator`, and **`ebean-test`** as a test-scoped dependency
(see `add-ebean-postgres-maven-pom.md`)
- **Step 2 complete**: A production `Database` bean exists (see `add-ebean-postgres-database-config.md`)
- **Avaje Inject** is on the classpath with test support (`io.avaje:avaje-inject-test`)
- **Docker** is installed and running on the developer machine
---
## Overview: Declarative vs Programmatic approach
`ebean-test` supports two ways to configure the test database:
| Approach | How | Best for |
|----------|-----|---------|
| **Declarative** | `src/test/resources/application-test.yaml` | Simple projects with no DI, no image mirrors |
| **Programmatic** | `@TestScope @Factory` class | Avaje Inject tests, private image mirrors (ECR), more control |
This guide uses the **programmatic approach** because it integrates naturally with
Avaje Inject, allows a private mirror to be specified (useful in CI with ECR or similar),
and makes the `Database` injectable into tests.
---
## Step 1 — Verify ebean-test is a test dependency
Confirm the following is present in `pom.xml` (added in Step 1):
```xml
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>${ebean.version}</version>
<scope>test</scope>
</dependency>
```
`ebean-test` transitively brings in `ebean-test-containers` which provides
`PostgresContainer` and `PostgisContainer`.
---
## Step 2 — Create a `@TestScope @Factory` class
Create a new class in the test source tree (e.g., `src/test/java/.../testconfig/TestConfiguration.java`).
Annotate it with `@TestScope` and `@Factory` so Avaje Inject uses it only in tests.
```java
package com.example.testconfig;
import io.avaje.inject.Bean;
import io.avaje.inject.Factory;
import io.avaje.inject.test.TestScope;
import io.ebean.Database;
@TestScope
@Factory
class TestConfiguration {
// bean methods added in the steps below
}
```
---
## Step 3 — Add a container bean and a Database bean
### Variant A — Plain PostgreSQL
```java
import io.ebean.test.containers.PostgresContainer;
@TestScope
@Factory
class TestConfiguration {
@Bean
PostgresContainer postgres() {
return PostgresContainer.builder("17") // Postgres image version
.dbName("my_app") // database to create inside the container
.build()
.start();
}
@Bean
Database database(PostgresContainer container) {
return container.ebean()
.builder()
.build();
}
}
```
### Variant B — PostGIS (PostgreSQL + PostGIS extension)
Use `PostgisContainer` instead of `PostgresContainer`. The default image is
`ghcr.io/baosystems/postgis:{version}` and the extensions `hstore`, `pgcrypto`,
and `postgis` are installed automatically.
```java
import io.ebean.test.containers.PostgisContainer;
@TestScope
@Factory
class TestConfiguration {
@Bean
PostgisContainer postgres() {
return PostgisContainer.builder("17") // PostGIS image version (Postgres 17)
.dbName("my_app")
.build()
.start();
}
@Bean
Database database(PostgisContainer container) {
return container.ebean()
.builder()
.build();
}
}
```
### Key differences from Variant A
| | PostgresContainer | PostgisContainer |
|---|---|---|
| Docker image | `postgres:{version}` | `ghcr.io/baosystems/postgis:{version}` |
| Default extensions | `hstore, pgcrypto` | `hstore, pgcrypto, postgis` |
| Default port | 6432 | 6432 |
| Optional LW mode | — | `.useLW(true)` (see Optional section) |
---
## Step 4 — Write a test
Annotate the test class with `@InjectTest` and inject `Database` with `@Inject`:
```java
package com.example.testconfig;
import io.avaje.inject.test.InjectTest;
import io.ebean.Database;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@InjectTest
class DatabaseTest {
@Inject
Database database;
@Test
void database_isAvailable() {
assertThat(database).isNotNull();
}
}
```
---
## Verification
Run the tests:
```bash
mvn test -pl <your-module>
```
Expected log output confirming the container started and Ebean connected:
```
INFO Container ut_postgres running with port:6432 ...
INFO connectivity confirmed for ut_postgres
INFO DataSourcePool [my_app] autoCommit[false] ...
INFO DatabasePlatform name:my_app platform:postgres
INFO Executing db-create-all.sql - ...
```
---
## Optional configurations
### Image mirror (for CI / private registry)
If CI builds pull images from a private registry (e.g., AWS ECR) instead of Docker Hub
or GitHub Container Registry, specify a mirror. The mirror is **only used in CI**
it is ignored on local developer machines (where Docker Hub / GHCR is used directly).
```java
@Bean
PostgresContainer postgres() {
return PostgresContainer.builder("16")
.dbName("my_app")
.mirror("123456789.dkr.ecr.ap-southeast-2.amazonaws.com/mirrored")
.build()
.start();
}
```
Alternatively, set the mirror globally via a system property or
`ebean.test.containers.mirror` in a properties file, avoiding code changes per project.
### Read-only datasource (for tests using read-replica simulation)
Call `.autoReadOnlyDataSource(true)` on the `DatabaseBuilder` to automatically
create a second read-only datasource pointing at the same container:
```java
@Bean
Database database(PostgresContainer container) {
return container.ebean()
.builder()
.autoReadOnlyDataSource(true) // test read-only queries against same container
.build();
}
```
### Dump metrics on shutdown
Useful for performance analysis during test runs:
```java
@Bean
Database database(PostgresContainer container) {
return container.ebean()
.builder()
.dumpMetricsOnShutdown(true)
.dumpMetricsOptions("loc,sql,hash")
.build();
}
```
### PostGIS: LW mode (HexWKB)
For PostGIS with DriverWrapperLW (HexWKB binary geometry encoding), set `.useLW(true)`.
This switches the JDBC URL prefix to `jdbc:postgresql_lwgis://` and requires the
`net.postgis:postgis-jdbc` dependency on the test classpath:
```xml
<!-- add to pom.xml test dependencies when using useLW(true) -->
<dependency>
<groupId>net.postgis</groupId>
<artifactId>postgis-jdbc</artifactId>
<version>2024.1.0</version>
<scope>test</scope>
</dependency>
```
```java
@Bean
PostgisContainer postgres() {
return PostgisContainer.builder("16")
.dbName("my_app")
.useLW(true) // use HexWKB + DriverWrapperLW
.build()
.start();
}
```
> **Note**: LW mode is not required for most PostGIS use cases. Only enable it if
> your entities use binary geometry types (e.g., `net.postgis.jdbc.geometry.Geometry`)
> that require the `DriverWrapperLW` driver.
---
## Keeping the container running (local development)
By default, `ebean-test` stops the Docker container when tests finish. To keep it
running between test runs (much faster for local development), create a marker file:
```bash
mkdir -p ~/.ebean && touch ~/.ebean/ignore-docker-shutdown
```
On CI servers, omit this file so containers are cleaned up after each build.
@@ -1,206 +0,0 @@
# Guide: Using Lombok with Ebean Entity Beans
## Purpose
This guide explains which Lombok annotations are safe and recommended for Ebean
entity beans, which ones to avoid, and why. It is written as prescriptive instructions
for AI agents and developers.
---
## The Core Rule
> **Do NOT use `@Data` on Ebean entity beans.**
Use `@Getter` + `@Setter` instead, with the optional `@Accessors(chain = true)` for
a fluent setter style.
---
## Why `@Data` is Incompatible with Ebean
`@Data` is a convenience annotation that is equivalent to applying `@Getter`,
`@Setter`, `@RequiredArgsConstructor`, `@ToString`, and `@EqualsAndHashCode` together.
Three of those are problematic for Ebean entity beans:
### 1. `@EqualsAndHashCode` (included in `@Data`) — breaks entity identity
`@Data` generates `hashCode()` and `equals()` based on all non-static, non-transient
fields. Ebean entity beans have identity semantics — two references to the same database
row should be considered equal based on their `@Id` value, not field-by-field comparison.
Problems caused:
- Inconsistent `hashCode` before and after persist (the `@Id` field is `0` on a new
entity, then changes after insert — violating the `hashCode` contract for collections)
- Entities placed in a `Set` or `HashMap` before saving will be unfindable after saving
- Ebean's internal identity map and dirty checking can be confused
### 2. `@ToString` (included in `@Data`) — triggers unexpected lazy loading
`@Data` generates a `toString()` that accesses **all** fields, including
`@OneToMany` and `@ManyToOne` associations. Accessing an unloaded lazy association
outside of a transaction triggers a `LazyInitializationException` or fires an unexpected
SQL query, which can:
- Cause subtle bugs in logging statements
- Trigger N+1 queries in test output or debug logging
- Fail with an exception if no active transaction exists
### 3. `@RequiredArgsConstructor` (included in `@Data`) — unnecessary for Ebean
Ebean does not require a default constructor — it can construct entity instances without
one. `@RequiredArgsConstructor` therefore adds nothing useful to entity beans.
---
## Recommended Annotation Set
Use exactly these three Lombok annotations on every Ebean entity bean:
```java
@Entity
@Getter
@Setter
@Accessors(chain = true)
@Table(name = "my_table")
public class MyEntity {
// ...
}
```
| Annotation | Purpose |
|---|---|
| `@Getter` | Generates `getFoo()` / `isFoo()` accessor methods |
| `@Setter` | Generates `setFoo(value)` mutator methods; Ebean enhancement intercepts these for dirty tracking |
| `@Accessors(chain = true)` | Makes setters return `this`, enabling fluent/builder-style property setting |
---
## `@Accessors(chain = true)` — Fluent Setter Style
With `chain = true`, setters return `this` instead of `void`, allowing method chaining:
```java
// without chain = true (void setters)
CMachine machine = new CMachine();
machine.setMake("Toyota");
machine.setModel("Hilux");
machine.setStatus("active");
// with @Accessors(chain = true)
CMachine machine = new CMachine()
.setMake("Toyota")
.setModel("Hilux")
.setStatus("active");
```
This is particularly useful when building test data:
```java
CMachine machine = new CMachine()
.setGid(UUID.randomUUID())
.setMachineType("HV")
.setStatus("active")
.setMake("Komatsu")
.setModel("PC200");
database.save(machine);
```
Ebean's bytecode enhancement is fully compatible with chained setters — the
enhancement intercepts each `setFoo()` call to record which fields have been modified
(dirty checking), regardless of whether the setter returns `void` or `this`.
---
## `@Accessors(fluent = true)` — also compatible
`@Accessors(fluent = true)` removes the `get`/`set`/`is` prefix, generating `name()`
(getter) and `name(value)` (setter) instead of `getName()` and `setName(value)`.
Ebean does **not** require JavaBeans naming conventions — it can work with any accessor
method style, including fluent accessors with no prefix. `@Accessors(fluent = true)` is
therefore compatible with Ebean.
`@Accessors(chain = true)` is the more common choice in practice (it keeps the familiar
`get`/`set` prefix while adding method chaining), but `fluent = true` is a valid
alternative if that style is preferred consistently across the codebase.
---
## Full Entity Bean Example
```java
package com.example.repository.data;
import io.ebean.annotation.WhenCreated;
import io.ebean.annotation.WhenModified;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.time.Instant;
import java.util.List;
import java.util.UUID;
@Entity
@Getter
@Setter
@Accessors(chain = true)
@Table(name = "machine")
public class CMachine {
@Id
private long id;
@Version
private int version;
@Column(nullable = false, unique = true)
private UUID gid;
@Column(nullable = false, length = 10)
private String machineType;
@Column(length = 200)
private String make;
@Column(length = 200)
private String model;
@WhenCreated
private Instant created;
@WhenModified
private Instant lastModified;
}
```
---
## Summary: Lombok Annotations and Ebean Compatibility
| Lombok Annotation | Compatible? | Notes |
|---|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `@Getter` | ✅ Safe | Use on every entity bean |
| `@Setter` | ✅ Safe | Use on every entity bean; enhancement intercepts these |
| `@Accessors(chain = true)` | ✅ Safe | Recommended for fluent construction style |
| `@ToString` | ❌ Avoid | Ebean does a better job and handles recursion |
| `@EqualsAndHashCode` | ❌ Avoid | Breaks entity identity and `@Id`-based equality |
| `@Data` | ❌ Avoid | Includes `@EqualsAndHashCode` and `@ToString` — both problematic |
| `@Value` | ❌ Avoid | Makes fields final — incompatible with Ebean's field-level bytecode enhancement |
| `@Accessors(fluent = true)` | ✅ Safe | Removes `get`/`set` prefix — Ebean does not require JavaBeans naming conventions and works with any accessor style |
| `@Builder` | ⚠️ Careful | Usable on non-entity helper/factory classes; on entity beans it requires a no-arg constructor alongside it and offers no advantage over `@Accessors(chain = true)` |
---
## Relationship with Ebean Bytecode Enhancement
Ebean's bytecode enhancement (applied by `ebean-maven-plugin` at build time) modifies
the `setXxx()` methods of entity beans to:
1. Mark the field as dirty (changed) so only modified fields are included in UPDATE statements
2. Support lazy loading of associations when a getter is called on an unloaded field
For this to work correctly, Ebean needs:
- Accessor methods for each persistent field (any naming style is fine — `getFoo()`, `foo()`, or no accessors at all; Ebean can also access fields directly)
- No override of `hashCode()` / `equals()` that would interfere with the identity map — which means **no `@Data` or `@EqualsAndHashCode`**
-110
View File
@@ -1,110 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
</parent>
<name>ebean api</name>
<description>ebean api</description>
<artifactId>ebean-api</artifactId>
<dependencies>
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-applog</artifactId>
<version>1.0</version>
</dependency>
<!-- exclude avaje-applog-slf4j to direct logging to something else -->
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-applog-slf4j</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.jspecify</groupId>
<artifactId>jspecify</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-config</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>jakarta-persistence-api</artifactId>
<version>${ebean-persistence-api.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-annotation</artifactId>
<version>${ebean-annotation.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-types</artifactId>
<version>${ebean-types.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource-api</artifactId>
<version>${ebean-datasource.version}</version>
</dependency>
<!-- Support MdcBackgroundExecutorWrapper -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
<optional>true</optional>
</dependency>
<!-- Jackson core used internally by Ebean -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
<optional>true</optional>
</dependency>
<!-- provided scope for JsonNode support -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<optional>true</optional>
</dependency>
</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>
@@ -1,91 +0,0 @@
package io.ebean;
import org.jspecify.annotations.NullMarked;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
* Background executor service for executing of tasks asynchronously.
* <p>
* This service can be used to execute tasks in the background.
* <p>
* This service is managed by Ebean and will perform a clean shutdown
* waiting for background tasks to complete with a default 30 second
* timeout. Shutdown occurs prior to DataSource shutdown.
* <p>
* This also propagates MDC context from the current thread to the
* background task if defined.
*/
@NullMarked
public interface BackgroundExecutor {
/**
* Execute a callable task in the background returning the Future.
*/
<T> Future<T> submit(Callable<T> task);
/**
* Execute a runnable task in the background returning the Future.
*/
Future<?> submit(Runnable task);
/**
* Execute a task in the background. Effectively the same as
* {@link BackgroundExecutor#submit(Runnable)} but returns void.
*/
void execute(Runnable task);
/**
* Execute a task periodically with a given delay.
*
* @param task the task to execute
* @param initialDelay the time to delay first execution
* @param delay the delay between the termination of one
* execution and the commencement of the next
* @param unit the time unit of the initialDelay and delay parameters
* @return a ScheduledFuture representing pending completion of
* the series of repeated tasks. The future's {@link
* Future#get() get()} method will never return normally,
* and will throw an exception upon task cancellation or
* abnormal termination of a task execution.
*/
ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long initialDelay, long delay, TimeUnit unit);
/**
* Execute a task periodically with a given period.
*
* <p>If any execution of this task takes longer than its period, then
* subsequent executions may start late, but will not concurrently
* execute.
*
* @param task the task to execute
* @param initialDelay the time to delay first execution
* @param period the period between successive executions
* @param unit the time unit of the initialDelay and period parameters
* @return a ScheduledFuture representing pending completion of
* the series of repeated tasks. The future's {@link
* Future#get() get()} method will never return normally,
* and will throw an exception upon task cancellation or
* abnormal termination of a task execution.
*/
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit unit);
/**
* Schedules a Runnable for one-shot action that becomes enabled after the given delay.
*
* @return a ScheduledFuture representing pending completion of the task and
* whose get() method will return null upon completion
*/
ScheduledFuture<?> schedule(Runnable task, long delay, TimeUnit unit);
/**
* Schedules a Callable for one-shot action that becomes enabled after the given delay.
*
* @return a ScheduledFuture that can be used to extract result or cancel
*/
<V> ScheduledFuture<V> schedule(Callable<V> task, long delay, TimeUnit unit);
}
@@ -1,25 +0,0 @@
package io.ebean;
/**
* Unsupported access of a property on an entity bean.
* <p>
* Attempted a lazy load operation on a bean that has disabled lazy loading
* or attempt to mutate an unmodifiable bean.
*/
public class BeanAccessException extends UnsupportedOperationException {
private static final long serialVersionUID = 1;
/**
* Create with no message.
*/
public BeanAccessException() {
super();
}
/**
* Create with message.
*/
public BeanAccessException(String message) {
super(message);
}
}
@@ -1,19 +0,0 @@
package io.ebean;
/**
* Defines a cancelable query.
* <p>
* Typically holds a representation of the PreparedStatement to perform the
* actual cancel.
* </p>
*/
public interface CancelableQuery {
/**
* Cancel the query.
* <p>
* For JDBC this translates to calling cancel on the PreparedStatement.
* </p>
*/
void cancel();
}
@@ -1,49 +0,0 @@
package io.ebean;
import io.ebean.service.SpiInTuples;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Default implementation of SpiInTuples.
*/
final class DInTuples implements SpiInTuples {
private final String[] properties;
private final int propertyCount;
private final List<Object[]> entries = new ArrayList<>();
DInTuples(String[] properties) {
this.properties = properties;
this.propertyCount = properties.length;
}
@Override
public InTuples add(Object... values) {
if (values.length != propertyCount) {
throw new IllegalArgumentException("Require " + propertyCount + " values but got " + values.length);
}
entries.add(values);
return this;
}
/**
* Return the first property name.
*/
@Override
public String[] properties() {
return properties;
}
/**
* Return all the value pairs.
*/
@Override
public List<Object[]> entries() {
return Collections.unmodifiableList(entries);
}
}
@@ -1,104 +0,0 @@
package io.ebean;
final class DInsertOptionsBuilder implements InsertOptions.Builder {
private Boolean getGeneratedKeys;
private boolean onConflictUpdate;
private boolean onConflictNothing;
private String constraint;
private String uniqueColumns;
private String updateSet;
@Override
public InsertOptions.Builder onConflictNothing() {
this.onConflictNothing = true;
return this;
}
@Override
public InsertOptions.Builder onConflictUpdate() {
this.onConflictUpdate = true;
return this;
}
@Override
public InsertOptions.Builder constraint(String constraint) {
this.constraint = constraint;
return this;
}
@Override
public InsertOptions.Builder uniqueColumns(String uniqueColumns) {
this.uniqueColumns = uniqueColumns;
return this;
}
@Override
public InsertOptions.Builder updateSet(String updateSet) {
this.updateSet = updateSet;
return this;
}
@Override
public InsertOptions.Builder getGeneratedKeys(boolean getGeneratedKeys) {
this.getGeneratedKeys = getGeneratedKeys;
return this;
}
@Override
public InsertOptions build() {
return new Options(constraint, uniqueColumns, updateSet, onConflictUpdate, onConflictNothing, getGeneratedKeys);
}
static final class Options implements InsertOptions {
private static final String UPDATE = "U";
private static final String NOTHING = "N";
private static final String NORMAL = "_";
private final String key;
private final Boolean getGeneratedKeys;
private final String constraint;
private final String uniqueColumns;
private final String updateSet;
Options(String constraint, String uniqueColumns, String updateSet, boolean onConflictUpdate, boolean onConflictNothing, Boolean getGeneratedKeys) {
this.constraint = constraint;
this.uniqueColumns = uniqueColumns;
this.updateSet = updateSet;
this.getGeneratedKeys = getGeneratedKeys;
this.key = (onConflictUpdate ? UPDATE : onConflictNothing ? NOTHING : NORMAL)
+ '+' + plus(constraint)
+ '+' + plus(uniqueColumns)
+ '+' + plus(updateSet);
}
private String plus(String val) {
return val == null ? "" : val;
}
@Override
public String key() {
return key;
}
@Override
public String constraint() {
return constraint;
}
@Override
public String uniqueColumns() {
return uniqueColumns;
}
@Override
public String updateSet() {
return updateSet;
}
@Override
public Boolean getGetGeneratedKeys() {
return getGeneratedKeys;
}
}
}
@@ -1,50 +0,0 @@
package io.ebean;
final class DPaging implements Paging {
static final Paging NONE = new DPaging(0, 0, null);
static Paging build(int pgIndex, int pgSize, OrderBy<?> orderBy) {
return new DPaging(pgIndex, pgSize, orderBy);
}
static Paging build(int pgIndex, int pgSize) {
return new DPaging(pgIndex, pgSize, null);
}
private final int pageNumber;
private final int pageSize;
private final OrderBy<?> orderBy;
DPaging(int pageNumber, int pageSize, OrderBy<?> orderBy) {
this.pageNumber = pageNumber;
this.pageSize = pageSize;
this.orderBy = orderBy;
}
@Override
public int pageIndex() {
return pageNumber;
}
@Override
public int pageSize() {
return pageSize;
}
@Override
public OrderBy<?> orderBy() {
return orderBy;
}
@Override
public Paging withPage(int pageNumber) {
return new DPaging(pageNumber, pageSize, orderBy);
}
@Override
public Paging withOrderBy(String orderByClause) {
return new DPaging(pageNumber, pageSize, OrderBy.of(orderByClause));
}
}
@@ -1,24 +0,0 @@
package io.ebean;
import jakarta.persistence.PersistenceException;
/**
* Thrown when a foreign key constraint is enforced or a field is too large.
*/
public class DataIntegrityException extends PersistenceException {
private static final long serialVersionUID = -6740171949170180970L;
/**
* Create with a message and cause.
*/
public DataIntegrityException(String message, Throwable cause) {
super(message, cause);
}
/**
* Create with message only.
*/
public DataIntegrityException(String message) {
super(message);
}
}
File diff suppressed because it is too large Load Diff
@@ -1,164 +0,0 @@
package io.ebean;
import io.ebean.config.ContainerConfig;
import io.ebean.service.SpiContainer;
import io.ebean.service.SpiContainerFactory;
import jakarta.persistence.PersistenceException;
import java.util.concurrent.locks.ReentrantLock;
/**
* Creates Database instances.
* <p>
* This uses either DatabaseConfig or properties in the application.properties file to
* configure and create a Database instance.
* <p>
* The Database instance can either be registered with the DB singleton or
* not. The DB singleton effectively holds a map of Database by a name.
* If the Database is registered with the DB singleton you can retrieve it
* later via {@link DB#byName(String)}.
* <p>
* One Database can be nominated as the 'default/primary' Database. Many
* methods on the DB singleton such as {@link DB#find(Class)} are just a
* convenient way of using the 'default/primary' Database.
*/
public final class DatabaseFactory {
private static final ReentrantLock lock = new ReentrantLock();
private static SpiContainer container;
private static String defaultServerName;
static {
EbeanVersion.getVersion();
}
/**
* Initialise the container with clustering configuration.
* <p>
* Call this prior to creating any Database instances or alternatively set the
* ContainerConfig on the DatabaseConfig when creating the first Database instance.
*/
public static void initialiseContainer(ContainerConfig containerConfig) {
lock.lock();
try {
container(containerConfig);
} finally {
lock.unlock();
}
}
/**
* Create using properties to configure the database.
*/
public static Database create(String name) {
lock.lock();
try {
return container(null).createServer(name);
} finally {
lock.unlock();
}
}
/**
* Create using the DatabaseConfig object to configure the database.
*
* <pre>{@code
*
* DatabaseConfig config = new DatabaseConfig();
* config.setName("db");
* config.loadProperties();
*
* Database database = DatabaseFactory.create(config);
*
* }</pre>
*/
public static Database create(DatabaseBuilder builder) {
lock.lock();
try {
var config = builder.settings();
if (config.getName() == null) {
throw new PersistenceException("The name is null (it is required)");
}
Database server = createInternal(config);
if (config.isRegister()) {
if (config.isDefaultServer()) {
if (defaultServerName != null && !defaultServerName.equals(config.getName())) {
throw new IllegalStateException("Registering [" + config.getName() + "] as the default server but [" + defaultServerName + "] is already registered as the default");
}
defaultServerName = config.getName();
}
DbPrimary.setSkip(true);
DbContext.getInstance().register(server, config.isDefaultServer());
}
return server;
} finally {
lock.unlock();
}
}
/**
* Create using the DatabaseConfig additionally specifying a classLoader to use as the context class loader.
*/
public static Database createWithContextClassLoader(DatabaseBuilder config, ClassLoader classLoader) {
lock.lock();
try {
ClassLoader currentContextLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
try {
return DatabaseFactory.create(config);
} finally {
// set the currentContextLoader back
Thread.currentThread().setContextClassLoader(currentContextLoader);
}
} finally {
lock.unlock();
}
}
/**
* Shutdown gracefully all Database instances cleaning up any resources as required.
* <p>
* This is typically invoked via JVM shutdown hook and not explicitly called.
*/
public static void shutdown() {
lock.lock();
try {
container.shutdown();
} finally {
lock.unlock();
}
}
private static Database createInternal(DatabaseBuilder.Settings config) {
return container(config.getContainerConfig()).createServer(config);
}
/**
* Return the SpiContainer initialising it if necessary.
*
* @param containerConfig the configuration controlling clustering communication
*/
private static SpiContainer container(ContainerConfig containerConfig) {
// thread safe in that all calling methods hold lock
if (container != null) {
return container;
}
if (containerConfig == null) {
// effectively load configuration from ebean.properties
containerConfig = new ContainerConfig();
}
container = createContainer(containerConfig);
return container;
}
/**
* Create the container instance using the configuration.
*/
private static SpiContainer createContainer(ContainerConfig containerConfig) {
SpiContainerFactory factory = XBootstrapService.containerFactory();
if (factory == null) {
throw new IllegalStateException("Service loader didn't find a SpiContainerFactory?");
}
return factory.create(containerConfig);
}
}
@@ -1,135 +0,0 @@
package io.ebean;
import io.ebean.config.BeanNotEnhancedException;
import io.ebean.datasource.DataSourceConfigurationException;
import jakarta.persistence.PersistenceException;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import static java.lang.System.Logger.Level.ERROR;
/**
* Holds Database instances.
*/
final class DbContext {
private static final System.Logger log = EbeanVersion.log;
static {
EbeanVersion.getVersion();
}
private static final DbContext INSTANCE = new DbContext();
private final ConcurrentHashMap<String, Database> concMap = new ConcurrentHashMap<>();
private final HashMap<String, Database> syncMap = new HashMap<>();
private final ReentrantLock lock = new ReentrantLock();
private Database defaultDatabase;
private DbContext() {
try {
if (!DbPrimary.isSkip()) {
// look to see if there is a default server defined
String defaultName = DbPrimary.getDefaultServerName();
if (defaultName != null && !defaultName.trim().isEmpty()) {
defaultDatabase = getWithCreate(defaultName.trim());
}
}
} catch (BeanNotEnhancedException e) {
String msg = "Bean is not enhanced? See https://ebean.io/docs/trouble-shooting#not-enhanced";
log.log(ERROR, msg, e);
throw e;
} catch (DataSourceConfigurationException e) {
String msg = "Configuration error creating DataSource for the default Database." +
" This typically means a missing application-test.yaml or missing ebean-test dependency." +
" See https://ebean.io/docs/trouble-shooting#datasource";
log.log(ERROR, msg, e);
throw new DataSourceConfigurationException(msg, e);
} catch (Throwable e) {
log.log(ERROR, "Error trying to create the default Database", e);
throw new RuntimeException(e);
}
}
/**
* Return the shared singleton instance.
*/
static DbContext getInstance() {
return INSTANCE;
}
/**
* Return the default database.
*/
Database getDefault() {
if (defaultDatabase == null) {
String msg = "The default Database has not been defined?"
+ " This is normally set via the ebean.datasource.default property."
+ " Otherwise it should be registered programmatically via registerServer()";
throw new PersistenceException(msg);
}
return defaultDatabase;
}
/**
* Return the database by name.
*/
Database get(String name) {
if (name == null || name.isEmpty()) {
return defaultDatabase;
}
Database server = concMap.get(name);
if (server != null) {
return server;
}
return getWithCreate(name);
}
/**
* Read, create and put of Databases.
*/
private Database getWithCreate(String name) {
lock.lock();
try {
Database server = syncMap.get(name);
if (server == null) {
// register when creating server this way
server = DatabaseFactory.create(name);
register(server, false);
}
return server;
} finally {
lock.unlock();
}
}
/**
* Register a server so we can get it by its name.
*/
void register(Database server, boolean isDefault) {
registerWithName(server.name(), server, isDefault);
}
private void registerWithName(String name, Database server, boolean isDefault) {
lock.lock();
try {
concMap.put(name, server);
syncMap.put(name, server);
if (isDefault) {
defaultDatabase = server;
}
} finally {
lock.unlock();
}
}
Database mock(String name, Database server, boolean defaultServer) {
Database originalPrimaryServer = this.defaultDatabase;
registerWithName(name, server, defaultServer);
return originalPrimaryServer;
}
}
@@ -1,83 +0,0 @@
package io.ebean;
import io.avaje.config.Config;
import java.util.Properties;
import java.util.concurrent.locks.ReentrantLock;
/**
* Provides singleton state for the default database.
* <p/>
* Intended for internal use as part of bootup, construction, registration of the default database.
*/
final class DbPrimary {
private static final ReentrantLock lock = new ReentrantLock();
private static String defaultServerName;
private static boolean skip;
/**
* Set whether to skip automatically creating the primary database.
*/
static void setSkip(boolean skip) {
lock.lock();
try {
DbPrimary.skip = skip;
} finally {
lock.unlock();
}
}
/**
* Return true to skip automatically creating the primary database.
*/
static boolean isSkip() {
lock.lock();
try {
return skip;
} finally {
lock.unlock();
}
}
/**
* Return the default database name.
*/
static String getDefaultServerName() {
lock.lock();
try {
if (defaultServerName == null) {
defaultServerName = determineDefaultServerName();
}
return defaultServerName;
} finally {
lock.unlock();
}
}
/**
* Determine and return the default server name checking system environment variables and then global properties.
*/
private static String determineDefaultServerName() {
String defaultServerName = System.getenv("EBEAN_DB");
defaultServerName = System.getProperty("db", defaultServerName);
defaultServerName = System.getProperty("ebean_db", defaultServerName);
if (isEmpty(defaultServerName)) {
defaultServerName = Config.getOptional("datasource.default").orElse(null);
if (isEmpty(defaultServerName)) {
defaultServerName = Config.getOptional("ebean.default.datasource").orElse(null);
}
}
if (defaultServerName == null) {
defaultServerName = "db";
}
return defaultServerName;
}
/**
* Return true if the string is null or empty.
*/
private static boolean isEmpty(String value) {
return value == null || value.trim().isEmpty();
}
}
@@ -1,249 +0,0 @@
package io.ebean;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import javax.sql.DataSource;
import java.sql.Connection;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* Query for performing native SQL queries that return DTO Bean's.
* <p>
* These beans are just normal classes. They must have public constructors
* and setters.
* <p>
* Constructors with arguments are used if the number of constructor arguments
* matches the number of columns in the resultSet.
* </p>
* <p>
* If the number of columns in the resultSet is greater than the largest constructor
* then the largest constructor is used for the first columns and remaining columns
* are mapped by setter methods.
* </p>
*
* <pre>{@code
*
* // CustomerDto is just a 'bean like' class
* // with public constructor(s) and public setter methods
*
* String sql = "select id, name from customer where name like :name and status_code = :status";
*
* List<CustomerDto> beans =
* DB.findDto(CustomerDto.class, sql)
* .setParameter("name", "Acme%")
* .setParameter("status", "ACTIVE")
* .findList();
*
* }</pre>
*/
@NullMarked
public interface DtoQuery<T> extends CancelableQuery {
/**
* Execute the query returning a list.
*/
List<T> findList();
/**
* Execute the query iterating a row at a time.
* <p>
* Note that the QueryIterator holds resources related to the underlying
* resultSet and potentially connection and MUST be closed. We should use
* QueryIterator in a <em>try with resource block</em>.
*/
QueryIterator<T> findIterate();
/**
* Execute the query returning a Stream.
* <p>
* Note that the Stream holds resources related to the underlying
* resultSet and potentially connection and MUST be closed. We should use
* the Stream in a <em>try with resource block</em>.
*/
Stream<T> findStream();
/**
* Execute the query iterating a row at a time.
* <p>
* This streaming type query is useful for large query execution as only 1 row needs to be held in memory.
* </p>
*/
void findEach(Consumer<T> consumer);
/**
* Execute the query iterating the results and batching them for the consumer.
* <p>
* This runs like findEach streaming results from the database but just collects the results
* into batches to pass to the consumer.
*
* @param batch The number of dto beans to collect before given them to the consumer
* @param consumer The consumer to process the batch of DTO beans
*/
void findEach(int batch, Consumer<List<T>> consumer);
/**
* Execute the query iterating a row at a time with the ability to stop consuming part way through.
* <p>
* Returning false after processing a row stops the iteration through the query results.
* </p>
* <p>
* This streaming type query is useful for large query execution as only 1 row needs to be held in memory.
* </p>
*/
void findEachWhile(Predicate<T> consumer);
/**
* Execute the query returning a single bean.
*/
@Nullable
T findOne();
/**
* Execute the query returning an optional bean.
*/
Optional<T> findOneOrEmpty();
/**
* Bind all the parameters using index positions.
* <p>
* Binds each parameter moving the index position each time.
* <p>
* A convenience for multiple calls to {@link #setParameter(Object)}
*/
DtoQuery<T> setParameters(Object... value);
/**
* Bind the next parameter using index position.
* <p>
* Bind the parameter using index position starting at 1 and incrementing.
* <p>
*/
DtoQuery<T> setParameter(Object value);
/**
* Bind the named parameter.
*/
DtoQuery<T> setParameter(String name, Object value);
/**
* Bind the named parameter to SQL NULL.
*/
DtoQuery<T> setNullParameter(String name, int jdbcType);
/**
* Bind the named multi-value array parameter which we would use with Postgres ANY.
* <p>
* For Postgres this binds an ARRAY rather than expands into multiple bind values.
* <pre>{@code
*
* String sql = "select id, name from o_customer where id = any(:idList)";
*
* var ids = List.of(1, 2, 3);
*
* List<CustomerDto> list2 = DB.findDto(CustomerDto.class, sql)
* .setArrayParameter("idList", ids)
* .findList();
*
* }</pre>
*/
DtoQuery<T> setArrayParameter(String name, Collection<?> values);
/**
* Bind the parameter by its index position (1 based like JDBC).
*/
DtoQuery<T> setParameter(int position, Object value);
/**
* Set a positioned parameter to SQL NULL.
*/
DtoQuery<T> setNullParameter(int position, int jdbcType);
/**
* Set the index of the first row of the results to return.
*/
DtoQuery<T> setFirstRow(int firstRow);
/**
* Set the maximum number of query results to return.
*/
DtoQuery<T> setMaxRows(int maxRows);
/**
* When resultSet columns are not able to be mapped to a bean property then instead of
* throwing effectively skip reading that column.
*/
DtoQuery<T> setRelaxedMode();
/**
* Set a label on the query to make it easier to identify queries related to query execution statistics.
*
* @param label A label that is unique to the DTO bean type.
*/
DtoQuery<T> setLabel(String label);
/**
* Set the profile location of this query. This is used to relate query execution metrics
* back to a location like a specific line of code.
*/
DtoQuery<T> setProfileLocation(ProfileLocation profileLocation);
/**
* Set a timeout on this query.
* <p>
* This will typically result in a call to setQueryTimeout() on a
* preparedStatement. If the timeout occurs an exception will be thrown - this
* will be a SQLException wrapped up in a PersistenceException.
* </p>
*
* @param secs the query timeout limit in seconds. Zero means there is no limit.
*/
DtoQuery<T> setTimeout(int secs);
/**
* A hint which for JDBC translates to the Statement.fetchSize().
* <p>
* Gives the JDBC driver a hint as to the number of rows that should be
* fetched from the database when more rows are needed for ResultSet.
* </p>
*/
DtoQuery<T> setBufferFetchSizeHint(int bufferFetchSizeHint);
/**
* Use the explicit transaction to execute the query.
*/
DtoQuery<T> usingTransaction(Transaction transaction);
/**
* Execute the query using the given connection.
*/
DtoQuery<T> usingConnection(Connection connection);
/**
* Ensure that the master DataSource is used if there is a read only data source
* being used (that is using a read replica database potentially with replication lag).
* <p>
* When the database is configured with a read-only DataSource via
* say {@link io.ebean.DatabaseBuilder#readOnlyDataSource(DataSource)} then
* by default when a query is run without an active transaction, it uses the read-only data
* source. We use {@code usingMaster()} to instead ensure that the query is executed
* against the master data source.
*/
default DtoQuery<T> usingMaster() {
return usingMaster(true);
}
/**
* Ensure the master DataSource is used when useMaster is true. Otherwise, the read only
* data source can be used if defined.
*
* @see #usingMaster()
*/
DtoQuery<T> usingMaster(boolean useMaster);
}
@@ -1,37 +0,0 @@
package io.ebean;
/**
* Thrown when a duplicate is attempted on a unique constraint.
* <p>
* In terms of catching this exception with the view of continuing processing
* using the same transaction look to use {@link Transaction#rollbackAndContinue()}.
*
* <pre>{@code
*
* try (Transaction txn = database.beginTransaction()) {
*
* try {
* ...
* database.save(bean);
* database.flush();
* } catch (DuplicateKeyException e) {
* // carry on processing using the transaction
* txn.rollbackAndContinue();
* ...
* }
*
* txn.commit();
* }
*
* }</pre>
*/
public class DuplicateKeyException extends DataIntegrityException {
private static final long serialVersionUID = -4771932723285724817L;
/**
* Create with a message and cause.
*/
public DuplicateKeyException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -1,103 +0,0 @@
package io.ebean;
import io.avaje.applog.AppLog;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.Properties;
import static java.lang.System.Logger.Level.*;
/**
* Class to determine the ebean version.
*
* @author Roland Praml, FOCONIS AG
*/
public final class EbeanVersion {
public static final System.Logger log = AppLog.getLogger("io.ebean");
/**
* Maintain the minimum ebean-agent version manually based on required ebean-agent bug fixes.
*/
private static final int MIN_AGENT_MAJOR_VERSION = 12;
private static final int MIN_AGENT_MINOR_VERSION = 12;
private static String version = "unknown";
static {
readVersion();
checkAgentVersion();
}
private static void readVersion() {
try {
try (InputStream in = ClassLoader.getSystemResourceAsStream("META-INF/ebean-maven-version.txt")) {
if (in != null) {
try (LineNumberReader reader = new LineNumberReader(new InputStreamReader(in))) {
version = reader.readLine();
log.log(INFO, "ebean version: {0}", version);
}
}
}
} catch (IOException e) {
log.log(WARNING, "Could not determine ebean version: {0}", e.getMessage());
}
}
private static void checkAgentVersion() {
try {
try (InputStream in = ClassLoader.getSystemResourceAsStream("META-INF/maven/io.ebean/ebean-agent/pom.properties")) {
// often we only have ebean-agent during development (with build time enhancement), null is expected
if (in != null) {
String agentVersion = readVersion(in);
if (agentVersion != null) {
if (checkMinAgentVersion(agentVersion)) {
log.log(ERROR, "Expected minimum ebean-agent version {0}.{1}.0 but we have {2}, please update the ebean-agent", MIN_AGENT_MAJOR_VERSION, MIN_AGENT_MINOR_VERSION, agentVersion);
}
}
}
}
} catch (IOException e) {
log.log(WARNING, "Could not check minimum ebean-agent version {0}.{1}.0 required due to - {2}", MIN_AGENT_MAJOR_VERSION, MIN_AGENT_MINOR_VERSION, e.getMessage());
}
}
/**
* Return true if ebean-agent is NOT at our minimum version.
*/
static boolean checkMinAgentVersion(String agentVersion) {
String[] versionSegments = agentVersion.split("\\.");
if (versionSegments.length != 3) {
return true;
} else {
int major = Integer.parseInt(versionSegments[0]);
int minor = Integer.parseInt(versionSegments[1]);
if (major < MIN_AGENT_MAJOR_VERSION) {
return true;
} else {
return major == MIN_AGENT_MAJOR_VERSION && minor < MIN_AGENT_MINOR_VERSION;
}
}
}
private static String readVersion(InputStream in) throws IOException {
Properties prop = new Properties();
prop.load(in);
in.close();
return prop.getProperty("version");
}
private EbeanVersion() {
// hide
}
/**
* Returns the ebean version (read from META-INF/ebean-maven-version.txt)
*/
public static String getVersion() {
return version;
}
}
@@ -1,704 +0,0 @@
package io.ebean;
import io.ebean.search.*;
import java.util.Collection;
import java.util.Map;
/**
* Expression factory for creating standard expressions.
* <p>
* Creates standard common expressions for using in a Query Where or Having
* clause.
* </p>
* <p>
* You will often not use this class directly but instead just add expressions
* via the methods on ExpressionList such as
* {@link ExpressionList#gt(String, Object)}.
* </p>
* <p>
* The ExpressionList is returned from {@link Query#where()}.
* </p>
* <pre>{@code
* // Example: fetch orders where status equals new or orderDate > lastWeek.
*
* Expression newOrLastWeek =
* Expr.or(Expr.eq("status", Order.Status.NEW),
* Expr.gt("orderDate", lastWeek));
*
* List<Order> list = DB.find(Order.class)
* .where().add(newOrLastWeek)
* .findList();
* ...
* }</pre>
*
* @see Query#where()
*/
public interface ExpressionFactory {
/**
* Return a new ExpressionList.
*/
<T> ExpressionList<T> expressionList();
/**
* Path exists - for the given path in a JSON document.
*/
Expression jsonExists(String propertyName, String path);
/**
* Path does not exist - for the given path in a JSON document.
*/
Expression jsonNotExists(String propertyName, String path);
/**
* Equal to - for the given path in a JSON document.
*/
Expression jsonEqualTo(String propertyName, String path, Object val);
/**
* Not Equal to - for the given path in a JSON document.
*/
Expression jsonNotEqualTo(String propertyName, String path, Object val);
/**
* Greater than - for the given path in a JSON document.
*/
Expression jsonGreaterThan(String propertyName, String path, Object val);
/**
* Greater than or equal to - for the given path in a JSON document.
*/
Expression jsonGreaterOrEqual(String propertyName, String path, Object val);
/**
* Less than - for the given path in a JSON document.
*/
Expression jsonLessThan(String propertyName, String path, Object val);
/**
* Less than or equal to - for the given path in a JSON document.
*/
Expression jsonLessOrEqualTo(String propertyName, String path, Object val);
/**
* Between - for the given path in a JSON document.
*/
Expression jsonBetween(String propertyName, String path, Object lowerValue, Object upperValue);
/**
* Array contains all the given values.
* <p>
* Array support is effectively limited to Postgres at this time.
* </p>
*/
Expression arrayContains(String propertyName, Object... values);
/**
* Array does not contain the given values.
* <p>
* Array support is effectively limited to Postgres at this time.
* </p>
*/
Expression arrayNotContains(String propertyName, Object... values);
/**
* Array is empty - for the given array property.
* <p>
* Array support is effectively limited to Postgres at this time.
* </p>
*/
Expression arrayIsEmpty(String propertyName);
/**
* Array is not empty - for the given array property.
* <p>
* Array support is effectively limited to Postgres at this time.
* </p>
*/
Expression arrayIsNotEmpty(String propertyName);
/**
* Equal To the result of a sub-query.
*/
Expression eq(String propertyName, Query<?> subQuery);
/**
* Equal To - property equal to the given value.
*/
Expression eq(String propertyName, Object value);
/**
* Equal To or Null - property equal to the given value or null.
*/
Expression eqOrNull(String propertyName, Object value);
/**
* Not Equal To the result of a sub-query.
*/
Expression ne(String propertyName, Query<?> subQuery);
/**
* Not Equal To - property not equal to the given value.
*/
Expression ne(String propertyName, Object value);
/**
* Case Insensitive Equal To - property equal to the given value (typically
* using a lower() function to make it case insensitive).
*/
Expression ieq(String propertyName, String value);
/**
* Case Insensitive Not Equal To - property not equal to the given value (typically
* using a lower() function to make it case insensitive).
*/
Expression ine(String propertyName, String value);
/**
* Case Insensitive Equal To that allows for named parameter use.
*/
Expression ieqObject(String propertyName, Object value);
/**
* Case Insensitive Not Equal To that allows for named parameter use.
*/
Expression ineObject(String propertyName, Object value);
/**
* In Range - {@code property >= value1 and property < value2}.
* <p>
* Unlike Between inRange is "half open" and usually more useful for use with dates or timestamps.
* </p>
*/
Expression inRange(String propertyName, Object value1, Object value2);
/**
* Value in Range between 2 properties.
*
* <pre>{@code
*
* .startDate.inRangeWith(endDate, now)
*
* // which equates to
* startDate <= now and (endDate > now or endDate is null)
*
* }</pre>
*
* <p>
* This is a convenience expression combining a number of simple expressions.
* The most common use of this could be called "effective dating" where 2 date or
* timestamp columns represent the date range in which
*/
Expression inRangeWith(String lowProperty, String highProperty, Object value);
/**
* A Property is in Range between 2 properties.
*
* <pre>{@code
*
* .orderDate.inRangeWith(QOrder.Alias.product.startDate, QOrder.Alias.product.endDate)
*
* // which equates to
* product.startDate <= orderDate and (orderDate < product.endDate or product.endDate is null)
*
* }</pre>
*
* <p>
* This is a convenience expression combining a number of simple expressions.
*/
Expression inRangeWithProperties(String propertyName, String lowProperty, String highProperty);
/**
* Between - property between the two given values.
*/
Expression between(String propertyName, Object value1, Object value2);
/**
* Between - value between two given properties.
*/
Expression betweenProperties(String lowProperty, String highProperty, Object value);
/**
* Greater Than Or Null - property greater than the given value or null.
* <p>
* A convenient expression combining GT and Is Null. Most often useful for range
* expressions where the top range value is nullable.
*/
Expression gtOrNull(String propertyName, Object value);
/**
* Greater than or Equal to OR Null ({@code >= or null })
* <p>
* A convenient expression combining GE and Is Null. Most often useful for range
* expressions where the top range value is nullable.
*/
Expression geOrNull(String propertyName, Object value);
/**
* Greater Than the result of a sub-query.
*/
Expression gt(String propertyName, Query<?> subQuery);
/**
* Greater Than - property greater than the given value.
*/
Expression gt(String propertyName, Object value);
/**
* Greater Than or Equal to the result of a sub-query.
*/
Expression ge(String propertyName, Query<?> subQuery);
/**
* Greater Than or Equal to - property greater than or equal to the given
* value.
*/
Expression ge(String propertyName, Object value);
/**
* Less Than or Null - property less than the given value or null.
* <p>
* A convenient expression combining LT and Is Null. Most often useful for range
* expressions where the bottom range value is nullable.
*/
Expression ltOrNull(String propertyName, Object value);
/**
* Less Than or Equal to OR Null ({@code <= or null })
* <p>
* A convenient expression combining LE and Is Null. Most often useful for range
* expressions where the bottom range value is nullable.
*/
Expression leOrNull(String propertyName, Object value);
/**
* Less Than the result of a sub-query.
*/
Expression lt(String propertyName, Query<?> subQuery);
/**
* Less Than - property less than the given value.
*/
Expression lt(String propertyName, Object value);
/**
* Less Than or Equal to the result of a sub-query.
*/
Expression le(String propertyName, Query<?> subQuery);
/**
* Less Than or Equal to - property less than or equal to the given value.
*/
Expression le(String propertyName, Object value);
/**
* Is Null - property is null.
*/
Expression isNull(String propertyName);
/**
* Is Not Null - property is not null.
*/
Expression isNotNull(String propertyName);
/**
* Case insensitive {@link #exampleLike(Object)}
*/
ExampleExpression iexampleLike(Object example);
/**
* Create the query by Example expression which is case sensitive and using
* LikeType.RAW (you need to add you own wildcards % and _).
*/
ExampleExpression exampleLike(Object example);
/**
* Create the query by Example expression specifying more options.
*/
ExampleExpression exampleLike(Object example, boolean caseInsensitive, LikeType likeType);
/**
* Like with support for named parameters.
*/
Expression like(String propertyName, Object value, boolean caseInsensitive, LikeType likeType);
/**
* Like - property like value where the value contains the SQL wild card
* characters % (percentage) and _ (underscore).
*/
Expression like(String propertyName, String value);
/**
* Case insensitive Like - property like value where the value contains the
* SQL wild card characters % (percentage) and _ (underscore). Typically uses
* a lower() function to make the expression case insensitive.
*/
Expression ilike(String propertyName, String value);
/**
* Starts With - property like value%.
*/
Expression startsWith(String propertyName, String value);
/**
* Case insensitive Starts With - property like value%. Typically uses a
* lower() function to make the expression case insensitive.
*/
Expression istartsWith(String propertyName, String value);
/**
* Ends With - property like %value.
*/
Expression endsWith(String propertyName, String value);
/**
* Case insensitive Ends With - property like %value. Typically uses a lower()
* function to make the expression case insensitive.
*/
Expression iendsWith(String propertyName, String value);
/**
* Contains - property like %value%.
*/
Expression contains(String propertyName, String value);
/**
* Case insensitive Contains - property like %value%. Typically uses a lower()
* function to make the expression case insensitive.
*/
Expression icontains(String propertyName, String value);
/**
* In expression using pairs of value objects.
*/
Expression inPairs(Pairs pairs);
/**
* In expression using multiple columns.
*/
Expression inTuples(InTuples pairs);
/**
* In - property has a value in the array of values.
*/
Expression in(String propertyName, Object[] values);
/**
* In - using a subQuery.
*/
Expression in(String propertyName, Query<?> subQuery);
/**
* In - property has a value in the collection of values.
*/
Expression in(String propertyName, Collection<?> values);
/**
* In where null or empty values means that no predicate is added to the query.
* <p>
* That is, only add the IN predicate if the values are not null or empty.
* <p>
* Without this we typically need to code an <code>if</code> block to only add
* the IN predicate if the collection is not empty like:
* </p>
*
* <h3>Without inOrEmpty()</h3>
* <pre>{@code
*
* query.where() // add some predicates
* .eq("status", Status.NEW);
*
* if (ids != null && !ids.isEmpty()) {
* query.where().in("customer.id", ids);
* }
*
* query.findList();
*
* }</pre>
*
* <h3>Using inOrEmpty()</h3>
* <pre>{@code
*
* query.where()
* .eq("status", Status.NEW)
* .inOrEmpty("customer.id", ids)
* .findList();
*
* }</pre>
*/
Expression inOrEmpty(String propertyName, Collection<?> values);
/**
* EXISTS a raw SQL SubQuery.
*
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression exists(String sqlSubQuery, Object... bindValues);
/**
* Not EXISTS a raw SQL SubQuery.
*
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression notExists(String sqlSubQuery, Object... bindValues);
/**
* IN a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression inSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Not IN a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression notInSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Equal To a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression eqSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Not Equal To a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression neSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Greater Than or Equal To a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression geSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Greater Than a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression gtSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Less Than or Equal To a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression leSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Less Than a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression ltSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Not In - property has a value in the array of values.
*/
Expression notIn(String propertyName, Object[] values);
/**
* Not In - property has a value in the collection of values.
*/
Expression notIn(String propertyName, Collection<?> values);
/**
* Not In - using a subQuery.
*/
Expression notIn(String propertyName, Query<?> subQuery);
/**
* Exists expression
*/
Expression exists(Query<?> subQuery);
/**
* Not exists expression
*/
Expression notExists(Query<?> subQuery);
/**
* Is empty expression for collection properties.
*/
Expression isEmpty(String propertyName);
/**
* Is not empty expression for collection properties.
*/
Expression isNotEmpty(String propertyName);
/**
* Id Equal to - ID property is equal to the value.
*/
Expression idEq(Object value);
/**
* Id IN a list of Id values.
*/
Expression idIn(Object... idValues);
/**
* Id IN a collection of Id values.
*/
Expression idIn(Collection<?> idCollection);
/**
* All Equal - Map containing property names and their values.
* <p>
* Expression where all the property names in the map are equal to the
* corresponding value.
* </p>
*
* @param propertyMap a map keyed by property names.
*/
Expression allEq(Map<String, Object> propertyMap);
/**
* Add expression for ANY of the given bit flags to be set.
*
* @param propertyName The property that holds the flags value
* @param flags The flags we are looking for
*/
Expression bitwiseAny(String propertyName, long flags);
/**
* Add expression for ALL of the given bit flags to be set.
*
* @param propertyName The property that holds the flags value
* @param flags The flags we are looking for
*/
Expression bitwiseAll(String propertyName, long flags);
/**
* Add bitwise AND expression of the given bit flags to compare with the match/mask.
*
* @param propertyName The property that holds the flags value
* @param flags The flags we are looking for
*/
Expression bitwiseAnd(String propertyName, long flags, long match);
/**
* Add raw expression with a single parameter.
* <p>
* The raw expression should contain a single ? at the location of the
* parameter.
* </p>
*/
Expression raw(String raw, Object value);
/**
* Add raw expression with an array of parameters.
* <p>
* The raw expression should contain the same number of ? as there are
* parameters.
* </p>
*/
Expression raw(String raw, Object[] values);
/**
* Add raw expression with no parameters.
*/
Expression raw(String raw);
/**
* Create a Text Match expression (currently doc store/Elastic only).
*/
Expression textMatch(String propertyName, String search, Match options);
/**
* Create a Text Multi match expression (currently doc store/Elastic only).
*/
Expression textMultiMatch(String query, MultiMatch options);
/**
* Create a text simple query expression (currently doc store/Elastic only).
*/
Expression textSimple(String search, TextSimple options);
/**
* Create a text query string expression (currently doc store/Elastic only).
*/
Expression textQueryString(String search, TextQueryString options);
/**
* Create a text common terms expression (currently doc store/Elastic only).
*/
Expression textCommonTerms(String search, TextCommonTerms options);
/**
* And - join two expressions with a logical and.
*/
Expression and(Expression expOne, Expression expTwo);
/**
* Or - join two expressions with a logical or.
*/
Expression or(Expression expOne, Expression expTwo);
/**
* Negate the expression (prefix it with NOT).
*/
Expression not(Expression exp);
/**
* Return a list of expressions that will be joined by AND's.
*/
<T> Junction<T> conjunction(Query<T> query);
/**
* Return a list of expressions that will be joined by OR's.
*/
<T> Junction<T> disjunction(Query<T> query);
/**
* Return a list of expressions that will be joined by AND's.
*/
<T> Junction<T> conjunction(Query<T> query, ExpressionList<T> parent);
/**
* Return a list of expressions that will be joined by OR's.
*/
<T> Junction<T> disjunction(Query<T> query, ExpressionList<T> parent);
/**
* Return a Text query junction for MUST, SHOULD or MUST NOT.
* <p>
* This is doc store Elastic only.
* </p>
*/
<T> Junction<T> junction(Junction.Type type, Query<T> query, ExpressionList<T> parent);
/**
* Add the expressions to the given expression list.
*
* @param where The expression list to add the expressions to
* @param expressions The expressions that are parsed
* @param params Bind parameters to match ? or ?1 bind positions.
*/
<T> void where(ExpressionList<T> where, String expressions, Object[] params);
}
@@ -1,139 +0,0 @@
package io.ebean;
import java.io.Serializable;
/**
* Defines how a relationship is fetched via either normal SQL join,
* a eager secondary query, via lazy loading or via eagerly hitting L2 cache.
* <p>
* <pre>{@code
* // Normal fetch join results in a single SQL query
* List<Order> list = DB.find(Order.class).fetch("details").findList();
*
* }</pre>
* <p>
* Example: Using a "query join" instead of a "fetch join" we instead use 2 SQL queries
*
* <pre>{@code
*
* // This will use 2 SQL queries to build this object graph
* List<Order> list =
* DB.find(Order.class)
* .fetch("details", FetchConfig.ofQuery())
* .findList();
*
* // query 1) find order
* // query 2) find orderDetails where order.id in (?,?...) // first 100 order id's
*
* }</pre>
*/
public final class FetchConfig implements Serializable {
private static final long serialVersionUID = 1L;
private static final int JOIN_MODE = 0;
private static final int QUERY_MODE = 1;
private static final int LAZY_MODE = 2;
private static final int CACHE_MODE = 3;
private final int mode;
private final int batchSize;
private final int hashCode;
private FetchConfig(int mode, int batchSize) {
this.mode = mode;
this.batchSize = batchSize;
this.hashCode = mode + 10 * batchSize;
}
/**
* Return FetchConfig to eagerly fetch the relationship using L2 cache.
* <p>
* Any cache misses will be loaded by secondary query to the database.
*/
public static FetchConfig ofCache() {
return new FetchConfig(CACHE_MODE, 100);
}
/**
* Return FetchConfig to eagerly fetch the relationship using a secondary query.
*/
public static FetchConfig ofQuery() {
return new FetchConfig(QUERY_MODE, 100);
}
/**
* Return FetchConfig to eagerly fetch the relationship using a secondary with a given batch size.
*/
public static FetchConfig ofQuery(int batchSize) {
return new FetchConfig(QUERY_MODE, batchSize);
}
/**
* Return FetchConfig to lazily load the relationship.
*/
public static FetchConfig ofLazy() {
return new FetchConfig(LAZY_MODE, 0);
}
/**
* Return FetchConfig to lazily load the relationship specifying the batch size.
*/
public static FetchConfig ofLazy(int batchSize) {
return new FetchConfig(LAZY_MODE, batchSize);
}
/**
* Return FetchConfig to fetch the relationship using SQL join.
*/
public static FetchConfig ofDefault() {
return new FetchConfig(JOIN_MODE, 100);
}
/**
* Return the batch size for fetching.
*/
public int getBatchSize() {
return batchSize;
}
/**
* Return true if the fetch should use the L2 cache.
*/
public boolean isCache() {
return mode == CACHE_MODE;
}
/**
* Return true if the fetch should be a eager secondary query.
*/
public boolean isQuery() {
return mode == QUERY_MODE;
}
/**
* Return true if the fetch should be a lazy query.
*/
public boolean isLazy() {
return mode == LAZY_MODE;
}
/**
* Return true if the fetch should try to use SQL join.
*/
public boolean isJoin() {
return mode == JOIN_MODE;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
return (hashCode == ((FetchConfig) o).hashCode);
}
@Override
public int hashCode() {
return hashCode;
}
}
@@ -1,74 +0,0 @@
package io.ebean;
import jakarta.persistence.PersistenceException;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* FutureMap represents the result of a background query execution that will
* return a map of entities.
* <p>
* It extends the java.util.concurrent.Future with the ability to cancel the
* query, check if it is finished and get the resulting list waiting for the
* query to finish (ie. the standard features of java.util.concurrent.Future).
* </p>
* <p>
* A simple example:
* </p>
* <pre>{@code
*
* // create a query to find all orders
* Query<Long,Order> query = DB.find(Order.class)
* .setMapKey("id");
*
* // execute the query in a background thread
* // immediately returning the futureMap
* FutureMap<Long,Order> futureMap = query.findFutureMap();
*
* // do something else ...
*
* if (!futureMap.isDone()){
* // we can cancel the query execution. This will cancel
* // the underlying query if that is supported by the JDBC
* // driver and database
* futureMap.cancel(true);
* }
*
* if (!futureMap.isCancelled()){
* // wait for the query to finish and return the map
* Map<Long,Order> map = futureMap.get();
* ...
* }
*
* }</pre>
*/
public interface FutureMap<K, T> extends Future<Map<K, T>> {
/**
* Return the query that is being executed by a background thread.
*/
Query<T> getQuery();
/**
* Same as {@link #get()} but wraps InterruptedException and ExecutionException in the
* unchecked PersistenceException.
*
* @return The query list result
* @throws PersistenceException when a InterruptedException or ExecutionException occurs.
*/
Map<K, T> getUnchecked();
/**
* Same as {@link #get(long, TimeUnit)} but wraps InterruptedException
* and ExecutionException in the unchecked PersistenceException.
*
* @return The query list result
* @throws TimeoutException if the wait timed out
* @throws PersistenceException if a InterruptedException or ExecutionException occurs.
*/
Map<K, T> getUnchecked(long timeout, TimeUnit unit) throws TimeoutException;
}
@@ -1,36 +0,0 @@
package io.ebean;
/**
* IN expression using multiple columns.
* <p>
* Currently this is not supported with SQLServer or DB2.
* <p>
* Produces SQL expression in the form of (A,B,C) IN ((a0,b0,c0), (a1,b1,c1), ... )
* where A,B,C are the properties in the tuples.
*/
public interface InTuples {
/**
* Create given the properties in the tuples.
*/
static InTuples of(String... properties) {
return new DInTuples(properties);
}
/**
* Create given the properties in the tuples.
*/
static InTuples of(Query.Property<?>... properties) {
String[] props = new String[properties.length];
for (int i = 0; i < properties.length; i++) {
props[i] = properties[i].toString();
}
return new DInTuples(props);
}
/**
* Add a tuple entry. All values must be non-null.
*/
InTuples add(Object... values);
}
@@ -1,119 +0,0 @@
package io.ebean;
import org.jspecify.annotations.Nullable;
/**
* Options to be used with insert such as ON CONFLICT DO UPDATE | NOTHING.
*/
public interface InsertOptions {
/**
* Use ON CONFLICT UPDATE with automatic determination of the unique columns to conflict on.
* <p>
* Uses mapping to determine the unique columns - {@code @Column(unique=true)} and {@code @Index(unique=true)} .
*/
InsertOptions ON_CONFLICT_UPDATE = InsertOptions.builder()
.onConflictUpdate()
.build();
/**
* Use ON CONFLICT DO NOTHING with automatic determination of the unique columns to conflict on.
* <p>
* Uses mapping to determine the unique columns - {@code @Column(unique=true)} and {@code @Index(unique=true)} .
*/
InsertOptions ON_CONFLICT_NOTHING = InsertOptions.builder()
.onConflictNothing()
.build();
/**
* Return a builder for InsertOptions.
*/
static Builder builder() {
return new DInsertOptionsBuilder();
}
/**
* Return the constraint name that is used for ON CONFLICT.
*/
@Nullable
String constraint();
/**
* Return the unique columns that is used for ON CONFLICT.
* <p>
* When not explicitly set will use mapping like {@code @Column(unique=true)} to determine the
* non-unique columns.
*/
@Nullable
String uniqueColumns();
/**
* Return the ON CONFLICT UPDATE SET clause.
* <p>
* When not set will use the non-unique columns.
*/
@Nullable
String updateSet();
/**
* Return if GetGeneratedKeys should be used to fetch the generated keys after insert.
*/
@Nullable
Boolean getGetGeneratedKeys();
/**
* Return the key for these build options.
*/
String key();
/**
* The builder for InsertOptions.
*/
interface Builder {
/**
* Use a ON CONFLICT UPDATE automatically determining the unique columns.
*/
Builder onConflictUpdate();
/**
* Use a ON CONFLICT DO NOTHING automatically determining the unique columns.
*/
Builder onConflictNothing();
/**
* Specify an explicit conflict constraint name.
* <p>
* When this is used then unique columns will not be used.
*/
Builder constraint(String constraint);
/**
* Specify the unique columns for the conflict target.
* <p>
* When not specified and constraint is also not specified then
* it will automatically determine the unique columns
* based on mapping like {@code @Column(unique=true)} and
* {@code @Index(unique=true)} .
*/
Builder uniqueColumns(String uniqueColumns);
/**
* Specify the ON CONFLICT DO UPDATE SET clause.
* <p>
* When not specified ebean will include all the non-unique columns.
*/
Builder updateSet(String updateSet);
/**
* Specify if GetGeneratedKeys should be used to return generated keys.
*/
Builder getGeneratedKeys(boolean getGeneratedKeys);
/**
* Build and return the insert options.
*/
InsertOptions build();
}
}

Some files were not shown because too many files have changed in this diff Show More