Compare commits

...
Author SHA1 Message Date
Rob Bygrave 2c4b8492da ebean-test: Add PersistenceContextAccess.clear() for tests that need to clear the Persistence Context
To support tests that use a transaction that wraps test setup and running the test logic. The need for this case is to clear the persistence context after the test setup phase.
2024-03-16 14:56:24 +13:00
Rob BygraveandGitHub 02dafc9838 Merge pull request #3360 from ebean-orm/feature/refactor-DbExpressionRequest
Refactor extract DbExpressionRequest interface for db platform specific expressions
2024-03-08 00:53:56 +13:00
Rob Bygrave 0816810d3b Refactor extract DbExpressionRequest interface for db platform specific expressions
This provides a simpler DbExpressionRequest interface for db platform specific expression adapters (rather than the SpiExpressionRequest which has more features that we don't wish to expose to those expression adapters.
2024-03-07 22:45:21 +13:00
Rob Bygrave 1f6e2ee844 No effective change - update test only ClusterTest, increase wait to 200ms 2024-03-07 20:59:41 +13:00
Rob Bygrave dc00765a98 Merge branch 'fix-for-db2' 2024-03-07 20:45:57 +13:00
Rob Bygrave a48b2f4ebe #3354 Use 4000 for DB Lob detection with distinct query
- Use 4000 to match the DB2 logic for considering a column a lob (for distinct etc)
- Rename distinctNoLobs -> platformDistinctNoLobs
- Rename  isDbLob() -> isLobForPlatform()
- Rename unselectLobs() -> unselectLobsForPlatform()
2024-03-07 20:45:40 +13:00
Rob BygraveandGitHub 837563544f Merge pull request #3357 from ebean-orm/feature/avaje-config-dependency-ContainerConfig
Modify ContainerConfig to remove the avaje-config dependency
2024-03-07 20:23:36 +13:00
Rob Bygrave fd199f406b Modify ContainerConfig to remove the avaje-config dependency
This actually reverts a change that was made in commit:
https://github.com/ebean-orm/ebean/commit/803f1d86428ce3b653276d72207e5a0009b57d16
2024-03-05 21:18:27 +13:00
Roland Praml a48e96c7e9 FIX broken test for DB2 2024-03-04 10:02:05 +01:00
Rob Bygrave 7ba6e5f67d Add howto-deploy-to-central.md 2024-03-03 22:08:47 +13:00
Rob Bygrave 6ce42b1ca3 Version 14.0.1 2024-03-03 20:24:26 +13:00
Rob BygraveandGitHub 89617cefbe Merge pull request #3353 from ebean-orm/feature/bump-migration-14
dep: Bump ebean-migration to 14.0.0, no effective change
2024-03-03 20:19:40 +13:00
Rob Bygrave dd377621a4 dep: Bump ebean-migration to 14.0.0, no effective change
No effective change in that ebean-migration 14.0.0 has no change, it was released to align version numbers with 14.x
2024-03-03 20:19:17 +13:00
Rob Bygrave d844855462 Bump ebean-agent to 14.0.1 2024-03-03 18:32:14 +13:00
Rob BygraveandGitHub f68c25d5f3 Merge pull request #3352 from ebean-orm/feature/dep-common-components
dep: Update the common components to 14.0.0 ebean-joda-types, ebean-jackson-jsonnode
2024-03-03 18:29:15 +13:00
Rob Bygrave 61cfc7a979 dep: Update the common components to 14.0.0 ebean-joda-types, ebean-jackson-jsonnode 2024-03-03 17:01:36 +13:00
Rob BygraveandGitHub 3c98ee7f1b Merge pull request #3351 from ebean-orm/dep/bump-config
Bump test dependencies only - logback and ebean-test-containers
2024-03-03 16:54:56 +13:00
Rob Bygrave 0738316f15 Bump test dependencies only - logback and ebean-test-containers 2024-03-03 16:54:22 +13:00
Rob BygraveandGitHub ceb83befa3 Merge pull request #3350 from ebean-orm/dep/bump-config
dep: Bump avaje-config to 3.12 - supports AWS AppConfig & Dynamic Logback
2024-03-03 15:42:59 +13:00
Rob Bygrave a0b04cceda dep: Bump avaje-config to 3.12 - supports AWS AppConfig & Dynamic Logback
This version of avaje-config supports using AWS AppConfig as a configuration source (via avaje-aws-appconfig). It also supports dynamic changing Logback logging levels (via avaje-dynamic-logback).
2024-03-03 15:38:14 +13:00
Rob Bygrave 03edfb5454 git workflow trigger on push to master and pull_request 2024-03-03 15:33:39 +13:00
Rob BygraveandGitHub 62015451df Merge pull request #3349 from ebean-orm/feature/dep-ebean-datasource
dep: Bump ebean-datasource to 8.12
2024-03-03 15:32:36 +13:00
Rob Bygrave ed9113efe6 dep: Bump ebean-datasource to 8.12
This adds the option to register a JVM shutdown hook (which we generally will not use with ebean as the ebean io.ebean.Database shutdown wants to shutdown the DataSource after any background tasks have completed).

This also adds an experimental feature for use with AWS Lambda to check for old idle connections due to lambda suspension.
2024-03-03 15:24:44 +13:00
Rob Bygrave 334793667e Add deployment error message for ManyToMany with one of the related beans missing an @Id property 2024-03-03 14:14:23 +13:00
Rob BygraveandGitHub 351a1c4739 Merge pull request #3348 from ebean-orm/feature/3313-fetchGroup-with-config
#3313 Ability to configure fetch batch size when using FetchGroups and query beans
2024-03-03 13:53:52 +13:00
Rob Bygrave b2de333dcc #3313 Ability to configure fetch batch size when using FetchGroups and query beans
We can do this currently using string paths and properties, this adds support for doing this when using query beans and strong types
2024-03-03 13:47:49 +13:00
Rob Bygrave 6091f7b683 No effective change - tidy test TestJsonImplicitLoaded 2024-03-03 12:25:25 +13:00
Rob BygraveandGitHub 43fb84cbc0 Merge pull request #3345 from FOCONIS/jsonwrite-loaded-props
NEW: Allow control of jsonwrite-loadedprops
2024-03-03 12:23:17 +13:00
Rob BygraveandGitHub 52a4e9e19b Merge pull request #3347 from ebean-orm/feature/3337-querybean-imports
#3337 Fix querybean-generation to not import the entity bean type
2024-03-03 12:17:42 +13:00
Rob Bygrave a2cdea24ed #3337 Fix querybean-generation to not import the entity bean type
Use the full canonical name of the entity bean in the generated code.
2024-03-03 12:13:49 +13:00
Rob Bygrave cd780208e5 Javadoc format only for io.ebean.Database 2024-03-03 11:45:36 +13:00
Rob BygraveandGitHub 9ce0e923d7 Merge pull request #3346 from ebean-orm/feature/lengthCheck-postgres
#3341 String length validation with Postgres PGobject (JSON/JSONB)
2024-03-02 10:26:52 +13:00
Rob Bygrave 9e461e4708 #3341 String length validation with Postgres PGobject (JSON/JSONB) 2024-03-02 10:06:22 +13:00
Rob Bygrave 5fa09a6f90 #3341 String length validation with Postgres PGobject (JSON/JSONB) 2024-03-02 09:52:04 +13:00
Rob Bygrave 6babb2e6f5 Add ebean.lengthCheck for mariadb test run 2024-03-02 09:39:25 +13:00
Rob Bygrave 26abe27e42 Add ebean.lengthCheck for sqlserver17 test run 2024-03-02 09:38:33 +13:00
Rob Bygrave 9b18d46b78 Add ebean.lengthCheck for mysql test run 2024-03-02 09:27:05 +13:00
Roland Praml eed487ad26 NEW: Allow control of jsonwrite-loadedprops 2024-02-29 13:26:22 +01:00
Rob BygraveandGitHub c10865dfaf Merge pull request #3344 from ebean-orm/feature/bump-avaje-config-311
Bump avaje-config to 3.11
2024-02-27 21:22:38 +13:00
Rob Bygrave 2352df309c Bump avaje-config to 3.11 2024-02-27 21:21:58 +13:00
Rob Bygrave feb2bd1e15 String length validation tidy up 2024-02-27 21:04:19 +13:00
Rob Bygrave 11c9bdfc6f Squashed commit of the following:
commit 20152e16891582f8ff466a93ec2cf01871824d6d
Author: Rob Bygrave <robin.bygrave@gmail.com>
Date:   Tue Feb 27 20:59:51 2024 +1300

    #3341 Update DatabaseConfig for fluid style + javadoc

commit 1c495a7384
Author: Roland Praml <roland.praml@foconis.de>
Date:   Mon Feb 26 10:25:42 2024 +0100

    Fix: Compile errors

commit 574876b758
Merge: df7b04877 77634fc3e
Author: Roland Praml <roland.praml@foconis.de>
Date:   Fri Feb 23 16:16:39 2024 +0100

    Merge branch 'master-rob' into FOCONIS-string-length-validation

commit df7b04877d
Author: Rob Bygrave <robin.bygrave@gmail.com>
Date:   Mon Jun 26 21:16:32 2023 +1200

    #3121 BindMaxLength validation

    At deploy time derive a BindMaxLength property to use
    per BeanProperty

commit 4683877e0b
Merge: 9a4b9d4be d0020ab8c
Author: Rob Bygrave <robin.bygrave@gmail.com>
Date:   Fri Jun 23 16:51:34 2023 +1200

    Merge branch 'string-length-validation' of github.com:FOCONIS/ebean into FOCONIS-string-length-validation

commit d0020ab8ce
Author: Roland Praml <roland.praml@foconis.de>
Date:   Tue Jun 20 14:47:20 2023 +0200

    Length validation less invasive

commit 9b3b8ad46a
Author: Roland Praml <roland.praml@foconis.de>
Date:   Tue Jun 20 13:03:04 2023 +0200

    extended DataBind, so that it could return the last bound object

commit ca3c02bc1c
Author: Roland Praml <roland.praml@foconis.de>
Date:   Mon Jun 19 09:52:52 2023 +0200

    Failing test for SqlServer
2024-02-27 21:04:06 +13:00
Rob BygraveandGitHub 4a6fc98395 Merge pull request #3339 from ebean-orm/fix/3338
Fix for #3338 Potential shutdown hang with SpringContextShutdownHook …
2024-02-26 21:58:39 +13:00
Rob Bygrave 7322030e90 Fix for #3338 Potential shutdown hang with SpringContextShutdownHook and ebean ShutdownHook 2024-02-26 08:32:44 +13:00
Rob BygraveandGitHub 77634fc3eb Merge pull request #3336 from ebean-orm/feature/bump-postgresql-4272
Bump postgresql dependency to 42.7.2
2024-02-21 16:11:24 +13:00
robin.bygrave ed8d4b5fc4 Bump postgresql dependency to 42.7.2 2024-02-21 16:05:13 +13:00
119 changed files with 1110 additions and 435 deletions
+4 -1
View File
@@ -1,7 +1,10 @@
name: Build
on: [push, pull_request]
on:
pull_request:
push:
branches: master
jobs:
build:
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+7 -7
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -14,7 +14,7 @@
<properties>
<postgis.jdbc.version>2.5.1</postgis.jdbc.version>
<postgres.jdbc.version>42.6.0</postgres.jdbc.version>
<postgres.jdbc.version>42.7.2</postgres.jdbc.version>
</properties>
<dependencies>
@@ -22,13 +22,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -47,19 +47,19 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis-types</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+8 -8
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,31 +17,31 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>13.24.0</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>13.24.0</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -60,13 +60,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
</parent>
<artifactId>composites</artifactId>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
</parent>
<name>ebean api</name>
@@ -39,7 +39,7 @@
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-config</artifactId>
<version>3.10</version>
<version>3.12</version>
</dependency>
<dependency>
@@ -3,7 +3,7 @@ package io.ebean;
import jakarta.persistence.PersistenceException;
/**
* Thrown when a foreign key constraint is enforced.
* Thrown when a foreign key constraint is enforced or a field is too large.
*/
public class DataIntegrityException extends PersistenceException {
private static final long serialVersionUID = -6740171949170180970L;
@@ -14,4 +14,11 @@ public class DataIntegrityException extends PersistenceException {
public DataIntegrityException(String message, Throwable cause) {
super(message, cause);
}
/**
* Create with message only.
*/
public DataIntegrityException(String message) {
super(message);
}
}
+10 -10
View File
@@ -88,16 +88,16 @@ public interface Database {
/**
* Return a new database builder.
* <pre>{@code
*
* // build the 'default' database using configuration
* // from application.properties / application.yaml
*
* Database db = Database.builder()
* .loadFromProperties()
* .build();
*
* }</pre>
* <pre>{@code
*
* // build the 'default' database using configuration
* // from application.properties / application.yaml
*
* Database db = Database.builder()
* .loadFromProperties()
* .build();
*
* }</pre>
*/
static DatabaseBuilder builder() {
return new DatabaseConfig();
@@ -87,6 +87,7 @@ public interface DatabaseBuilder {
}
return this;
}
/**
* Set the name of the Database.
*/
@@ -2221,6 +2222,11 @@ public interface DatabaseBuilder {
@Deprecated
DatabaseBuilder setMetricNaming(Function<String, String> metricNaming);
/**
* Sets the length check mode.
*/
DatabaseConfig lengthCheck(LengthCheck lengthCheck);
/**
* Provides read access (getters) for the DatabaseBuilder configuration
* that has been set.
@@ -3103,5 +3109,9 @@ public interface DatabaseBuilder {
*/
Function<String, String> getMetricNaming();
/**
* Returns the length check mode.
*/
LengthCheck getLengthCheck();
}
}
@@ -1,8 +1,5 @@
package io.ebean.config;
import io.avaje.config.Config;
import io.avaje.config.Configuration;
import java.util.Properties;
/**
@@ -19,16 +16,6 @@ public class ContainerConfig {
private String podName;
private int port;
private Properties properties;
private Configuration configuration;
public ContainerConfig() {
this.configuration = Config.asConfiguration();
this.active = configuration.getBool("ebean.cluster.active", active);
this.serviceName = configuration.getNullable("ebean.cluster.serviceName", serviceName);
this.namespace = configuration.getNullable("ebean.cluster.namespace", namespace);
this.podName = configuration.getNullable("ebean.cluster.podName", podName);
this.port = configuration.getInt("ebean.cluster.port", 0);
}
/**
* Return the service name.
@@ -104,7 +91,7 @@ public class ContainerConfig {
* Return the deployment properties.
*/
public Properties getProperties() {
return properties != null ? properties : configuration.asProperties();
return properties;
}
/**
@@ -114,4 +101,25 @@ public class ContainerConfig {
this.properties = properties;
}
/**
* Load the settings from properties.
*/
public void loadFromProperties(Properties properties) {
this.properties = properties;
this.active = getProperty(properties, "ebean.cluster.active", active);
this.serviceName = properties.getProperty("ebean.cluster.serviceName", serviceName);
this.namespace = properties.getProperty("ebean.cluster.namespace", namespace);
this.podName = properties.getProperty("ebean.cluster.podName", podName);
String portParam = properties.getProperty("ebean.cluster.port");
if (portParam != null) {
this.port = Integer.parseInt(portParam);
}
}
/**
* Return the boolean property setting.
*/
protected boolean getProperty(Properties properties, String key, boolean defaultValue) {
return "true".equalsIgnoreCase(properties.getProperty(key, Boolean.toString(defaultValue)));
}
}
@@ -545,6 +545,8 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
private String dumpMetricsOptions;
private LengthCheck lengthCheck = LengthCheck.OFF;
private Function<String, String> metricNaming = MetricNamingMatch.INSTANCE;
/**
@@ -2195,6 +2197,7 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
jdbcFetchSizeFindEach = p.getInt("jdbcFetchSizeFindEach", jdbcFetchSizeFindEach);
jdbcFetchSizeFindList = p.getInt("jdbcFetchSizeFindList", jdbcFetchSizeFindList);
databasePlatformName = p.get("databasePlatformName", databasePlatformName);
lengthCheck = p.getEnum(LengthCheck.class, "lengthCheck", lengthCheck);
uuidVersion = p.getEnum(UuidVersion.class, "uuidVersion", uuidVersion);
uuidStateFile = p.get("uuidStateFile", uuidStateFile);
@@ -2571,6 +2574,19 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
return this;
}
/**
* Returns the length check mode.
*/
public LengthCheck getLengthCheck() {
return lengthCheck;
}
@Override
public DatabaseConfig lengthCheck(LengthCheck lengthCheck) {
this.lengthCheck = lengthCheck;
return this;
}
public enum UuidVersion {
VERSION4,
VERSION1,
@@ -0,0 +1,22 @@
package io.ebean.config;
/**
* Defines the length-check mode.
*
* @author Roland Praml, FOCONIS AG
*/
public enum LengthCheck {
/**
* By default, length checking is off. This means, strings/jsons and files are passed to the DB and the DB might or might not check the length.
* The DB has to check the data length. Note this is not possible for certain datatypes (e.g. clob without size)
*/
OFF,
/**
* When enabling length check, ebean validates strings/json strings and files before saving them to DB.
*/
ON,
/**
* Same as "ON", but take the UTF8-bytelength for validation. This may be useful, if you have an UTF8 based charset (default for DB2)
*/
UTF8
}
@@ -8,6 +8,7 @@ import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
@@ -23,7 +24,7 @@ public final class ShutdownManager {
private static final System.Logger log = EbeanVersion.log;
private static final ReentrantLock lock = new ReentrantLock();
private static final List<Database> databases = new ArrayList<>();
private static final List<Database> databases = Collections.synchronizedList(new ArrayList<>());
private static final ShutdownHook shutdownHook = new ShutdownHook();
private static boolean stopping;
@@ -177,12 +178,7 @@ public final class ShutdownManager {
* Register an ebeanServer to be shutdown when the JVM is shutdown.
*/
public static void registerDatabase(Database server) {
lock.lock();
try {
databases.add(server);
} finally {
lock.unlock();
}
databases.add(server);
}
/**
@@ -192,12 +188,7 @@ public final class ShutdownManager {
* </p>
*/
public static void unregisterDatabase(Database server) {
lock.lock();
try {
databases.remove(server);
} finally {
lock.unlock();
}
databases.remove(server);
}
private static class ShutdownHook extends Thread {
@@ -22,6 +22,8 @@ public class JsonWriteOptions {
protected JsonConfig.Include include;
protected boolean includeLoadedImplicit = true;
protected Map<String, JsonWriteBeanVisitor<?>> visitorMap;
/**
@@ -73,6 +75,20 @@ public class JsonWriteOptions {
this.include = include;
}
/**
* Should loaded properties be included implicit, if no other fetch path is specified (default = true).
*/
public boolean isIncludeLoadedImplicit() {
return includeLoadedImplicit;
}
/**
* Set include loaded properties implicit (default = true).
*/
public void setIncludeLoadedImplicit(boolean includeLoadedImplicit) {
this.includeLoadedImplicit = includeLoadedImplicit;
}
/**
* Register a JsonWriteBeanVisitor for the root level.
*/
@@ -75,6 +75,7 @@ class DatabaseConfigTest {
props.setProperty("defaultServer", "false");
props.setProperty("skipDataSourceCheck", "true");
props.setProperty("readOnlyDatabase", "true");
props.setProperty("lengthCheck", "ON");
props.setProperty("queryPlan.enable", "true");
props.setProperty("queryPlan.thresholdMicros", "10000");
@@ -95,6 +96,7 @@ class DatabaseConfigTest {
assertTrue(settings.isLoadModuleInfo());
assertTrue(settings.skipDataSourceCheck());
assertTrue(settings.readOnlyDatabase());
assertThat(settings.getLengthCheck()).isEqualTo(LengthCheck.ON);
assertTrue(settings.isIdGeneratorAutomatic());
assertFalse(settings.getPlatformConfig().isCaseSensitiveCollation());
@@ -128,8 +130,11 @@ class DatabaseConfigTest {
assertThat(settings.getMappingLocations()).containsExactly("classpath:/foo","bar");
config.setPersistBatch(PersistBatch.NONE);
config.setPersistBatchOnCascade(PersistBatch.NONE);
config.persistBatch(PersistBatch.NONE)
.persistBatchOnCascade(PersistBatch.NONE)
.lengthCheck(LengthCheck.ON)
.lengthCheck(LengthCheck.UTF8);
Properties props1 = new Properties();
props1.setProperty("ebean.persistBatch", "ALL");
@@ -146,6 +151,7 @@ class DatabaseConfigTest {
assertEquals(PersistBatch.ALL, settings.getPersistBatch());
assertEquals(PersistBatch.ALL, settings.getPersistBatchOnCascade());
assertEquals(LengthCheck.UTF8, settings.getLengthCheck());
config.setEnabledL2Regions("r0,orgs");
assertEquals("r0,orgs", settings.getEnabledL2Regions());
@@ -174,6 +180,7 @@ class DatabaseConfigTest {
assertEquals(600, config.getQueryPlanCapturePeriodSecs());
assertEquals(10000L, config.getQueryPlanCaptureMaxTimeMillis());
assertEquals(10, config.getQueryPlanCaptureMaxCount());
assertThat(config.getLengthCheck()).isEqualTo(LengthCheck.OFF);
config.setLoadModuleInfo(false);
assertFalse(config.isAutoLoadModuleInfo());
+31 -31
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
</parent>
<name>ebean bom</name>
@@ -89,103 +89,103 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>13.24.0</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>13.24.0</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.18.0</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-xml</artifactId>
<version>13.18.0</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-autotune</artifactId>
<version>13.18.0</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>kotlin-querybean-generator</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-redis</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-spring-txn</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<!-- platforms -->
@@ -193,79 +193,79 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-clickhouse</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-db2</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-h2</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-hana</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mariadb</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mysql</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-nuodb</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-oracle</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgres</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis-types</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlite</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlserver</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+3 -3
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
</parent>
<artifactId>ebean-core-type</artifactId>
@@ -16,7 +16,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -30,7 +30,7 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.6.0</version>
<version>42.7.2</version>
<optional>true</optional>
</dependency>
@@ -174,4 +174,9 @@ public interface DataBinder {
*/
String popJson();
/**
* Returns the last bound object (e.g. for BindValidation). Note for InputStreams you'll get an InputStreamInfo.
*/
Object popLastObject();
}
@@ -0,0 +1,27 @@
package io.ebean.core.type;
import java.io.InputStream;
/**
* Helper to transports length info of DataBind.setBinaryStream(stream, length) to BindValidation
*
* @author Roland Praml, FOCONIS AG
*/
public final class InputStreamInfo {
private final InputStream stream;
private final long length;
public InputStreamInfo(InputStream stream, long length) {
this.stream = stream;
this.length = length;
}
public InputStream stream() {
return stream;
}
public long length() {
return length;
}
}
+8 -8
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
</parent>
<artifactId>ebean-core</artifactId>
@@ -22,7 +22,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -46,13 +46,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.18.0</version>
<version>14.0.0</version>
</dependency>
<dependency>
@@ -151,7 +151,7 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.6.0</version>
<version>42.7.2</version>
<optional>true</optional>
</dependency>
@@ -159,21 +159,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
@@ -3,13 +3,14 @@ package io.ebeaninternal.api;
import io.ebeaninternal.server.core.SpiOrmQueryRequest;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.expression.platform.DbExpressionHandler;
import io.ebeaninternal.server.expression.platform.DbExpressionRequest;
import java.util.List;
/**
* Request object used for gathering expression sql and bind values.
*/
public interface SpiExpressionRequest {
public interface SpiExpressionRequest extends DbExpressionRequest {
/**
* Return the DB specific handler for JSON and ARRAY expressions.
@@ -34,11 +35,13 @@ public interface SpiExpressionRequest {
/**
* Append to the expression sql without any parsing.
*/
@Override
SpiExpressionRequest append(String expression);
/**
* Append to the expression sql without any parsing.
*/
@Override
SpiExpressionRequest append(char c);
/**
@@ -47,6 +50,7 @@ public interface SpiExpressionRequest {
* This is a fast path case when expression is a bean property path and falls back to using parse()
* when that isn't the case.
*/
@Override
SpiExpressionRequest property(String expression);
/**
@@ -1,10 +1,14 @@
package io.ebeaninternal.server.bind;
import io.ebean.core.type.DataBinder;
import io.ebean.core.type.InputStreamInfo;
import io.ebeaninternal.api.CoreLog;
import io.ebeaninternal.server.core.timezone.DataTimeZone;
import java.io.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.math.BigDecimal;
import java.sql.*;
import java.util.ArrayList;
@@ -23,6 +27,8 @@ public class DataBind implements DataBinder {
protected int pos;
private String json;
private Object lastObject = null;
public DataBind(DataTimeZone dataTimeZone, PreparedStatement pstmt, Connection connection) {
this.dataTimeZone = dataTimeZone;
this.pstmt = pstmt;
@@ -65,16 +71,19 @@ public class DataBind implements DataBinder {
@Override
public void setObject(Object value) throws SQLException {
pstmt.setObject(++pos, value);
lastObject = value;
}
@Override
public final void setObject(Object value, int sqlType) throws SQLException {
pstmt.setObject(++pos, value, sqlType);
lastObject = value;
}
@Override
public void setNull(int jdbcType) throws SQLException {
pstmt.setNull(++pos, jdbcType);
lastObject = null;
}
@Override
@@ -96,7 +105,7 @@ public class DataBind implements DataBinder {
}
}
private void closeInputStreams() {
public void closeInputStreams() {
if (inputStreams != null) {
for (InputStream inputStream : inputStreams) {
try {
@@ -117,36 +126,43 @@ public class DataBind implements DataBinder {
@Override
public void setString(String value) throws SQLException {
pstmt.setString(++pos, value);
lastObject = value;
}
@Override
public final void setInt(int value) throws SQLException {
pstmt.setInt(++pos, value);
lastObject = null;
}
@Override
public final void setLong(long value) throws SQLException {
pstmt.setLong(++pos, value);
lastObject = null;
}
@Override
public final void setShort(short value) throws SQLException {
pstmt.setShort(++pos, value);
lastObject = null;
}
@Override
public final void setFloat(float value) throws SQLException {
pstmt.setFloat(++pos, value);
lastObject = null;
}
@Override
public final void setDouble(double value) throws SQLException {
pstmt.setDouble(++pos, value);
lastObject = null;
}
@Override
public final void setBigDecimal(BigDecimal value) throws SQLException {
pstmt.setBigDecimal(++pos, value);
lastObject = null;
}
@Override
@@ -157,6 +173,7 @@ public class DataBind implements DataBinder {
} else {
pstmt.setDate(++pos, value);
}
lastObject = null;
}
@Override
@@ -167,6 +184,7 @@ public class DataBind implements DataBinder {
} else {
pstmt.setTimestamp(++pos, value);
}
lastObject = null;
}
@Override
@@ -177,26 +195,31 @@ public class DataBind implements DataBinder {
} else {
pstmt.setTime(++pos, value);
}
lastObject = null;
}
@Override
public void setBoolean(boolean value) throws SQLException {
pstmt.setBoolean(++pos, value);
lastObject = null;
}
@Override
public void setBytes(byte[] value) throws SQLException {
pstmt.setBytes(++pos, value);
lastObject = value;
}
@Override
public void setByte(byte value) throws SQLException {
pstmt.setByte(++pos, value);
lastObject = null;
}
@Override
public void setChar(char value) throws SQLException {
pstmt.setString(++pos, String.valueOf(value));
lastObject = null;
}
@Override
@@ -211,21 +234,31 @@ public class DataBind implements DataBinder {
}
inputStreams.add(inputStream);
pstmt.setBinaryStream(++pos, inputStream, length);
lastObject = new InputStreamInfo(inputStream, length);
}
@Override
public void setBlob(byte[] bytes) throws SQLException {
pstmt.setBinaryStream(++pos, new ByteArrayInputStream(bytes), bytes.length);
lastObject = bytes;
}
@Override
public void setClob(String content) throws SQLException {
pstmt.setCharacterStream(++pos, new StringReader(content), content.length());
lastObject = content;
}
@Override
public void setArray(String arrayType, Object[] elements) throws SQLException {
pstmt.setArray(++pos, connection.createArrayOf(arrayType, elements));
lastObject = null;
}
@Override
public Object popLastObject() {
Object ret = lastObject;
lastObject = null;
return ret;
}
}
@@ -106,6 +106,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
private final String asOfViewSuffix;
private final boolean jacksonCorePresent;
private final int queryPlanTTLSeconds;
private final BindMaxLength bindMaxLength;
private int entityBeanCount;
private List<BeanDescriptor<?>> immutableDescriptorList;
/**
@@ -160,6 +161,19 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
this.changeLogListener = config.changeLogListener(bootupClasses.getChangeLogListener());
this.changeLogRegister = config.changeLogRegister(bootupClasses.getChangeLogRegister());
this.jacksonCorePresent = config.isJacksonCorePresent();
this.bindMaxLength = initMaxLength();
}
BindMaxLength initMaxLength() {
LengthCheck lengthCheck = this.config.getLengthCheck();
switch (lengthCheck) {
case OFF:
return null;
case UTF8:
return BindMaxLength.ofUtf8();
default:
return BindMaxLength.ofStandard();
}
}
@Override
@@ -1501,6 +1515,10 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
return list;
}
public BindMaxLength bindMaxLength() {
return bindMaxLength;
}
/**
* Comparator to sort the BeanDescriptors by name.
*/
@@ -1,6 +1,7 @@
package io.ebeaninternal.server.deploy;
import com.fasterxml.jackson.core.JsonToken;
import io.ebean.DataIntegrityException;
import io.ebean.ValuePair;
import io.ebean.bean.EntityBean;
import io.ebean.bean.EntityBeanIntercept;
@@ -40,8 +41,8 @@ import io.ebeanservice.docstore.api.mapping.DocMappingBuilder;
import io.ebeanservice.docstore.api.mapping.DocPropertyMapping;
import io.ebeanservice.docstore.api.mapping.DocPropertyOptions;
import io.ebeanservice.docstore.api.support.DocStructure;
import jakarta.persistence.PersistenceException;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
@@ -166,6 +167,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
*/
private final String dbComment;
private final DbEncryptFunction dbEncryptFunction;
private final BindMaxLength bindMaxLength;
private int deployOrder;
final boolean jsonSerialize;
final boolean jsonDeserialize;
@@ -258,6 +260,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
}
this.jsonSerialize = deploy.isJsonSerialize();
this.jsonDeserialize = deploy.isJsonDeserialize();
this.bindMaxLength = deploy.bindMaxLength();
}
private String tableAliasIntern(BeanDescriptor<?> descriptor, String s, boolean dbEncrypted, String dbColumn) {
@@ -345,6 +348,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
this.elPlaceHolderEncrypted = override.replace(source.elPlaceHolderEncrypted, source.dbColumn);
this.jsonSerialize = source.jsonSerialize;
this.jsonDeserialize = source.jsonDeserialize;
this.bindMaxLength = source.bindMaxLength;
}
/**
@@ -555,6 +559,18 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
@SuppressWarnings("unchecked")
public void bind(DataBind b, Object value) throws SQLException {
scalarType.bind(b, value);
if (bindMaxLength != null) {
Object obj = b.popLastObject();
long length = bindMaxLength.length(dbLength, obj);
if (length > dbLength) {
b.closeInputStreams();
String s = String.valueOf(value); // take original bind value here.
if (s.length() > 50) {
s = s.substring(0, 47) + "...";
}
throw new DataIntegrityException("Cannot bind value '" + s + "' (effective length=" + length + ") to column '" + dbColumn + "' (length=" + dbLength + ")");
}
}
}
@SuppressWarnings(value = "unchecked")
@@ -1166,14 +1182,14 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
* Returns true if this <code>isLob()</code> or the type will effectively map to a lob.
*/
@Override
public boolean isDbLob() {
public boolean isLobForPlatform() {
if (lob) {
return true;
}
switch (dbType) {
case DbPlatformType.JSON:
case DbPlatformType.JSONB:
return dbLength == 0; // must be analog to DbPlatformTypeMapping.lookup
return dbLength == 0 || dbLength > 4000; // must be analog to DbPlatformTypeMapping.lookup
case DbPlatformType.JSONBlob:
case DbPlatformType.JSONClob:
return true;
@@ -379,6 +379,9 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
for (ExportedProperty exportedProperty : exportedProperties) {
row.addColumn(exportedProperty.getForeignDbColumn());
}
if (importedId == null) {
throw new PersistenceException("Missing @Id property on bean related to ManyToMany " + fullName());
}
importedId.buildImport(row);
return row.build();
}
@@ -0,0 +1,90 @@
package io.ebeaninternal.server.deploy;
import io.ebean.core.type.InputStreamInfo;
import java.nio.charset.StandardCharsets;
/**
* The max length check on bind values.
*/
public interface BindMaxLength {
/**
* Return a UTF8 based implementation.
*/
static BindMaxLength ofUtf8() {
return new UTF8();
}
/**
* Return a standard implementation.
*/
static BindMaxLength ofStandard() {
return new Standard();
}
/**
* Return the length of the object.
*/
long length(int dbLength, Object obj);
/**
* Length check based on UTF8 bytes.
*/
final class UTF8 implements BindMaxLength {
@Override
public long length(int dbLength, Object obj) {
if (obj == null) {
return -1;
} else if (obj instanceof String) {
String s = (String) obj;
return utf8String(dbLength, s);
} else if (obj instanceof byte[]) {
return ((byte[]) obj).length;
} else if (obj instanceof InputStreamInfo) {
return ((InputStreamInfo) obj).length();
} else if ("org.postgresql.util.PGobject".equals(obj.getClass().getCanonicalName())) {
String value = ((org.postgresql.util.PGobject) obj).getValue();
return value == null ? -1 : utf8String(dbLength, value);
} else {
return -1;
}
}
private static int utf8String(int dbLength, String s) {
int stringLength = s.length();
if (stringLength > dbLength) {
return stringLength;
} else if (stringLength * 4 <= dbLength) {
return -1;
} else {
return s.getBytes(StandardCharsets.UTF_8).length;
}
}
}
/**
* Standard string length implementation.
*/
final class Standard implements BindMaxLength {
@Override
public long length(int dbLength, Object obj) {
if (obj == null) {
return -1;
} else if (obj instanceof String) {
return ((String) obj).length();
} else if (obj instanceof byte[]) {
return ((byte[]) obj).length;
} else if (obj instanceof InputStreamInfo) {
return ((InputStreamInfo) obj).length();
} else if ("org.postgresql.util.PGobject".equals(obj.getClass().getCanonicalName())) {
String value = ((org.postgresql.util.PGobject) obj).getValue();
return value == null ? -1 : value.length();
} else {
return -1;
}
}
}
}
@@ -63,7 +63,7 @@ class DynamicPropertyAggregationFormula extends DynamicPropertyBase {
}
@Override
public boolean isDbLob() {
public boolean isLobForPlatform() {
return false;
}
@@ -1,10 +1,10 @@
package io.ebeaninternal.server.deploy.meta;
import io.ebean.DatabaseBuilder;
import io.ebean.annotation.Cache;
import io.ebean.annotation.DocStore;
import io.ebean.annotation.DocStoreMode;
import io.ebean.annotation.Identity;
import io.ebean.DatabaseBuilder;
import io.ebean.config.TableName;
import io.ebean.config.dbplatform.IdType;
import io.ebean.config.dbplatform.PlatformIdGenerator;
@@ -21,7 +21,6 @@ import io.ebeaninternal.server.idgen.UuidV1IdGenerator;
import io.ebeaninternal.server.idgen.UuidV1RndIdGenerator;
import io.ebeaninternal.server.idgen.UuidV4IdGenerator;
import io.ebeaninternal.server.rawsql.SpiRawSql;
import jakarta.persistence.Entity;
import jakarta.persistence.MappedSuperclass;
@@ -139,6 +138,10 @@ public class DeployBeanDescriptor<T> {
this.beanType = beanType;
}
public BindMaxLength bindMaxLength() {
return manager.bindMaxLength();
}
private String[] readPropertyNames() {
try {
Field field = beanType.getField("_ebean_props");
@@ -1,14 +1,17 @@
package io.ebeaninternal.server.deploy.meta;
import io.avaje.lang.Nullable;
import io.ebean.annotation.*;
import io.ebean.config.ScalarTypeConverter;
import io.ebean.config.dbplatform.DbDefaultValue;
import io.ebean.config.dbplatform.DbEncrypt;
import io.ebean.config.dbplatform.DbEncryptFunction;
import io.ebean.config.dbplatform.ExtraDbTypes;
import io.ebean.core.type.ScalarType;
import io.ebean.util.AnnotationUtil;
import io.ebeaninternal.server.core.InternString;
import io.ebeaninternal.server.deploy.BeanProperty;
import io.ebeaninternal.server.deploy.BindMaxLength;
import io.ebeaninternal.server.deploy.DbMigrationInfo;
import io.ebeaninternal.server.deploy.DeployDocPropertyOptions;
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
@@ -1133,4 +1136,20 @@ public class DeployBeanProperty {
boolean isJsonType() {
return mutationDetection != null;
}
@Nullable
public BindMaxLength bindMaxLength() {
if (dbLength == 0) {
return null;
}
switch (dbType) {
case Types.VARCHAR:
case Types.BLOB:
case ExtraDbTypes.JSON:
return desc.bindMaxLength();
default:
return null;
}
}
}
@@ -1,6 +1,5 @@
package io.ebeaninternal.server.expression.platform;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.expression.BitwiseOp;
/**
@@ -9,7 +8,7 @@ import io.ebeaninternal.server.expression.BitwiseOp;
abstract class BaseDbExpression implements DbExpressionHandler {
@Override
public void bitwise(SpiExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, long match) {
public void bitwise(DbExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, long match) {
final String bitOp = bitOp(operator);
request.append('(').property(propName).append(' ').append(bitOp).append(" ? ").append(compare).append(" ?)");
}
@@ -28,7 +27,7 @@ abstract class BaseDbExpression implements DbExpressionHandler {
/**
* Common alternative where the bitwise operation is a function (specifically bitand is used - H2 and Oracle).
*/
protected void bitwiseFunction(SpiExpressionRequest request, String propName, BitwiseOp operator, String compare) {
protected void bitwiseFunction(DbExpressionRequest request, String propName, BitwiseOp operator, String compare) {
final String funcName = functionName(operator);
request.append(funcName).append('(').property(propName).append(", ?) ").append(compare).append(" ?");
}
@@ -1,6 +1,5 @@
package io.ebeaninternal.server.expression.platform;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.expression.Op;
/**
@@ -9,17 +8,17 @@ import io.ebeaninternal.server.expression.Op;
class BasicDbExpression extends BaseDbExpression {
@Override
public void json(SpiExpressionRequest request, String propName, String path, Op operator, Object value) {
public void json(DbExpressionRequest request, String propName, String path, Op operator, Object value) {
throw new RuntimeException("JSON expressions only supported on Postgres and Oracle");
}
@Override
public void arrayContains(SpiExpressionRequest request, String propName, boolean contains, Object... values) {
public void arrayContains(DbExpressionRequest request, String propName, boolean contains, Object... values) {
throw new RuntimeException("ARRAY expressions only supported on Postgres");
}
@Override
public void arrayIsEmpty(SpiExpressionRequest request, String propName, boolean empty) {
public void arrayIsEmpty(DbExpressionRequest request, String propName, boolean empty) {
throw new RuntimeException("ARRAY expressions only supported on Postgres");
}
}
@@ -1,6 +1,5 @@
package io.ebeaninternal.server.expression.platform;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.expression.BitwiseOp;
import io.ebeaninternal.server.expression.Op;
@@ -12,22 +11,22 @@ public interface DbExpressionHandler {
/**
* Write the db platform specific json expression.
*/
void json(SpiExpressionRequest request, String propName, String path, Op operator, Object value);
void json(DbExpressionRequest request, String propName, String path, Op operator, Object value);
/**
* Add SQL for ARRAY CONTAINS expression.
*/
void arrayContains(SpiExpressionRequest request, String propName, boolean contains, Object... values);
void arrayContains(DbExpressionRequest request, String propName, boolean contains, Object... values);
/**
* Add SQL for ARRAY IS EMPTY expression.
*/
void arrayIsEmpty(SpiExpressionRequest request, String propName, boolean empty);
void arrayIsEmpty(DbExpressionRequest request, String propName, boolean empty);
/**
* Add the bitwise expression.
*/
void bitwise(SpiExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, long match);
void bitwise(DbExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, long match);
/**
* Performs a "CONCAT" operation for that platform.
@@ -0,0 +1,22 @@
package io.ebeaninternal.server.expression.platform;
/**
* Request building the expression sql.
*/
public interface DbExpressionRequest {
/**
* Append to the expression sql without any parsing.
*/
DbExpressionRequest append(String expression);
/**
* Append to the expression sql without any parsing.
*/
DbExpressionRequest append(char c);
/**
* Append to the expression sql with logical property parsing to db columns with logical path prefix.
*/
DbExpressionRequest property(String expression);
}
@@ -1,6 +1,5 @@
package io.ebeaninternal.server.expression.platform;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.expression.BitwiseOp;
/**
@@ -9,7 +8,7 @@ import io.ebeaninternal.server.expression.BitwiseOp;
final class H2DbExpression extends BasicDbExpression {
@Override
public void bitwise(SpiExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, long match) {
public void bitwise(DbExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, long match) {
final String funcName = functionName(operator);
request.append(funcName).append('(').property(propName).append(", cast(? as long)) ").append(compare).append(" cast(? as long)");
}
@@ -1,6 +1,5 @@
package io.ebeaninternal.server.expression.platform;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.expression.BitwiseOp;
import io.ebeaninternal.server.expression.Op;
@@ -10,17 +9,17 @@ import io.ebeaninternal.server.expression.Op;
final class HanaDbExpression extends BaseDbExpression {
@Override
public void bitwise(SpiExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, long match) {
public void bitwise(DbExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, long match) {
bitwiseFunction(request, propName, operator, compare);
}
@Override
public void json(SpiExpressionRequest request, String propName, String path, Op operator, Object value) {
public void json(DbExpressionRequest request, String propName, String path, Op operator, Object value) {
request.append("json_value(").property(propName).append(", '$.").append(path).append("')").append(operator.bind());
}
@Override
public void arrayIsEmpty(SpiExpressionRequest request, String propName, boolean empty) {
public void arrayIsEmpty(DbExpressionRequest request, String propName, boolean empty) {
request.append("cardinality(").property(propName).append(')');
if (empty) {
request.append(" = 0");
@@ -41,7 +40,7 @@ final class HanaDbExpression extends BaseDbExpression {
}
@Override
public void arrayContains(SpiExpressionRequest request, String propName, boolean contains, Object... values) {
public void arrayContains(DbExpressionRequest request, String propName, boolean contains, Object... values) {
for (int i = 0; i < values.length; i++) {
if (i > 0) {
request.append(" and ");
@@ -1,6 +1,5 @@
package io.ebeaninternal.server.expression.platform;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.expression.Op;
/**
@@ -9,7 +8,7 @@ import io.ebeaninternal.server.expression.Op;
final class MariaDbExpression extends BasicDbExpression {
@Override
public void json(SpiExpressionRequest request, String propName, String path, Op operator, Object value) {
public void json(DbExpressionRequest request, String propName, String path, Op operator, Object value) {
request.append('(').property(propName).append(" ->> '$.").append(path).append("')").append(operator.bind());
}
}
@@ -1,6 +1,5 @@
package io.ebeaninternal.server.expression.platform;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.expression.Op;
/**
@@ -9,7 +8,7 @@ import io.ebeaninternal.server.expression.Op;
final class MySqlDbExpression extends BasicDbExpression {
@Override
public void json(SpiExpressionRequest request, String propName, String path, Op operator, Object value) {
public void json(DbExpressionRequest request, String propName, String path, Op operator, Object value) {
request.append('(').property(propName).append(" ->> '$.").append(path).append("')").append(operator.bind());
}
@@ -1,6 +1,5 @@
package io.ebeaninternal.server.expression.platform;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.expression.BitwiseOp;
import io.ebeaninternal.server.expression.Op;
@@ -15,7 +14,7 @@ final class OracleDbExpression extends BaseDbExpression {
}
@Override
public void json(SpiExpressionRequest request, String propName, String path, Op operator, Object value) {
public void json(DbExpressionRequest request, String propName, String path, Op operator, Object value) {
if (operator == Op.EXISTS) {
request.append("json_exists(").property(propName).append(", '$.").append(path).append("')");
} else if (operator == Op.NOT_EXISTS) {
@@ -26,17 +25,17 @@ final class OracleDbExpression extends BaseDbExpression {
}
@Override
public void bitwise(SpiExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, long match) {
public void bitwise(DbExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, long match) {
bitwiseFunction(request, propName, operator, compare);
}
@Override
public void arrayContains(SpiExpressionRequest request, String propName, boolean contains, Object... values) {
public void arrayContains(DbExpressionRequest request, String propName, boolean contains, Object... values) {
throw new IllegalStateException("ARRAY expressions not supported on Oracle");
}
@Override
public void arrayIsEmpty(SpiExpressionRequest request, String propName, boolean empty) {
public void arrayIsEmpty(DbExpressionRequest request, String propName, boolean empty) {
throw new IllegalStateException("ARRAY expressions not supported on Oracle");
}
}
@@ -1,6 +1,5 @@
package io.ebeaninternal.server.expression.platform;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.expression.Op;
/**
@@ -14,7 +13,7 @@ final class PostgresDbExpression extends BaseDbExpression {
}
@Override
public void json(SpiExpressionRequest request, String propName, String path, Op operator, Object value) {
public void json(DbExpressionRequest request, String propName, String path, Op operator, Object value) {
String[] paths = path.split("\\.");
if (paths.length == 1) {
// (t0.content ->> 'title') = 'Some value'
@@ -34,7 +33,7 @@ final class PostgresDbExpression extends BaseDbExpression {
}
@Override
public void arrayContains(SpiExpressionRequest request, String propName, boolean contains, Object... values) {
public void arrayContains(DbExpressionRequest request, String propName, boolean contains, Object... values) {
if (!contains) {
request.append("not (");
}
@@ -49,7 +48,7 @@ final class PostgresDbExpression extends BaseDbExpression {
}
@Override
public void arrayIsEmpty(SpiExpressionRequest request, String propName, boolean empty) {
public void arrayIsEmpty(DbExpressionRequest request, String propName, boolean empty) {
request.append("coalesce(cardinality(").property(propName).append("),0)");
if (empty) {
request.append(" = 0");
@@ -1,6 +1,5 @@
package io.ebeaninternal.server.expression.platform;
import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.server.expression.Op;
/**
@@ -9,19 +8,19 @@ import io.ebeaninternal.server.expression.Op;
final class SqlServerDbExpression extends BaseDbExpression {
@Override
public void json(final SpiExpressionRequest request, final String propName,
public void json(final DbExpressionRequest request, final String propName,
final String path, final Op operator, final Object value) {
request.append("json_value(").property(propName).append(", '$.").append(path).append("')").append(operator.bind());
}
@Override
public void arrayContains(final SpiExpressionRequest request, final String propName,
public void arrayContains(final DbExpressionRequest request, final String propName,
final boolean contains, final Object... values) {
throw new RuntimeException("ARRAY expressions not supported on Microsoft SQL Server");
}
@Override
public void arrayIsEmpty(final SpiExpressionRequest request, final String propName, final boolean empty) {
public void arrayIsEmpty(final DbExpressionRequest request, final String propName, final boolean empty) {
throw new RuntimeException("ARRAY expressions not supported on Microsoft SQL Server");
}
}
@@ -402,7 +402,13 @@ public final class DJsonContext implements SpiJsonContext {
private WriteJson createWriteJson(JsonGenerator gen, JsonWriteOptions options) {
FetchPath pathProps = (options == null) ? null : options.getPathProperties();
Map<String, JsonWriteBeanVisitor<?>> visitors = (options == null) ? null : options.getVisitorMap();
return new WriteJson(server, gen, pathProps, visitors, determineObjectMapper(options), determineInclude(options));
return new WriteJson(server,
gen,
pathProps,
visitors,
determineObjectMapper(options),
determineInclude(options),
options == null || options.isIncludeLoadedImplicit());
}
private <T> void toJsonFromCollection(Collection<T> collection, String key, JsonGenerator gen, JsonWriteOptions options) throws IOException {
@@ -490,4 +496,5 @@ public final class DJsonContext implements SpiJsonContext {
JsonConfig.Include include = options.getInclude();
return (include != null) ? include : defaultInclude;
}
}
@@ -31,12 +31,15 @@ public final class WriteJson implements SpiJsonWriter {
private final ArrayStack<Object> parentBeans;
private final Object objectMapper;
private final JsonConfig.Include include;
private final boolean includeLoadedImplicit;
/**
* Construct for full bean use (normal).
*/
public WriteJson(SpiEbeanServer server, JsonGenerator generator, FetchPath fetchPath,
Map<String, JsonWriteBeanVisitor<?>> visitors, Object objectMapper, JsonConfig.Include include) {
Map<String, JsonWriteBeanVisitor<?>> visitors, Object objectMapper, JsonConfig.Include include,
boolean includeLoadedImplicit) {
this.server = server;
this.generator = generator;
@@ -44,6 +47,7 @@ public final class WriteJson implements SpiJsonWriter {
this.visitors = visitors;
this.objectMapper = objectMapper;
this.include = include;
this.includeLoadedImplicit = includeLoadedImplicit;
this.parentBeans = new ArrayStack<>();
this.pathStack = new PathStack();
}
@@ -54,6 +58,7 @@ public final class WriteJson implements SpiJsonWriter {
public WriteJson(JsonGenerator generator, JsonConfig.Include include) {
this.generator = generator;
this.include = include;
this.includeLoadedImplicit = true;
this.visitors = null;
this.server = null;
this.fetchPath = null;
@@ -443,7 +448,7 @@ public final class WriteJson implements SpiJsonWriter {
currentIncludeProps = null;
}
}
return new WriteBean(desc, explicitAllProps, currentIncludeProps, bean, visitor);
return new WriteBean(desc, explicitAllProps, includeLoadedImplicit, currentIncludeProps, bean, visitor);
}
@Override
@@ -477,6 +482,7 @@ public final class WriteJson implements SpiJsonWriter {
public static class WriteBean {
final boolean explicitAllProps;
final boolean includeLoadedImplicit;
final Set<String> currentIncludeProps;
final BeanDescriptor<?> desc;
final EntityBean currentBean;
@@ -485,14 +491,15 @@ public final class WriteJson implements SpiJsonWriter {
final JsonWriteBeanVisitor visitor;
WriteBean(BeanDescriptor<?> desc, EntityBean currentBean, JsonWriteBeanVisitor<?> visitor) {
this(desc, false, null, currentBean, visitor);
this(desc, false, true, null, currentBean, visitor);
}
WriteBean(BeanDescriptor<?> desc, boolean explicitAllProps, Set<String> currentIncludeProps, EntityBean currentBean, JsonWriteBeanVisitor<?> visitor) {
WriteBean(BeanDescriptor<?> desc, boolean explicitAllProps, boolean includeLoadedImplicit, Set<String> currentIncludeProps, EntityBean currentBean, JsonWriteBeanVisitor<?> visitor) {
super();
this.desc = desc;
this.currentBean = currentBean;
this.explicitAllProps = explicitAllProps;
this.includeLoadedImplicit = includeLoadedImplicit;
this.currentIncludeProps = currentIncludeProps;
this.visitor = visitor;
}
@@ -507,9 +514,11 @@ public final class WriteJson implements SpiJsonWriter {
if (currentIncludeProps != null) {
// explicitly controlled by pathProperties
return currentIncludeProps.contains(prop.name());
} else {
} else if (includeLoadedImplicit){
// include only loaded properties
return currentBean._ebean_getIntercept().isLoadedProperty(prop.propertyIndex());
} else {
return prop.isId();
}
}
@@ -33,7 +33,7 @@ public interface STreeProperty extends ScalarDataReader<Object> {
/**
* Returns true, if this is a lob property from db-perspective.
*/
boolean isDbLob();
boolean isLobForPlatform();
/**
* Return true if the property is an embedded type.
@@ -48,7 +48,7 @@ public final class SqlTreeBuilder {
private final SpiQuery.TemporalMode temporalMode;
private SqlTreeNode rootNode;
private boolean sqlDistinct;
private final boolean distinctNoLobs;
private final boolean platformDistinctNoLobs;
private final SqlTreeCommon common;
/**
@@ -63,7 +63,7 @@ public final class SqlTreeBuilder {
this.query = null;
this.subQuery = false;
this.distinctOnPlatform = false;
this.distinctNoLobs = false;
this.platformDistinctNoLobs = false;
this.queryDetail = queryDetail;
this.predicates = predicates;
this.temporalMode = SpiQuery.TemporalMode.CURRENT;
@@ -98,7 +98,7 @@ public final class SqlTreeBuilder {
this.predicates = predicates;
this.alias = new SqlTreeAlias(request.baseTableAlias(), temporalMode);
this.distinctOnPlatform = builder.isPlatformDistinctOn();
this.distinctNoLobs = builder.isPlatformDistinctNoLobs();
this.platformDistinctNoLobs = builder.isPlatformDistinctNoLobs();
String fromForUpdate = builder.fromForUpdate(query);
CQueryHistorySupport historySupport = builder.historySupport(query);
CQueryDraftSupport draftSupport = builder.draftSupport(query);
@@ -269,8 +269,8 @@ public final class SqlTreeBuilder {
if (joinList != null) {
joinList.add(selectNode);
}
if (sqlDistinct && distinctNoLobs) {
selectNode.unselectLobs();
if (sqlDistinct && platformDistinctNoLobs) {
selectNode.unselectLobsForPlatform();
}
return selectNode;
}
@@ -82,6 +82,6 @@ interface SqlTreeNode {
/**
* Unselect lobs (for distinct queries on DB2 and Oracle).
*/
default void unselectLobs() {
default void unselectLobsForPlatform() {
}
}
@@ -379,16 +379,16 @@ class SqlTreeNodeBean implements SqlTreeNode {
@Override
public void unselectLobs() {
public void unselectLobsForPlatform() {
if (children != null) {
for (SqlTreeNode child : children) {
child.unselectLobs();
child.unselectLobsForPlatform();
}
}
if (hasLob()) {
List<STreeProperty> lst = new ArrayList<>();
for (STreeProperty prop : properties) {
if (!prop.isDbLob()) {
if (!prop.isLobForPlatform()) {
lst.add(prop);
}
}
@@ -399,7 +399,7 @@ class SqlTreeNodeBean implements SqlTreeNode {
private boolean hasLob() {
for (STreeProperty prop : properties) {
if (prop.isDbLob()) {
if (prop.isLobForPlatform()) {
return true;
}
}
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
</parent>
<name>ebean ddl generation</name>
@@ -28,14 +28,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>provided</scope>
</dependency>
@@ -65,7 +65,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
+2 -2
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -14,7 +14,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>provided</scope>
</dependency>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
</parent>
<name>ebean postgis types</name>
@@ -19,14 +19,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<!-- provided scope -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>provided</scope>
</dependency>
@@ -47,7 +47,7 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.6.0</version>
<version>42.7.2</version>
<scope>provided</scope>
</dependency>
@@ -62,7 +62,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
</parent>
<name>ebean querybean</name>
@@ -17,7 +17,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>provided</scope>
</dependency>
@@ -63,14 +63,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
@@ -84,7 +84,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>provided</scope>
</dependency>
@@ -108,6 +108,18 @@ public abstract class TQAssocBean<T, R, QB> extends TQAssoc<T, R> {
return fetchWithProperties(FETCH_DEFAULT, properties);
}
/**
* Fetch this association with config for the type of fetch and the specified properties.
*
* @param config Fetch configuration to define the type of fetch to use
* @param properties The properties to fetch
*/
@SafeVarargs @SuppressWarnings("varargs")
public final R fetch(FetchConfig config, TQProperty<QB,?>... properties) {
return fetchWithProperties(config, properties);
}
/**
* Eagerly fetch this association using a 'query join' loading the specified properties.
*/
@@ -0,0 +1,14 @@
package org.example.domain;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Version;
@Entity
public class Alias {
@Id
long id;
@Version
long version;
}
@@ -1,6 +1,7 @@
package org.querytest;
import io.ebean.DB;
import io.ebean.FetchConfig;
import io.ebean.FetchGroup;
import io.ebean.Query;
import io.ebean.test.LoggedSql;
@@ -8,6 +9,7 @@ import org.example.domain.Customer;
import org.example.domain.Order;
import org.example.domain.OrderDetail;
import org.example.domain.otherpackage.PhoneNumber;
import org.example.domain.query.QContact;
import org.example.domain.query.QCustomer;
import org.example.domain.query.QOrder;
import org.example.domain.query.QOrderDetail;
@@ -26,10 +28,17 @@ public class QOrderTest {
private static final QOrder or = QOrder.alias();
private static final QContact co = QContact.alias();
private static final FetchGroup<Customer> fgC = QCustomer.forFetchGroup()
.select(cu.name, cu.phoneNumber)
.buildFetchGroup();
private static final FetchGroup<Customer> fgCustomerWithContacts = QCustomer.forFetchGroup()
.select(cu.name, cu.phoneNumber)
.contacts.fetch(FetchConfig.ofQuery(1000), co.firstName, co.lastName, co.email)
.buildFetchGroup();
private static final FetchGroup<Order> fgNested1 = QOrder.forFetchGroup()
.select(or.status, or.shipDate)
.customer.fetch(fgC)
@@ -70,6 +79,20 @@ public class QOrderTest {
DB.delete(customer);
}
@Test
void fetchQueryWithBatch() {
LoggedSql.start();
new QCustomer()
.select(fgCustomerWithContacts)
.findList();
final List<String> sql = LoggedSql.stop();
assertThat(sql).hasSize(2);
assertThat(sql.get(0)).contains("select t0.id, t0.name, t0.phone_number from be_customer t0");
assertThat(sql.get(1)).contains("select t0.customer_id, t0.id, t0.first_name, t0.last_name, t0.email from be_contact t0 where");
}
@Test
public void fetchCache() {
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
</parent>
<artifactId>ebean-redis</artifactId>
@@ -22,28 +22,28 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
@@ -57,7 +57,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>provided</scope>
</dependency>
@@ -1,12 +1,9 @@
package org.integration;
import io.ebean.DatabaseBuilder;
import io.ebean.redis.DuelCache;
import org.domain.Person;
import io.ebean.DB;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.config.DatabaseConfig;
import io.ebean.redis.DuelCache;
import org.domain.Person;
import org.domain.query.QPerson;
import org.junit.jupiter.api.Test;
@@ -14,21 +11,21 @@ import javax.sql.DataSource;
import static org.assertj.core.api.Assertions.assertThat;
public class ClusterTest {
class ClusterTest {
private Database createOther(DataSource dataSource) {
DatabaseBuilder config = new DatabaseConfig();
config.setDataSource(dataSource);
config.loadFromProperties();
config.setDefaultServer(false);
config.setName("other");
config.setDdlGenerate(false);
config.setDdlRun(false);
return DatabaseFactory.create(config);
return Database.builder()
.dataSource(dataSource)
.loadFromProperties()
.defaultDatabase(false)
.name("other")
.ddlGenerate(false)
.ddlRun(false)
.build();
}
@Test
public void testBothNear() throws InterruptedException {
void testBothNear() throws InterruptedException {
// ensure the default server exists first
final Database db = DB.getDefault();
Database other = createOther(db.pluginApi().dataSource());
@@ -61,7 +58,7 @@ public class ClusterTest {
}
@Test
public void test() throws InterruptedException {
void test() throws InterruptedException {
// ensure the default server exists first
final Database db = DB.getDefault();
Database other = createOther(db.pluginApi().dataSource());
@@ -116,6 +113,6 @@ public class ClusterTest {
}
private void allowAsyncMessaging() throws InterruptedException {
Thread.sleep(100);
Thread.sleep(200);
}
}
+3 -3
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
</parent>
<artifactId>ebean-spring-txn</artifactId>
@@ -28,7 +28,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>provided</scope>
</dependency>
@@ -77,7 +77,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
@@ -2,15 +2,19 @@ package org.example;
import io.ebean.DB;
import io.ebean.Transaction;
import io.ebean.test.PersistenceContextAccess;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.in;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -42,6 +46,24 @@ public class EbeanSpringModuleTest {
super();
}
@Transactional
@Rollback
@Test
public void testWithRollback() {
// setup
User user = new User();
user.setName("rollback1");
DB.save(user);
// this loads the user into the [transaction scoped] persistence context
User found = DB.find(User.class, user.getOid());
found.setName("mutated");
PersistenceContextAccess.clear();
userService.insideTestRollback(user.getOid());
}
/**
* Test app.
*/
@@ -16,4 +16,6 @@ public interface UserService {
void batchInsert();
void requiresNew();
void insideTestRollback(long oid);
}
@@ -12,6 +12,8 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The Class UserServiceImpl.
*
@@ -28,6 +30,13 @@ public class UserServiceImpl implements UserService, ApplicationContextAware {
@Autowired
private Database ebeanServer;
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
public void insideTestRollback(long oid) {
User found = ebeanServer.find(User.class, oid);
assertThat(found.getName()).isEqualTo("rollback1");
}
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
public void save(User user) {
ebeanServer.save(user);
+9 -9
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
</parent>
<name>ebean test</name>
@@ -33,20 +33,20 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
@@ -135,28 +135,28 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>13.24.0</version>
<version>14.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>13.24.0</version>
<version>14.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
@@ -213,7 +213,7 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.6.0</version>
<version>42.7.2</version>
<exclusions>
<exclusion>
<groupId>org.checkerframework</groupId>
@@ -0,0 +1,59 @@
package io.ebean.test;
import io.ebean.Transaction;
import io.ebean.bean.PersistenceContext;
import io.ebeaninternal.api.SpiTransaction;
/**
* Provides tests access to the persistence context.
* <p>
* Expected to be used with tests that use Spring test {@code @Rollback} {@code @Transactional}.
* These tests have an outer transaction that will rollback. The issue is that test setup code
* is now running in the SAME TRANSACTION as the code under test (main code we are testing) and
* that the Ebean Persistence Context is transaction scoped - so the test setup code can load
* entities into the ebean persistence context during the test setup phase - we SHOULD clear the
* persistence context AFTER the setup phase of the test and BEFORE we run the code under test.
*
* <pre>{@code
*
* @Test
* @Transactional // spring transactional
* @Rollback // spring test rollback
* void myTestWithSpringRollback() {
*
* // Test Setup: this MIGHT load entities into the persistence context
* performTestSetup();
*
* // clear out the persistence context
* PersistenceContextAccess.clear();
*
* // Act
* performActionsWeAreTestingHere();
*
* // Assert
* assertThat(...)
*
* }
*
* }</pre>
*/
public class PersistenceContextAccess {
/**
* Clear the persistence context of the current transaction.
* <p>
* This is expected to be called after test setup phase and before
* the test executes the code we are looking to test - so
* AFTER "setup" and BEFORE "act".
*/
public static void clear() {
Transaction current = Transaction.current();
if (current != null) {
SpiTransaction spiTransaction = (SpiTransaction) current;
PersistenceContext pc = spiTransaction.persistenceContext();
if (pc != null) {
pc.clear();
}
}
}
}
@@ -12,12 +12,20 @@ class ContainerConfigTest {
@Test
void loadFromProperties() {
ContainerConfig containerConfig = new ContainerConfig();
Properties p = new Properties();
p.setProperty("ebean.cluster.active", "true");
p.setProperty("ebean.cluster.serviceName", "a");
p.setProperty("ebean.cluster.namespace", "b");
p.setProperty("ebean.cluster.podName", "c");
p.setProperty("ebean.cluster.port", "42");
assertThat(containerConfig.isActive()).isFalse();
assertThat(containerConfig.getServiceName()).isNull();
assertThat(containerConfig.getNamespace()).isNull();
assertThat(containerConfig.getPodName()).isNull();
assertThat(containerConfig.getPort()).isEqualTo(0);
ContainerConfig containerConfig = new ContainerConfig();
containerConfig.loadFromProperties(p);
assertThat(containerConfig.isActive()).isTrue();
assertThat(containerConfig.getServiceName()).isEqualTo("a");
assertThat(containerConfig.getNamespace()).isEqualTo("b");
assertThat(containerConfig.getPodName()).isEqualTo("c");
assertThat(containerConfig.getPort()).isEqualTo(42);
}
}
@@ -43,7 +43,7 @@ public class WriteJsonDirtyTest {
JsonFactory jsonFactory = new JsonFactory();
JsonGenerator generator = jsonFactory.createGenerator(writer);
WriteJson writeJson = new WriteJson(server, generator, null, null, null, null);
WriteJson writeJson = new WriteJson(server, generator, null, null, null, null, true);
descriptor.jsonWriteDirty(writeJson, entityBean, dirtyProperties);
generator.flush();
@@ -0,0 +1,101 @@
package org.tests.basic;
import io.ebean.DB;
import io.ebean.DataIntegrityException;
import io.ebean.xtest.BaseTestCase;
import org.junit.jupiter.api.Test;
import org.tests.model.json.EBasicJsonList;
import org.tests.model.json.EBasicJsonMap;
import org.tests.model.types.SomeFileBean;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
/**
* @author Roland Praml, FOCONIS AG
*/
public class TestLength extends BaseTestCase {
@Test
void testFileSize() throws IOException {
File f1 = File.createTempFile("testfile", "tmp");
byte[] buf = new byte[1024];
try (FileOutputStream fos = new FileOutputStream(f1)) {
for (int i = 0; i < 100; i++) {
fos.write(buf);
}
}
SomeFileBean sfb1 = new SomeFileBean();
sfb1.setContent(f1);
DB.save(sfb1);
try (FileOutputStream fos = new FileOutputStream(f1)) {
for (int i = 0; i < 101; i++) {
fos.write(buf);
}
}
SomeFileBean sfb2 = new SomeFileBean();
sfb2.setContent(f1);
assertThatThrownBy(() -> DB.save(sfb2)).isInstanceOf(DataIntegrityException.class);
}
/**
* The property 'EBasicJsonMap.content' is annotated with @DbJson(length=5000). So we assume, that we cannot save Json-objects
* where the serialized form exceed that limit and we would expect an error on save.
* The length check works for platforms like h2, as H2 uses a 'varchar(5000)'. So it is impossible to save such long jsons,
* but it won't work for SqlServer, as here 'nvarchar(max)' is used. No validation happens at DB level and you might get very
* large Json objects in your database. This mostly happens unintentionally (programming error, misconfiguration)
* So they are in the database and they cannot be accessed by ebean any more, because there are new limits in Jackson:
* - Max 5 Meg per string in 2.15.0
* - Max 20 Meg per string in 2.15.1
* see https://github.com/FasterXML/jackson-core/issues/1014
*/
@Test
void testLongString() {
// s is so big, that it could not be deserialized by jackson
String s = new String(new char[20_000_001]).replace('\0', 'x');
EBasicJsonMap bean = new EBasicJsonMap();
bean.setName("b1");
bean.setContent(Map.of("string", s));
assertThatThrownBy(() -> {
// we expect, that we can NOT save the bean, this is ensured by the bind validator.
DB.save(bean);
}).isInstanceOf(DataIntegrityException.class);
}
/**
* Tests the UTF8 validation.
*/
@Test
void testUtf8() {
String s = new String(new char[40]).replace('\0', '€');
EBasicJsonList bean = new EBasicJsonList();
bean.setName("b1");
bean.setTags(List.of(s));
if (isDb2() || isOracle()) {
// by default, DB2 && oracle uses bytes in varchar, so an '€' symbol needs 3 bytes
assertThatThrownBy(() -> {
// we expect, that we can NOT save the bean, this is ensured by the bind validator.
DB.save(bean);
}).isInstanceOf(DataIntegrityException.class);
} else {
DB.save(bean);
}
}
}
@@ -0,0 +1,52 @@
package org.tests.json;
import io.ebean.DB;
import io.ebean.DataIntegrityException;
import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.Test;
import org.tests.model.json.EBasicJsonMap;
import java.util.Map;
class TestDbJsonLength {
/**
* The property 'EBasicJsonMap.content' is annotated with @DbJson(length=5000). So we assume, that we cannot save Json-objects
* where the serialized form exceed that limit and we would expect an error on save.
* The length check works for platforms like h2, as H2 uses a 'varchar(5000)'. So it is impossible to save such long jsons,
* but it won't work for SqlServer, as here 'nvarchar(max)' is used. No validation happens at DB level and you might get very
* large Json objects in your database. This mostly happens unintentionally (programming error, misconfiguration)
* So they are in the database and they cannot be accessed by ebean any more, because there are new limits in Jackson:
* - Max 5 Meg per string in 2.15.0
* - Max 20 Meg per string in 2.15.1
* see https://github.com/FasterXML/jackson-core/issues/1014
*/
@Test
void testLongString() {
// s is so big, that it could not be deserialized by jackson
String s = new String(new char[20_000_001]).replace('\0', 'x');
EBasicJsonMap bean = new EBasicJsonMap();
bean.setName("b1");
bean.setContent(Map.of("string", s));
SoftAssertions softly = new SoftAssertions();
softly.assertThatThrownBy(() -> {
DB.save(bean);
}).isInstanceOf(DataIntegrityException.class);
if (bean.getId() != null) {
// we expect, that we could NOT save the bean, but this is not true for sqlServer.
// we will get a javax.persistence.PersistenceException: Error loading on org.tests.model.json.EBasicJsonMap.content
// when we try to load the bean back from DB
DB.find(EBasicJsonMap.class, bean.getId());
}
softly.assertAll();
}
}
@@ -0,0 +1,36 @@
package org.tests.json.include;
import io.ebean.DB;
import io.ebean.FetchPath;
import io.ebean.config.JsonConfig;
import io.ebean.text.PathProperties;
import io.ebean.text.json.JsonWriteOptions;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Contact;
import org.tests.model.basic.ResetBasicData;
import static org.assertj.core.api.Assertions.assertThat;
class TestJsonImplicitLoaded {
@Test
void testToBeanToJson() {
ResetBasicData.reset();
FetchPath path = PathProperties.parse("*");
Contact bean = DB.find(Contact.class).setId(1).apply(path).findOne();
JsonWriteOptions options = new JsonWriteOptions();
options.setInclude(JsonConfig.Include.NON_NULL);
options.setPathProperties(path);
options.setIncludeLoadedImplicit(false);
String asJson = DB.json().toJson(bean, options);
assertThat(asJson).contains("customer\":{\"id\":1}"); // hold only ID
bean.getCustomer().getName(); // lazy-load bean;
asJson = DB.json().toJson(bean, options);
assertThat(asJson).contains("customer\":{\"id\":1}"); // expect the same result
}
}
@@ -18,7 +18,7 @@ public class EBasicJsonMap {
String name;
@DbJson
@DbJson(length = 5000)
Map<String, Object> content;
@OneToMany(mappedBy = "owner", cascade = CascadeType.ALL)
@@ -1,9 +1,7 @@
package org.tests.model.types;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.Version;
import jakarta.persistence.*;
import java.io.File;
@Entity
@@ -18,6 +16,7 @@ public class SomeFileBean {
String name;
@Lob
@Column(length = 100 * 1024) // limit to 100kb
File content;
public Long getId() {
@@ -157,6 +157,7 @@ datasource.oracle.url=jdbc:oracle:thin:@localhost:1521:XE
## set this to use timestamp rather than timestamptz
#ebean.postgres.timestamp=timestamp
ebean.pg.lengthCheck=on
datasource.pg.username=unit
datasource.pg.password=test
datasource.pg.url=jdbc:postgresql://127.0.0.1:6432/unit
@@ -2,4 +2,4 @@ ebean.test.platform=cockroach
ebean.test.dbName=unit
datasource.default=cockroach
#ebean.test.cockroach.version=v21.2.6
ebean.lengthCheck=on
@@ -5,3 +5,4 @@ ebean.test.username=admin
ebean.test.password=admin
datasource.default=db2-11
ebean.db2-11.databasePlatformName=db2luw
ebean.lengthCheck=utf8
@@ -6,3 +6,4 @@ ebean.test.mariadb.version=10.3
ebean.test.mariadb.containerName=ut_mariadb-10-3
ebean.test.mariadb.port=14308
datasource.default=mariadb-103
ebean.lengthCheck=on
@@ -4,3 +4,4 @@ ebean.test.mariadb.version=10.6
ebean.test.mariadb.containerName=ut_mariadb-10-6
ebean.test.mariadb.port=14307
datasource.default=mariadb-106
ebean.lengthCheck=on
@@ -4,3 +4,4 @@ ebean.test.dbName=test_ebean
# note: do not conflict with mariadb port
#ebean.test.mysql.port=4306
datasource.default=mysql-docker
ebean.lengthCheck=on
@@ -1,3 +1,4 @@
ebean.test.platform=oracle
ebean.test.dbName=test_eb
datasource.default=oracle
ebean.lengthCheck=utf8
@@ -2,4 +2,4 @@ ebean.test.platform=postgres
datasource.default=postgres
ebean.test.dbName=unit
ebean.test.postgres.version=15
ebean.lengthCheck=on
@@ -8,3 +8,4 @@ ebean.test.sqlserver.url=jdbc:sqlserver://localhost:9435;databaseName=test_ebean
datasource.default=sqlserver2017
ebean.sqlserver2017.databasePlatformName=sqlserver17
ebean.lengthCheck=on
@@ -7,6 +7,7 @@ ebean.test.sqlserver.port=9434
ebean.test.sqlserver.url=jdbc:sqlserver://localhost:9434;databaseName=test_ebean;sendTimeAsDateTime=false;integratedSecurity=false;trustServerCertificate=true
datasource.default=sqlserver2019
ebean.sqlserver2019.databasePlatformName=sqlserver17
ebean.lengthCheck=on
## A case sensitive collation example:
#ebean.test.sqlserver.collation=LATIN1_GENERAL_100_CI_AS_SC_UTF8
@@ -2,4 +2,4 @@ ebean.test.platform=yugabyte
datasource.default=yugabyte
ebean.test.dbName=unit
ebean.test.yugabyte.version=2.18.0.0-b65
ebean.lengthCheck=on
+49
View File
@@ -0,0 +1,49 @@
# Deploy to Central
```shell
## confirm on master and building
git checkout master
mvn clean verify
## set the appropriate version
mvs
## run tests and package
mvn -T 4 clean package
## deploy
mvn -T 4 deploy -pl '!composites,!platforms' -Pcentral -DskipTests -DskipStagingRepositoryClose=true -DstagingProgressTimeoutMinutes=9
## git commit, git tag, git push --tags
## convert to javax
./jakarta-to-javax.sh
## set javax version
mvs
## deploy javax
mvn -T 4 clean package
mvn -T 4 deploy -pl '!composites,!platforms' -Pcentral -DskipTests -DskipStagingRepositoryClose=true -DstagingProgressTimeoutMinutes=9
## checkout / cleanup
git checkout .
## goto ebean-15x branch
git checkout ebean-15x
## update ebean-15x branch from master and resolve conflicts
git merge master
## resolve conflicts
## git commit, git push
## set 15.x version
mvs
## build and deploy 15.x
mvn -T 4 clean package
mvn -T 4 deploy -pl '!composites,!platforms' -Pcentral -DskipTests -DskipStagingRepositoryClose=true -DstagingProgressTimeoutMinutes=9
```
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
</parent>
<name>kotlin querybean generator</name>
@@ -21,7 +21,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
@@ -35,7 +35,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
@@ -56,14 +56,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
<scope>test</scope>
</dependency>
@@ -2,9 +2,8 @@ package io.ebean.querybean.generator;
interface Constants {
String AT_GENERATED = "@Generated(\"io.ebean.querybean.kotlin-generator\")";
String AT_TYPEQUERYBEAN = "@TypeQueryBean(\"v1\")";
String GENERATED = "io.ebean.typequery.Generated";
String AT_GENERATED = "@io.ebean.typequery.Generated(\"io.ebean.querybean.kotlin-generator\")";
String AT_TYPEQUERYBEAN = "@io.ebean.typequery.TypeQueryBean(\"v1\")";
String MAPPED_SUPERCLASS = "jakarta.persistence.MappedSuperclass";
String DISCRIMINATOR_VALUE = "jakarta.persistence.DiscriminatorValue";
@@ -19,16 +18,9 @@ interface Constants {
String DBJSONB = "io.ebean.annotation.DbJsonB";
String DBNAME = "io.ebean.annotation.DbName";
String TQROOTBEAN = "io.ebean.typequery.TQRootBean";
String TQASSOC = "io.ebean.typequery.TQAssoc";
String TQASSOCBEAN = "io.ebean.typequery.TQAssocBean";
String TQPROPERTY = "io.ebean.typequery.TQProperty";
String TYPEQUERYBEAN = "io.ebean.typequery.TypeQueryBean";
String DATABASE = "io.ebean.Database";
String DB = "io.ebean.DB";
String FETCHGROUP = "io.ebean.FetchGroup";
String QUERY = "io.ebean.Query";
String TRANSACTION = "io.ebean.Transaction";
String MODULEINFO = "io.ebean.config.ModuleInfo";
String METAINF_MANIFEST = "META-INF/ebean-generated-info.mf";
@@ -3,17 +3,7 @@ package io.ebean.querybean.generator;
class KotlinLangAdapter implements LangAdapter {
@Override
public void beginClass(Append writer, String shortName) {
writer.append("class Q%s : TQRootBean<%1$s, Q%1$s> {", shortName).eol();
}
@Override
public void beginAssocClass(Append writer, String shortName, String origShortName) {
// writer.append("class Q%s<R> : TQAssocBean<%s,R> {", shortName, origShortName).eol();
}
@Override
public void alias(Append writer, String shortName) {
public void alias(Append writer, String shortName, String fullName) {
writer.append(" companion object {").eol();
writer.append(" /**").eol();
writer.append(" * shared 'Alias' instance used to provide").eol();
@@ -25,7 +15,7 @@ class KotlinLangAdapter implements LangAdapter {
writer.append(" * Return a query bean used to build a FetchGroup.").eol();
writer.append(" */").eol();
writer.append(" fun forFetchGroup(): Q%s {", shortName).eol();
writer.append(" return Q%s(FetchGroup.queryFor(%s::class.java));", shortName, shortName).eol();
writer.append(" return Q%s(io.ebean.FetchGroup.queryFor(%s::class.java));", shortName, fullName).eol();
writer.append(" }").eol();
writer.append(" }").eol().eol();
}
@@ -59,31 +49,31 @@ class KotlinLangAdapter implements LangAdapter {
}
@Override
public void rootBeanConstructor(Append writer, String shortName, String dbName) {
public void rootBeanConstructor(Append writer, String shortName, String dbName, String fullName) {
String name = (dbName == null) ? "default" : dbName;
writer.append(" /**").eol();
writer.append(" * Construct using the %s Database.", name).eol();
writer.append(" */").eol();
if (dbName == null) {
writer.append(" constructor() : super(%s::class.java)", shortName).eol().eol();
writer.append(" constructor() : super(%s::class.java)", fullName).eol().eol();
} else {
writer.append(" constructor() : super(%s::class.java, DB.byName(\"%s\"))", shortName, dbName).eol().eol();
writer.append(" constructor() : super(%s::class.java, io.ebean.DB.byName(\"%s\"))", fullName, dbName).eol().eol();
}
writer.append(" /**").eol();
writer.append(" * Construct with a given Transaction.", name).eol();
writer.append(" */").eol();
if (dbName == null) {
writer.append(" constructor(transaction: Transaction) : super(%s::class.java, transaction)", shortName).eol().eol();
writer.append(" constructor(transaction: io.ebean.Transaction) : super(%s::class.java, transaction)", fullName).eol().eol();
} else {
writer.append(" constructor(transaction: Transaction) : super(%s::class.java, DB.byName(\"%s\"), transaction)", shortName, dbName).eol().eol();
writer.append(" constructor(transaction: io.ebean.Transaction) : super(%s::class.java, io.ebean.DB.byName(\"%s\"), transaction)", fullName, dbName).eol().eol();
}
writer.eol();
writer.append(" /**").eol();
writer.append(" * Construct with a given Database.").eol();
writer.append(" */").eol();
writer.append(" constructor(database: Database) : super(%s::class.java, database)", shortName).eol().eol();
writer.append(" constructor(database: io.ebean.Database) : super(%s::class.java, database)", fullName).eol().eol();
writer.append(" /**").eol();
writer.append(" * Construct for Alias.").eol();
@@ -93,7 +83,7 @@ class KotlinLangAdapter implements LangAdapter {
writer.append(" /**").eol();
writer.append(" * Private constructor for FetchGroup building.").eol();
writer.append(" */").eol();
writer.append(" private constructor(fetchGroupQuery: Query<%s>) : super(fetchGroupQuery)", shortName).eol();
writer.append(" private constructor(fetchGroupQuery: io.ebean.Query<%s>) : super(fetchGroupQuery)", fullName).eol();
writer.eol();
writer.append(" /** Return a copy of the query. */").eol();
@@ -2,13 +2,10 @@ package io.ebean.querybean.generator;
public interface LangAdapter {
void beginClass(Append writer, String shortName);
void beginAssocClass(Append writer, String shortName, String origShortName);
void alias(Append writer, String shortName, String beanFullName);
void alias(Append writer, String shortName);
void rootBeanConstructor(Append writer, String shortName, String dbName);
void rootBeanConstructor(Append writer, String shortName, String dbName, String beanFullName);
void assocBeanConstructor(Append writer, String shortName);
@@ -91,7 +91,6 @@ class SimpleModuleInfoWriter {
writer.append("import java.util.ArrayList;").eol();
writer.append("import java.util.Collections;").eol();
writer.append("import java.util.List;").eol();
writer.append("import %s;", Constants.GENERATED).eol();
writer.eol();
writer.append("import io.ebean.config.ModuleInfo;").eol();
writer.append("import io.ebean.config.EntityClassRegister;").eol();
@@ -123,22 +123,11 @@ class SimpleQueryBeanWriter {
}
private void gatherPropertyDetails() {
importTypes.add(Constants.GENERATED);
importTypes.add(beanFullName);
importTypes.add(Constants.TQROOTBEAN);
importTypes.add(Constants.TYPEQUERYBEAN);
importTypes.add(Constants.DATABASE);
importTypes.add(Constants.FETCHGROUP);
importTypes.add(Constants.QUERY);
importTypes.add(Constants.TRANSACTION);
if (implementsInterface != null) {
implementsInterfaceFullName = implementsInterface.getQualifiedName().toString();
boolean nested = implementsInterface.getNestingKind().isNested();
implementsInterfaceShortName = Util.shortName(nested, implementsInterfaceFullName);
}
if (dbName != null) {
importTypes.add(Constants.DB);
}
addClassProperties();
}
@@ -230,12 +219,6 @@ class SimpleQueryBeanWriter {
* Prepare the imports for writing assoc bean.
*/
private void prepareAssocBeanImports() {
importTypes.remove(Constants.DB);
importTypes.remove(Constants.TQROOTBEAN);
importTypes.remove(Constants.DATABASE);
importTypes.remove(Constants.FETCHGROUP);
importTypes.remove(Constants.QUERY);
if (embeddable) {
importTypes.add(Constants.TQASSOC);
} else {
@@ -266,7 +249,6 @@ class SimpleQueryBeanWriter {
* Write constructors.
*/
private void writeConstructors() {
if (writingAssocBean) {
writeAssocBeanFetch();
writeAssocBeanConstructor();
@@ -279,7 +261,7 @@ class SimpleQueryBeanWriter {
* Write the constructors for 'root' type query bean.
*/
private void writeRootBeanConstructor() {
lang().rootBeanConstructor(writer, shortName, dbName);
lang().rootBeanConstructor(writer, shortName, dbName, beanFullName);
}
private void writeAssocBeanFetch() {
@@ -315,7 +297,6 @@ class SimpleQueryBeanWriter {
* Write constructor for 'assoc' type query bean.
*/
private void writeAssocBeanConstructor() {
lang().assocBeanConstructor(writer, shortName);
}
@@ -344,11 +325,10 @@ class SimpleQueryBeanWriter {
writer.append(Constants.AT_GENERATED).eol();
writer.append(Constants.AT_TYPEQUERYBEAN).eol();
if (embeddable) {
writer.append("class Q%s<R> : TQAssoc<%s,R> {", shortName, shortInnerName).eol();
writer.append("class Q%s<R> : TQAssoc<%s,R> {", shortName, beanFullName).eol();
} else {
writer.append("class Q%s<R> : TQAssocBean<%s,R,Q%s> {", shortName, shortInnerName, origShortName).eol();
writer.append("class Q%s<R> : TQAssocBean<%s,R,Q%s> {", shortName, beanFullName, origShortName).eol();
}
} else {
writer.append("/**").eol();
writer.append(" * Query bean for %s.", shortName).eol();
@@ -357,7 +337,7 @@ class SimpleQueryBeanWriter {
writer.append(" */").eol();
writer.append(Constants.AT_GENERATED).eol();
writer.append(Constants.AT_TYPEQUERYBEAN).eol();
lang().beginClass(writer, shortName);
writer.append("class Q%s : io.ebean.typequery.TQRootBean<%s, Q%s> {", shortName, beanFullName, shortName).eol();
}
writer.eol();
@@ -365,7 +345,7 @@ class SimpleQueryBeanWriter {
private void writeAlias() {
if (!writingAssocBean) {
lang().alias(writer, shortName);
lang().alias(writer, shortName, beanFullName);
}
}
+14 -14
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,67 +15,67 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hsqldb</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlanywhere</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.0.0</version>
<version>14.0.1</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,7 +15,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.0.0</version>
<version>14.0.1</version>
</dependency>
</dependencies>

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