Compare commits

..
Author SHA1 Message Date
Rob Bygrave 27504a4dae [maven-release-plugin] prepare release ebean-parent-13.10.0 2022-10-14 13:31:10 +13:00
Rob Bygrave 9c64a69b8c Bump to 13.10.0-SNAPSHOT 2022-10-14 13:13:09 +13:00
Rob Bygrave 6c354357ff Update and fix pom versions after merge of older PR 2022-10-14 12:57:45 +13:00
Rob BygraveandGitHub 19bbe6e860 Merge pull request #2828 from ebean-orm/feature/jackson-mapper-module
Extract jackson mapper module
2022-10-14 12:39:43 +13:00
Rob BygraveandGitHub 62adaa7527 Merge pull request #2826 from ebean-orm/feature/json-node-module
Refactor extract ebean-jackson-jsonnode module - support for Jackson JsonNode (into separate module)
2022-10-14 12:39:27 +13:00
Rob Bygrave 9a25fb584c #2855 - @DbArray not allowing null to be persisted, stores empty list instead
Currently, this bug fix needs to be enabled explicitly via ebean.mf with:

allow-nullable-dbarray: true

We will look to enable this bug fix by default shortly noting that some code
will see a behaviour change. We need to publicise it well when we do turn
this on by default.

This bug fix is actually in ebean-agent 13.10.0 and all this change in ebean-core
does is read the new `@DbArray(nullable=false)` attribute [as a new alternative to
using `@NotNull` or `@Column(nullable=false)`]
2022-10-14 11:14:12 +13:00
Rob Bygrave 475f937421 #2858 - Example for entity-field-access 2022-10-14 11:08:49 +13:00
Rob Bygrave 227968ef8e #2857 - @DbArray - slight performance optimisation for empty array 2022-10-14 08:16:43 +13:00
Rob Bygrave 8e02dedf9f #2856 - @DbArray - improve bind logging, non-null arrays auto bind null to [] so improve bind logging to reflect that 2022-10-14 08:14:12 +13:00
Rob Bygrave 5a49041a3b Tidy test UserInterestLiveKey, final with accessors 2022-09-23 13:54:17 +12:00
Rob Bygrave ea341a556d Bump postgresql to 42.5.0 2022-09-23 13:53:45 +12:00
Rob Bygrave 7affd20092 Bump ebean-agent to 13.9.4 2022-09-15 10:31:58 +12:00
Rob Bygrave 9d9960ded2 Bump test-java16 to use io.ebean.tile:enhancement:13.9.4
Plus add a @Transient field in there for the constructor to deal with
2022-09-15 08:41:05 +12:00
Rob Bygrave 62a055ef1f Bump to 13.9.4-SNAPSHOT after release 2022-09-14 11:37:52 +12:00
Rob Bygrave 993607ef4b [maven-release-plugin] prepare for next development iteration 2022-09-14 11:18:25 +12:00
Rob Bygrave 18765b3ac2 [maven-release-plugin] prepare release ebean-parent-13.9.3 2022-09-14 11:18:18 +12:00
Rob Bygrave ea8e195183 Update test-java16 to use updated agent 2022-09-14 11:12:45 +12:00
Rob Bygrave f54c212b67 #2833 - Fix PostgresPlatformProvider plaform sniffing query (Postgres vs Cockroach) 2022-09-14 11:10:10 +12:00
Rob Bygrave 14d11b1c70 Improve tests only - ExtendedServerTest and test-java16 2022-09-11 17:12:02 +12:00
Rob Bygrave 7f5f0f6b8e Extract ebean-jackson-mapper module - fix module-info with requires com.fasterxml.jackson.annotation; 2022-09-08 23:05:16 +12:00
Rob Bygrave 318b22448c Extract ebean-jackson-mapper module - refactor DefaultTypeManager.dbJsonType()
- When detected markerAnnotation (e.g. Jackson annotation) then go directly to createJsonObjectMapperType()
- Simplify for the simple List, Set and Map of Object cases.
2022-09-08 23:01:05 +12:00
Rob Bygrave 610b3f7dc8 Extract ebean-jackson-mapper module - Change checkJacksonAnnotations() to instead use ScalarJsonMapper.markerAnnotation() 2022-09-08 22:38:10 +12:00
Rob Bygrave 7a887d219f Extract ebean-jackson-mapper module - rename DeployBeanObtainJackson -> AnnotatedClassUtil and convert to static method 2022-09-08 22:14:16 +12:00
Rob Bygrave e74e4ba532 Extract ebean-jackson-mapper module - rename ScalarTypeJsonObjectMapper to ScalarJsonJacksonMapper and move 2022-09-08 22:09:10 +12:00
Rob Bygrave d5f753d110 Extract ebean-jackson-mapper module - initial step 2022-09-08 21:39:00 +12:00
Rob Bygrave c53ca6c16e Rename ebean-json-node module to ebean-jackson-jsonnode 2022-09-08 14:53:33 +12:00
Rob Bygrave 5981d313ae Rename ebean-json-node module to ebean-jackson-jsonnode 2022-09-08 14:50:58 +12:00
Rob Bygrave cba3d24df1 Refactor DeployUtil rename methods (change/improve method names) 2022-09-07 22:56:43 +12:00
Rob Bygrave 27beab2980 Refactor internal TypeManager change/improve its method names 2022-09-07 22:53:15 +12:00
Rob Bygrave aeb4b8ed25 Refactor TypeManager - remove unnecessary add() method from interface allowing it to be private 2022-09-07 22:41:56 +12:00
Rob Bygrave edddc935df Update DefaultTypeManager to reuse PostgresHelper.isPostgresCompatible() 2022-09-07 22:38:09 +12:00
Rob Bygrave 5c1b478085 Refactor extract ebean-json-node module - support for Jackson JsonNode (into separate module) 2022-09-07 21:39:36 +12:00
Rob Bygrave 39de9d56db #2825 - DB Migration - create schema migration is repeated unnecessarily 2022-09-07 19:55:43 +12:00
Rob Bygrave 94dbd9d6ad Bump to 13.9.3-SNAPSHOT after release 2022-09-05 19:28:41 +12:00
Rob Bygrave 7c23dd06f8 [maven-release-plugin] prepare for next development iteration 2022-09-05 17:44:35 +12:00
126 changed files with 1154 additions and 613 deletions
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean-clickhouse</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean-cockroach</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean-db2</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean-h2</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean-hana</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean-mariadb</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean-mysql</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean-nuodb</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean-oracle</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean-postgres</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean-sqlite</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean-sqlserver</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean-yugabyte</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+19 -7
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean (all platforms)</name>
@@ -16,19 +16,31 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -41,18 +53,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<artifactId>composites</artifactId>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean api</name>
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<!-- <parent>-->
<!-- <groupId>org.avaje</groupId>-->
@@ -14,7 +14,7 @@
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
<name>ebean autotune</name>
@@ -26,7 +26,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
@@ -55,7 +55,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
+28 -16
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean bom</name>
@@ -89,94 +89,106 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-xml</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-autotune</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>kotlin-querybean-generator</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-redis</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
+10 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<artifactId>ebean-core-type</artifactId>
@@ -16,7 +16,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -26,6 +26,14 @@
<optional>true</optional>
</dependency>
<!-- Provided scope for Postgres JSON/JSONB support -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.4.1</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.avaje</groupId>
<artifactId>junit</artifactId>
@@ -1,5 +1,7 @@
package io.ebeaninternal.server.type;
package io.ebean.core.type;
import io.ebean.annotation.Platform;
import io.ebean.config.dbplatform.DatabasePlatform;
import org.postgresql.util.PGobject;
import java.sql.SQLException;
@@ -9,12 +11,12 @@ public final class PostgresHelper {
/**
* The Postgres JSON DB type.
*/
static final String JSON_TYPE = "json";
public static final String JSON_TYPE = "json";
/**
* The Postgres JSONB DB type.
*/
static final String JSONB_TYPE = "jsonb";
public static final String JSONB_TYPE = "jsonb";
static final String INET_TYPE = "inet";
@@ -31,4 +33,13 @@ public final class PostgresHelper {
pgo.setValue(rawJson);
return pgo;
}
/**
* Return true if the platform is Postgres or compatible like Yugabyte, Cockroach.
*/
public static boolean isPostgresCompatible(DatabasePlatform databasePlatform) {
return databasePlatform.isPlatform(Platform.POSTGRES)
|| databasePlatform.isPlatform(Platform.YUGABYTE)
|| databasePlatform.isPlatform(Platform.COCKROACH);
}
}
@@ -0,0 +1,24 @@
package io.ebean.core.type;
import io.ebean.annotation.MutationDetection;
/**
* Holds the configured mapper and default mutation detection mode to be used.
*/
public interface ScalarJsonManager {
/**
* Return the default mutation detection mode.
*/
MutationDetection mutationDetection();
/**
* Return the object mapper supplied in DatabaseConfig.
*/
Object mapper();
/**
* Return the Postgres type given the jdbc type.
*/
String postgresType(int dbType);
}
@@ -0,0 +1,23 @@
package io.ebean.core.type;
import io.avaje.lang.Nullable;
import java.lang.annotation.Annotation;
/**
* Supports JSON bean properties that use something like Jackson ObjectMapper to convert between
* JSON content and the logical bean property value.
*/
public interface ScalarJsonMapper {
/**
* Return a ScalarType for the given JSON property.
*/
ScalarType<?> createType(ScalarJsonRequest request);
/**
* Return a marker annotation to detect when the JSON mapper should be used explicitly.
*/
@Nullable
<A extends Annotation> Class<A> markerAnnotation();
}
@@ -0,0 +1,67 @@
package io.ebean.core.type;
import io.ebean.annotation.MutationDetection;
/**
* A request to create a ScalarType for a bean property (typically annotated with {@code @DbJson}).
*/
public final class ScalarJsonRequest {
private final ScalarJsonManager manager;
private final int dbType;
private final DocPropertyType docType;
private final Class<?> beanType;
private final MutationDetection mode;
private final String name;
public ScalarJsonRequest(ScalarJsonManager manager, int dbType, DocPropertyType docType, Class<?> beanType, MutationDetection mode, String name) {
this.manager = manager;
this.dbType = dbType;
this.docType = docType;
this.beanType = beanType;
this.mode = mode;
this.name = name;
}
/**
* Return the manager.
*/
public ScalarJsonManager manager() {
return manager;
}
/**
* Return the jdbc type this property maps to (e.g. JSON, JSONB etc).
*/
public int dbType() {
return dbType;
}
/**
* Return the document store docType.
*/
public DocPropertyType docType() {
return docType;
}
/**
* Return the type of the bean that this property belongs to.
*/
public Class<?> beanType() {
return beanType;
}
/**
* Return the mutation detection mode the property should use.
*/
public MutationDetection mode() {
return mode;
}
/**
* Return the property name.
*/
public String name() {
return name;
}
}
@@ -0,0 +1,28 @@
package io.ebean.core.type;
import io.avaje.lang.Nullable;
/**
* A ScalarType that has variations based on the mapped JDBC type (like VARCHAR, CLOB, JSON etc).
*/
public interface ScalarTypeSet<T> {
/**
* The property type these scalar types map to.
*/
Class<?> type();
/**
* Return a default ScalarType to use when no other annotations like {@code @DbJson} are present.
*/
@Nullable
ScalarType<?> defaultType();
/**
* Return the scalarType to use for the given jdbc type.
* <p>
* For example VARCHAR, CLOB, JSON etc.
*/
ScalarType<T> forType(int jdbcType);
}
@@ -0,0 +1,17 @@
package io.ebean.core.type;
import io.avaje.lang.Nullable;
import io.ebean.config.DatabaseConfig;
/**
* Factory to create ScalarTypeSet.
*/
public interface ScalarTypeSetFactory {
/**
* Create the ScalarTypeSet given the config and optional objectMapper.
*/
@Nullable
ScalarTypeSet<?> createTypeSet(DatabaseConfig config, @Nullable Object objectMapper);
}
@@ -4,6 +4,7 @@ module io.ebean.core.type {
requires transitive java.sql;
requires transitive io.ebean.api;
requires static org.postgresql.jdbc;
requires static com.fasterxml.jackson.core;
+9 -9
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<artifactId>ebean-core</artifactId>
@@ -15,14 +15,14 @@
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -46,13 +46,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -135,7 +135,7 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.4.1</version>
<version>42.5.0</version>
<optional>true</optional>
</dependency>
@@ -143,21 +143,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
@@ -145,7 +145,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
this.dbIdentity = config.getDatabasePlatform().dbIdentity();
this.deplyInherit = config.getDeployInherit();
this.deployUtil = config.getDeployUtil();
this.typeManager = deployUtil.getTypeManager();
this.typeManager = deployUtil.typeManager();
this.beanManagerFactory = new BeanManagerFactory(config.getDatabasePlatform());
this.beanLifecycleAdapterFactory = new BeanLifecycleAdapterFactory(this.config);
this.persistControllerManager = new PersistControllerManager(bootupClasses);
@@ -184,12 +184,12 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
@Override
public ScalarType<?> scalarType(String cast) {
return typeManager.getScalarType(cast);
return typeManager.type(cast);
}
@Override
public ScalarType<?> scalarType(int jdbcType) {
return typeManager.getScalarType(jdbcType);
return typeManager.type(jdbcType);
}
/**
@@ -884,7 +884,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
private void makeOrderColumn(DeployBeanPropertyAssocMany<?> oneToMany) {
DeployBeanDescriptor<?> targetDesc = targetDescriptor(oneToMany);
DeployOrderColumn orderColumn = oneToMany.getOrderColumn();
final ScalarType<?> scalarType = typeManager.getScalarType(Integer.class);
final ScalarType<?> scalarType = typeManager.type(Integer.class);
DeployBeanProperty orderProperty = new DeployBeanProperty(targetDesc, Integer.class, scalarType, null);
orderProperty.setName(DeployOrderColumn.LOGICAL_NAME);
orderProperty.setDbColumn(orderColumn.getName());
@@ -927,6 +927,10 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
return alreadyDirty || value != null && scalarType.isDirty(value);
}
public boolean isArrayType() {
return scalarType instanceof ScalarTypeArray;
}
/**
* Return the scalarType.
*/
@@ -152,7 +152,6 @@ public class DeployBeanDescriptor<T> {
private DocStoreMode docStoreDelete;
private DeployBeanProperty idProperty;
private TableJoin primaryKeyJoin;
private Object jacksonAnnotatedClass;
/**
* Construct the BeanDescriptor.
@@ -1130,14 +1129,4 @@ public class DeployBeanDescriptor<T> {
}
}
/**
* Returns the jackson annotated class, if jackson is present.
*/
@SuppressWarnings("unchecked")
Object /*AnnotatedClass*/ getJacksonAnnotatedClass() {
if (jacksonAnnotatedClass == null) {
jacksonAnnotatedClass = new DeployBeanObtainJackson(config, beanType).obtain();
}
return jacksonAnnotatedClass;
}
}
@@ -1042,20 +1042,6 @@ public class DeployBeanProperty {
this.elementProperty = true;
}
/**
* Returns the jackson annotated field, if jackson is present.
*/
public Object /*AnnotatedField*/ getJacksonField() {
com.fasterxml.jackson.databind.introspect.AnnotatedClass jac =
(com.fasterxml.jackson.databind.introspect.AnnotatedClass) getDesc().getJacksonAnnotatedClass();
for (com.fasterxml.jackson.databind.introspect.AnnotatedField candidate : jac.fields()) {
if (candidate.getName().equals(getName())) {
return candidate;
}
}
return null;
}
public void initMetaAnnotations(Set<Class<?>> metaAnnotationsFilter) {
metaAnnotations = AnnotationUtil.metaFindAllFor(field, metaAnnotationsFilter);
}
@@ -222,7 +222,7 @@ final class AnnotationAssocManys extends AnnotationAssoc {
dbKeyColumn = mapKeyColumn.name();
}
ScalarType<?> keyScalarType = util.getTypeManager().getScalarType(prop.getMapKeyType());
ScalarType<?> keyScalarType = util.typeManager().type(prop.getMapKeyType());
DeployBeanProperty keyProp = new DeployBeanProperty(elementDescriptor, elementType, keyScalarType, null);
setElementProperty(keyProp, "key", dbKeyColumn, sortOrder++);
@@ -234,10 +234,10 @@ final class AnnotationAssocManys extends AnnotationAssoc {
}
}
ScalarType<?> valueScalarType = util.getTypeManager().getScalarType(elementType);
ScalarType<?> valueScalarType = util.typeManager().type(elementType);
if (valueScalarType == null && elementType.isEnum()) {
Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>)elementType;
valueScalarType = util.getTypeManager().createEnumScalarType(enumClass, EnumType.STRING);
valueScalarType = util.typeManager().enumType(enumClass, EnumType.STRING);
}
boolean scalar = true;
@@ -52,9 +52,9 @@ abstract class AnnotationBase {
AnnotationBase(DeployUtil util) {
this.util = util;
this.databasePlatform = util.getDbPlatform();
this.databasePlatform = util.dbPlatform();
this.platform = databasePlatform.platform();
this.namingConvention = util.getNamingConvention();
this.namingConvention = util.namingConvention();
}
/**
@@ -301,7 +301,7 @@ final class AnnotationFields extends AnnotationParser {
private void initEncrypt(DeployBeanProperty prop) {
if (!prop.isTransient()) {
EncryptDeploy encryptDeploy = util.getEncryptDeploy(info.getDescriptor().getBaseTableFull(), prop.getDbColumn());
EncryptDeploy encryptDeploy = util.encryptDeploy(info.getDescriptor().getBaseTableFull(), prop.getDbColumn());
if (encryptDeploy == null || encryptDeploy.getMode() == Mode.MODE_ANNOTATION) {
Encrypted encrypted = get(prop, Encrypted.class);
if (encrypted != null) {
@@ -398,7 +398,7 @@ final class AnnotationFields extends AnnotationParser {
return;
}
if (dbEncString) {
DbEncrypt dbEncrypt = util.getDbPlatform().dbEncrypt();
DbEncrypt dbEncrypt = util.dbPlatform().dbEncrypt();
if (dbEncrypt != null) {
// check if we have a DB encryption function for this type
int jdbcType = prop.getScalarType().jdbcType();
@@ -427,7 +427,7 @@ final class AnnotationFields extends AnnotationParser {
private ScalarTypeBytesBase getDbEncryptType(DeployBeanProperty prop) {
int dbType = prop.isLob() ? Types.BLOB : Types.VARBINARY;
return (ScalarTypeBytesBase) util.getTypeManager().getScalarType(dbType);
return (ScalarTypeBytesBase) util.typeManager().type(dbType);
}
private DataEncryptSupport createDataEncryptSupport(DeployBeanProperty prop) {
@@ -108,7 +108,7 @@ public final class DeployCreateProperties {
@SuppressWarnings({"unchecked"})
private DeployBeanProperty createManyType(DeployBeanDescriptor<?> desc, Class<?> targetType, ManyType manyType) {
try {
ScalarType<?> scalarType = typeManager.getScalarType(targetType);
ScalarType<?> scalarType = typeManager.type(targetType);
if (scalarType != null) {
return new DeployBeanPropertySimpleCollection(desc, targetType, manyType);
}
@@ -141,7 +141,7 @@ public final class DeployCreateProperties {
if (propertyType.isEnum() || propertyType.isPrimitive()) {
return new DeployBeanProperty(desc, propertyType, null, null);
}
ScalarType<?> scalarType = typeManager.getScalarType(propertyType);
ScalarType<?> scalarType = typeManager.type(propertyType);
if (scalarType != null) {
return new DeployBeanProperty(desc, propertyType, scalarType, null);
}
@@ -60,15 +60,15 @@ public final class DeployUtil {
this.useValidationNotNull = config.isUseValidationNotNull();
}
public TypeManager getTypeManager() {
public TypeManager typeManager() {
return typeManager;
}
public DatabasePlatform getDbPlatform() {
public DatabasePlatform dbPlatform() {
return dbPlatform;
}
public NamingConvention getNamingConvention() {
public NamingConvention namingConvention() {
return namingConvention;
}
@@ -82,7 +82,7 @@ public final class DeployUtil {
}
}
EncryptDeploy getEncryptDeploy(TableName table, String column) {
EncryptDeploy encryptDeploy(TableName table, String column) {
if (encryptDeployManager == null) {
return EncryptDeploy.ANNOTATION;
}
@@ -102,7 +102,7 @@ public final class DeployUtil {
try {
Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) enumType;
EnumType type = enumerated != null ? enumerated.value() : null;
ScalarType<?> scalarType = typeManager.createEnumScalarType(enumClass, type);
ScalarType<?> scalarType = typeManager.enumType(enumClass, type);
prop.setScalarType(scalarType);
prop.setDbType(scalarType.jdbcType());
} catch (IllegalStateException e) {
@@ -123,7 +123,7 @@ public final class DeployUtil {
// this will be an Enum type...
return;
}
ScalarType<?> scalarType = getScalarType(property);
ScalarType<?> scalarType = scalarType(property);
if (scalarType != null) {
// set the jdbc type this maps to
property.setDbType(scalarType.jdbcType());
@@ -132,12 +132,12 @@ public final class DeployUtil {
}
}
private ScalarType<?> getScalarType(DeployBeanProperty property) {
private ScalarType<?> scalarType(DeployBeanProperty property) {
// Note that Temporal types already have dbType
// set via annotations
Class<?> propType = property.getPropertyType();
try {
ScalarType<?> scalarType = typeManager.getScalarType(propType, property.getDbType());
ScalarType<?> scalarType = typeManager.type(propType, property.getDbType());
if (scalarType != null || property.isTransient()) {
return scalarType;
}
@@ -155,7 +155,7 @@ public final class DeployUtil {
* Map to Postgres HSTORE type (with fallback to JSON storage in VARCHAR).
*/
void setDbMap(DeployBeanProperty prop, DbMap dbMap) {
ScalarType<?> scalarType = typeManager.getDbMapScalarType();
ScalarType<?> scalarType = typeManager.dbMapType();
int dbType = scalarType.jdbcType();
prop.setDbType(dbType);
prop.setScalarType(scalarType);
@@ -171,8 +171,13 @@ public final class DeployUtil {
* Set the DbArray type (effectively Postgres only).
*/
void setDbArray(DeployBeanProperty prop, DbArray dbArray) {
if (!dbArray.nullable()) {
// Non-nullable ScalarTypeArray's will auto bind null to empty array, we need to
// set nullable(false) before the ScalarTypeArray is determined and assigned
prop.setNullable(false);
}
Class<?> type = prop.getPropertyType();
ScalarType<?> scalarType = typeManager.getArrayScalarType(type, prop.getGenericType(), prop.isNullable());
ScalarType<?> scalarType = typeManager.dbArrayType(type, prop.getGenericType(), prop.isNullable());
if (scalarType == null) {
throw new RuntimeException("No ScalarType for @DbArray type for " + prop.getFullBeanName());
}
@@ -193,7 +198,7 @@ public final class DeployUtil {
}
void setDbJsonType(DeployBeanProperty prop, DbJson dbJsonType) {
int dbType = getDbJsonStorage(dbJsonType.storage());
int dbType = dbJsonStorage(dbJsonType.storage());
setDbJsonType(prop, dbType, dbJsonType.length(), dbJsonType.mutationDetection());
}
@@ -204,7 +209,7 @@ public final class DeployUtil {
private void setDbJsonType(DeployBeanProperty prop, int dbType, int dbLength, MutationDetection mutationDetection) {
prop.setDbType(dbType);
prop.setMutationDetection(mutationDetection);
ScalarType<?> scalarType = typeManager.getJsonScalarType(prop, dbType, dbLength);
ScalarType<?> scalarType = typeManager.dbJsonType(prop, dbType, dbLength);
if (scalarType == null) {
throw new RuntimeException("No ScalarType for JSON property " + prop + " dbType:" + dbType);
}
@@ -219,7 +224,7 @@ public final class DeployUtil {
/**
* Return the JDBC type for the JSON storage type.
*/
private int getDbJsonStorage(DbJsonType dbJsonType) {
private int dbJsonStorage(DbJsonType dbJsonType) {
switch (dbJsonType) {
case JSONB:
return DbPlatformType.JSONB;
@@ -248,7 +253,7 @@ public final class DeployUtil {
// this also sets the lob flag on DeployBeanProperty
int lobType = isClobType(type) ? dbCLOBType : dbBLOBType;
scalarType = typeManager.getScalarType(type, lobType);
scalarType = typeManager.type(type, lobType);
if (scalarType == null) {
// this should never occur actually
throw new RuntimeException("No ScalarType for LOB type " + type + " dbType:" + lobType);
@@ -21,7 +21,7 @@ final class DtoMetaConstructor {
this.types = constructor.getParameterTypes();
this.scalarTypes = new ScalarType[types.length];
for (int i = 0; i < types.length; i++) {
scalarTypes[i] = typeManager.getScalarType(types[i]);
scalarTypes[i] = typeManager.type(types[i]);
}
this.handle = LOOKUP.findConstructor(someClass, typeFor(types));
}
@@ -25,7 +25,7 @@ final class DtoMetaProperty implements DtoReadSet {
this.name = name;
if (writeMethod != null) {
this.setter = lookupMethodHandle(dtoType, writeMethod);
this.scalarType = typeManager.getScalarType(propertyType(writeMethod), propertyClass(writeMethod));
this.scalarType = typeManager.type(propertyType(writeMethod), propertyClass(writeMethod));
} else {
this.scalarType = null;
this.setter = null;
@@ -36,7 +36,7 @@ public final class DJsonScalar {
gen.writeRaw(']');
} else {
ScalarType scalarType = typeManager.getScalarType(value.getClass());
ScalarType scalarType = typeManager.type(value.getClass());
if (scalarType == null) {
throw new IllegalArgumentException("unhandled type " + value.getClass());
}
@@ -2,6 +2,7 @@ package io.ebeaninternal.server.persist;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.core.type.DataReader;
import io.ebean.core.type.PostgresHelper;
import io.ebean.core.type.ScalarType;
import io.ebeaninternal.api.BindParams;
import io.ebeaninternal.api.CoreLog;
@@ -37,7 +38,7 @@ public final class Binder {
public Binder(TypeManager typeManager, SpiLogManager logManager, int asOfBindCount, boolean asOfStandardsBased,
DbExpressionHandler dbExpressionHandler, DataTimeZone dataTimeZone, MultiValueBind multiValueBind) {
this.typeManager = typeManager;
this.geoTypeBinder = typeManager.getGeoTypeBinder();
this.geoTypeBinder = typeManager.geoTypeBinder();
this.asOfBindCount = asOfBindCount;
this.asOfStandardsBased = asOfStandardsBased;
this.dbExpressionHandler = dbExpressionHandler;
@@ -153,7 +154,7 @@ public final class Binder {
}
public ScalarType<?> getScalarType(Class<?> clazz) {
ScalarType<?> type = typeManager.getScalarType(clazz);
ScalarType<?> type = typeManager.type(clazz);
if (type == null) {
throw new PersistenceException("No ScalarType registered for " + clazz);
}
@@ -217,6 +217,8 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
}
if (prop.isLob()) {
bindLog.append("[LOB]");
} else if (value == null && !prop.isNullable() && prop.isArrayType()) {
bindLog.append("[]"); // null bound as empty array
} else {
String sv = String.valueOf(value);
if (sv.length() > 50) {
@@ -1,6 +1,5 @@
package io.ebeaninternal.server.type;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.ebean.annotation.*;
import io.ebean.config.DatabaseConfig;
@@ -9,9 +8,7 @@ import io.ebean.config.PlatformConfig;
import io.ebean.config.ScalarTypeConverter;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.core.type.DocPropertyType;
import io.ebean.core.type.ExtraTypeFactory;
import io.ebean.core.type.ScalarType;
import io.ebean.core.type.*;
import io.ebean.types.Cidr;
import io.ebean.types.Inet;
import io.ebean.util.AnnotationUtil;
@@ -40,6 +37,7 @@ import java.time.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static io.ebean.core.type.PostgresHelper.isPostgresCompatible;
import static java.lang.System.Logger.Level.*;
/**
@@ -51,6 +49,7 @@ public final class DefaultTypeManager implements TypeManager {
private static final System.Logger log = CoreLog.internal;
private final Map<Class<?>, ScalarTypeSet<?>> typeSets = new HashMap<>();
private final ConcurrentHashMap<Class<?>, ScalarType<?>> typeMap;
private final ConcurrentHashMap<Integer, ScalarType<?>> nativeMap;
private final ConcurrentHashMap<String, ScalarType<?>> logicalMap;
@@ -66,36 +65,14 @@ public final class DefaultTypeManager implements TypeManager {
private final Object objectMapper;
private final boolean objectMapperPresent;
private final boolean postgres;
private final TypeJsonManager jsonManager;
private final ScalarJsonManager jsonManager;
private final boolean offlineMigrationGeneration;
private final EnumType defaultEnumType;
private final DatabasePlatform databasePlatform;
// OPTIONAL ScalarTypes registered if Jackson/JsonNode is in the classpath
/**
* Jackson's JsonNode storage to Clob.
*/
private ScalarType<?> jsonNodeClob;
/**
* Jackson's JsonNode storage to Blob.
*/
private ScalarType<?> jsonNodeBlob;
/**
* Jackson's JsonNode storage to Varchar.
*/
private ScalarType<?> jsonNodeVarchar;
/**
* Jackson's JsonNode storage to Postgres JSON or Clob.
*/
private ScalarType<?> jsonNodeJson;
/**
* Jackson's JsonNode storage to Postgres JSONB or Clob.
*/
private ScalarType<?> jsonNodeJsonb;
private final PlatformArrayTypeFactory arrayTypeListFactory;
private final PlatformArrayTypeFactory arrayTypeSetFactory;
private final ScalarJsonMapper jsonMapper;
private GeoTypeBinder geoTypeBinder;
/**
@@ -118,9 +95,11 @@ public final class DefaultTypeManager implements TypeManager {
this.offlineMigrationGeneration = DbOffline.isGenerateMigration();
this.defaultEnumType = config.getDefaultEnumType();
ServiceLoader<ScalarJsonMapper> mappers = ServiceLoader.load(ScalarJsonMapper.class);
jsonMapper = mappers.findFirst().orElse(null);
initialiseStandard(config);
initialiseJavaTimeTypes(config);
initialiseJacksonTypes();
loadTypesFromProviders(config, objectMapper);
loadGeoTypeBinder(config);
@@ -160,22 +139,21 @@ public final class DefaultTypeManager implements TypeManager {
* Load custom scalar types registered via ExtraTypeFactory and ServiceLoader.
*/
private void loadTypesFromProviders(DatabaseConfig config, Object objectMapper) {
ServiceLoader<ExtraTypeFactory> factories = ServiceLoader.load(ExtraTypeFactory.class);
Iterator<ExtraTypeFactory> iterator = factories.iterator();
if (iterator.hasNext()) {
// use the cacheFactory (via classpath service loader)
ExtraTypeFactory plugin = iterator.next();
List<? extends ScalarType<?>> types = plugin.createTypes(config, objectMapper);
for (ScalarType<?> type : types) {
for (ExtraTypeFactory plugin : ServiceLoader.load(ExtraTypeFactory.class)) {
for (ScalarType<?> type : plugin.createTypes(config, objectMapper)) {
add(type);
}
}
}
private boolean isPostgresCompatible(DatabasePlatform databasePlatform) {
return databasePlatform.isPlatform(Platform.POSTGRES)
|| databasePlatform.isPlatform(Platform.YUGABYTE)
|| databasePlatform.isPlatform(Platform.COCKROACH);
for (ScalarTypeSetFactory factory : ServiceLoader.load(ScalarTypeSetFactory.class)) {
ScalarTypeSet<?> typeSet = factory.createTypeSet(config, objectMapper);
if (typeSet != null) {
typeSets.put(typeSet.type(), typeSet);
ScalarType<?> defaultType = typeSet.defaultType();
if (defaultType != null) {
typeMap.put(typeSet.type(), defaultType);
}
}
}
}
private boolean hstoreSupport() {
@@ -185,8 +163,7 @@ public final class DefaultTypeManager implements TypeManager {
/**
* Register a custom ScalarType.
*/
@Override
public void add(ScalarType<?> scalarType) {
private void add(ScalarType<?> scalarType) {
typeMap.put(scalarType.type(), scalarType);
logAdd(scalarType);
}
@@ -198,7 +175,7 @@ public final class DefaultTypeManager implements TypeManager {
}
@Override
public ScalarType<?> getScalarType(String cast) {
public ScalarType<?> type(String cast) {
return logicalMap.get(cast);
}
@@ -206,27 +183,27 @@ public final class DefaultTypeManager implements TypeManager {
* Return the ScalarType for the given jdbc type as per java.sql.Types.
*/
@Override
public ScalarType<?> getScalarType(int jdbcType) {
public ScalarType<?> type(int jdbcType) {
return nativeMap.get(jdbcType);
}
@Override
public ScalarType<?> getScalarType(Type propertyType, Class<?> propertyClass) {
public ScalarType<?> type(Type propertyType, Class<?> propertyClass) {
if (propertyType instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType)propertyType;
ParameterizedType pt = (ParameterizedType) propertyType;
Type rawType = pt.getRawType();
if (List.class == rawType || Set.class == rawType) {
return getArrayScalarType((Class<?>)rawType, propertyType, true);
return dbArrayType((Class<?>) rawType, propertyType, true);
}
}
return getScalarType(propertyClass);
return type(propertyClass);
}
/**
* This can return null if no matching ScalarType is found.
*/
@Override
public ScalarType<?> getScalarType(Class<?> type) {
public ScalarType<?> type(Class<?> type) {
ScalarType<?> found = typeMap.get(type);
if (found == null) {
if (type.getName().equals("org.joda.time.LocalTime")) {
@@ -260,7 +237,7 @@ public final class DefaultTypeManager implements TypeManager {
return found;
}
// second step - loop through interfaces of this type
for (Class<?> iface: parent.getInterfaces()) {
for (Class<?> iface : parent.getInterfaces()) {
found = checkInheritedTypes(iface);
if (found != null && found != ScalarTypeNotFound.INSTANCE) {
typeMap.put(type, found); // store type for next lookup
@@ -274,37 +251,37 @@ public final class DefaultTypeManager implements TypeManager {
}
@Override
public GeoTypeBinder getGeoTypeBinder() {
public GeoTypeBinder geoTypeBinder() {
return geoTypeBinder;
}
@Override
public ScalarType<?> getDbMapScalarType() {
public ScalarType<?> dbMapType() {
return hstoreSupport() ? hstoreType : ScalarTypeJsonMap.typeFor(false, Types.VARCHAR, false);
}
@Override
public ScalarType<?> getArrayScalarType(Class<?> type, Type genericType, boolean nullable) {
Type valueType = getValueType(genericType);
public ScalarType<?> dbArrayType(Class<?> type, Type genericType, boolean nullable) {
Type valueType = valueType(genericType);
if (type.equals(List.class)) {
return getArrayScalarTypeList(valueType, nullable);
return dbArrayTypeList(valueType, nullable);
} else if (type.equals(Set.class)) {
return getArrayScalarTypeSet(valueType, nullable);
return dbArrayTypeSet(valueType, nullable);
} else {
throw new IllegalStateException("@DbArray does not support type " + type);
}
}
private ScalarType<?> getArrayScalarTypeSet(Type valueType, boolean nullable) {
private ScalarType<?> dbArrayTypeSet(Type valueType, boolean nullable) {
if (isEnumType(valueType)) {
return arrayTypeSetFactory.typeForEnum(createEnumScalarType(asEnumClass(valueType), null), nullable);
return arrayTypeSetFactory.typeForEnum(enumType(asEnumClass(valueType), null), nullable);
}
return arrayTypeSetFactory.typeFor(valueType, nullable);
}
private ScalarType<?> getArrayScalarTypeList(Type valueType, boolean nullable) {
private ScalarType<?> dbArrayTypeList(Type valueType, boolean nullable) {
if (isEnumType(valueType)) {
return arrayTypeListFactory.typeForEnum(createEnumScalarType(asEnumClass(valueType), null), nullable);
return arrayTypeListFactory.typeForEnum(enumType(asEnumClass(valueType), null), nullable);
}
return arrayTypeListFactory.typeFor(valueType, nullable);
}
@@ -318,67 +295,50 @@ public final class DefaultTypeManager implements TypeManager {
}
@Override
public ScalarType<?> getJsonScalarType(DeployBeanProperty prop, int dbType, int dbLength) {
public ScalarType<?> dbJsonType(DeployBeanProperty prop, int dbType, int dbLength) {
Class<?> type = prop.getPropertyType();
Type genericType = prop.getGenericType();
boolean hasJacksonAnnotations = objectMapperPresent && checkJacksonAnnotations(prop);
if (type.equals(String.class)) {
return ScalarTypeJsonString.typeFor(postgres, dbType);
}
if (type.equals(List.class)) {
DocPropertyType docType = getDocType(genericType);
if (!hasJacksonAnnotations && isValueTypeSimple(genericType)) {
return ScalarTypeJsonList.typeFor(postgres, dbType, docType, prop.isNullable(), jsonManager.keepSource(prop));
} else {
return createJsonObjectMapperType(prop, dbType, docType);
if (jsonMapper != null) {
var markerAnnotation = jsonMapper.markerAnnotation();
if (markerAnnotation != null && !prop.getMetaAnnotations(markerAnnotation).isEmpty()) {
return createJsonObjectMapperType(prop, dbType, docPropertyType(prop, type));
}
}
if (type.equals(Set.class)) {
DocPropertyType docType = getDocType(genericType);
if (!hasJacksonAnnotations && isValueTypeSimple(genericType)) {
return ScalarTypeJsonSet.typeFor(postgres, dbType, docType, prop.isNullable(), jsonManager.keepSource(prop));
} else {
return createJsonObjectMapperType(prop, dbType, docType);
}
Type genericType = prop.getGenericType();
if (type.equals(List.class) && isValueTypeSimple(genericType)) {
return ScalarTypeJsonList.typeFor(postgres, dbType, docType(genericType), prop.isNullable(), keepSource(prop));
}
if (type.equals(Map.class)) {
if (!hasJacksonAnnotations && isMapValueTypeObject(genericType)) {
return ScalarTypeJsonMap.typeFor(postgres, dbType, jsonManager.keepSource(prop));
} else {
return createJsonObjectMapperType(prop, dbType, DocPropertyType.OBJECT);
}
if (type.equals(Set.class) && isValueTypeSimple(genericType)) {
return ScalarTypeJsonSet.typeFor(postgres, dbType, docType(genericType), prop.isNullable(), keepSource(prop));
}
if (type.equals(Map.class) && isMapValueTypeObject(genericType)) {
return ScalarTypeJsonMap.typeFor(postgres, dbType, keepSource(prop));
}
if (objectMapperPresent && prop.getMutationDetection() == MutationDetection.DEFAULT) {
if (type.equals(JsonNode.class)) {
switch (dbType) {
case Types.VARCHAR:
return jsonNodeVarchar;
case Types.BLOB:
return jsonNodeBlob;
case Types.CLOB:
return jsonNodeClob;
case DbPlatformType.JSONB:
return jsonNodeJsonb;
default:
return jsonNodeJson;
}
ScalarTypeSet<?> typeSet = typeSets.get(type);
if (typeSet != null) {
return typeSet.forType(dbType);
}
}
return createJsonObjectMapperType(prop, dbType, DocPropertyType.OBJECT);
}
/**
* Returns TRUE, if there is any jackson annotation on that property. All jackson annotations
* are annotated with the &#64;JacksonAnnotation meta annotation. So detection is easy.
*/
private boolean checkJacksonAnnotations(DeployBeanProperty prop) {
return prop.getMetaAnnotation(com.fasterxml.jackson.annotation.JacksonAnnotation.class) != null;
private boolean keepSource(DeployBeanProperty prop) {
if (prop.getMutationDetection() == MutationDetection.DEFAULT) {
prop.setMutationDetection(jsonManager.mutationDetection());
}
return prop.getMutationDetection() == MutationDetection.SOURCE;
}
private DocPropertyType getDocType(Type genericType) {
private DocPropertyType docPropertyType(DeployBeanProperty prop, Class<?> type) {
return type.equals(List.class) || type.equals(Set.class) ? docType(prop.getGenericType()) : DocPropertyType.OBJECT;
}
private DocPropertyType docType(Type genericType) {
if (genericType instanceof Class<?>) {
ScalarType<?> found = getScalarType((Class<?>)genericType);
ScalarType<?> found = type((Class<?>) genericType);
if (found != null) {
return found.docType();
}
@@ -394,7 +354,7 @@ public final class DefaultTypeManager implements TypeManager {
return String.class.equals(typeArg) || Long.class.equals(typeArg);
}
private Type getValueType(Type collectionType) {
private Type valueType(Type collectionType) {
return TypeReflectHelper.getValueType(collectionType);
}
@@ -407,11 +367,14 @@ public final class DefaultTypeManager implements TypeManager {
}
private ScalarType<?> createJsonObjectMapperType(DeployBeanProperty prop, int dbType, DocPropertyType docType) {
Class<?> type = prop.getPropertyType();
if (objectMapper == null) {
throw new IllegalArgumentException("Type [" + type + "] unsupported for @DbJson mapping - Jackson ObjectMapper not present");
if (jsonMapper == null) {
throw new IllegalArgumentException("Unsupported @DbJson mapping - Jackson ObjectMapper not present for " + prop);
}
return ScalarTypeJsonObjectMapper.createTypeFor(jsonManager, prop, dbType, docType);
if (MutationDetection.DEFAULT == prop.getMutationDetection()) {
prop.setMutationDetection(jsonManager.mutationDetection());
}
var req = new ScalarJsonRequest(jsonManager, dbType, docType, prop.getDesc().getBeanType(), prop.getMutationDetection(), prop.getName());
return jsonMapper.createType(req);
}
/**
@@ -421,7 +384,7 @@ public final class DefaultTypeManager implements TypeManager {
* different jdbcTypes in a single system.
*/
@Override
public ScalarType<?> getScalarType(Class<?> type, int jdbcType) {
public ScalarType<?> type(Class<?> type, int jdbcType) {
// File is a special Lob so check for that first
if (File.class.equals(type)) {
return fileType;
@@ -430,13 +393,13 @@ public final class DefaultTypeManager implements TypeManager {
// check for Clob, LongVarchar etc ...
// the reason being that String maps to multiple jdbc types
// varchar, clob, longVarchar.
ScalarType<?> scalarType = getLobTypes(jdbcType);
ScalarType<?> scalarType = lobTypes(jdbcType);
if (scalarType != null) {
// it is a specific Lob type...
return scalarType;
}
scalarType = getScalarType(type);
scalarType = type(type);
if (scalarType != null) {
if (jdbcType == 0 || scalarType.jdbcType() == jdbcType) {
// matching type
@@ -462,8 +425,8 @@ public final class DefaultTypeManager implements TypeManager {
* types - like String - Varchar, LongVarchar, Clob. For this reason I check
* for the specific Lob types first before looking for a matching type.
*/
private ScalarType<?> getLobTypes(int jdbcType) {
return getScalarType(jdbcType);
private ScalarType<?> lobTypes(int jdbcType) {
return type(jdbcType);
}
/**
@@ -507,7 +470,7 @@ public final class DefaultTypeManager implements TypeManager {
* <p>
* Return null if the EnumValue annotations are not present/used.
*/
private ScalarTypeEnum<?> createEnumScalarType2(Class<?> enumType) {
private ScalarTypeEnum<?> enumTypeEnumValue(Class<?> enumType) {
boolean integerType = true;
Map<String, String> nameValueMap = new LinkedHashMap<>();
for (Field field : enumType.getDeclaredFields()) {
@@ -536,8 +499,8 @@ public final class DefaultTypeManager implements TypeManager {
* much shorter codes used in the DB.
*/
@Override
public ScalarType<?> createEnumScalarType(Class<? extends Enum<?>> enumType, EnumType type) {
ScalarType<?> scalarType = getScalarType(enumType);
public ScalarType<?> enumType(Class<? extends Enum<?>> enumType, EnumType type) {
ScalarType<?> scalarType = type(enumType);
if (scalarType instanceof ScalarTypeWrapper) {
// no override or further mapping required
return scalarType;
@@ -549,16 +512,16 @@ public final class DefaultTypeManager implements TypeManager {
}
return scalarEnum;
}
scalarEnum = createEnumScalarTypePerExtentions(enumType);
scalarEnum = enumTypePerExtensions(enumType);
if (scalarEnum == null) {
// use JPA normal Enum type (without mapping)
scalarEnum = createEnumScalarTypePerSpec(enumType, type);
scalarEnum = enumTypePerSpec(enumType, type);
}
add(scalarEnum);
return scalarEnum;
}
private ScalarTypeEnum<?> createEnumScalarTypePerSpec(Class<?> enumType, EnumType type) {
private ScalarTypeEnum<?> enumTypePerSpec(Class<?> enumType, EnumType type) {
if (type == null) {
if (defaultEnumType == EnumType.ORDINAL) {
return new ScalarTypeEnumStandard.OrdinalEnum(enumType);
@@ -572,16 +535,16 @@ public final class DefaultTypeManager implements TypeManager {
}
}
private ScalarTypeEnum<?> createEnumScalarTypePerExtentions(Class<? extends Enum<?>> enumType) {
private ScalarTypeEnum<?> enumTypePerExtensions(Class<? extends Enum<?>> enumType) {
for (Method method : enumType.getMethods()) {
DbEnumValue dbValue = AnnotationUtil.get(method, DbEnumValue.class);
if (dbValue != null) {
boolean integerValues = DbEnumType.INTEGER == dbValue.storage();
return createEnumScalarTypeDbValue(enumType, method, integerValues, dbValue.length(), dbValue.withConstraint());
return enumTypeDbValue(enumType, method, integerValues, dbValue.length(), dbValue.withConstraint());
}
}
// look for EnumValue annotations instead
return createEnumScalarType2(enumType);
return enumTypeEnumValue(enumType);
}
/**
@@ -589,7 +552,7 @@ public final class DefaultTypeManager implements TypeManager {
* <p>
* Return null if the EnumValue annotations are not present/used.
*/
private ScalarTypeEnum<?> createEnumScalarTypeDbValue(Class<? extends Enum<?>> enumType, Method method, boolean integerType, int length, boolean withConstraint) {
private ScalarTypeEnum<?> enumTypeDbValue(Class<? extends Enum<?>> enumType, Method method, boolean integerType, int length, boolean withConstraint) {
Map<String, String> nameValueMap = new LinkedHashMap<>();
for (Enum<?> enumConstant : enumType.getEnumConstants()) {
try {
@@ -671,7 +634,7 @@ public final class DefaultTypeManager implements TypeManager {
}
Class<?> logicalType = paramTypes[0];
Class<?> persistType = paramTypes[1];
ScalarType<?> wrappedType = getScalarType(persistType);
ScalarType<?> wrappedType = type(persistType);
if (wrappedType == null) {
throw new IllegalStateException("Could not find ScalarType for: " + paramTypes[1]);
}
@@ -695,7 +658,7 @@ public final class DefaultTypeManager implements TypeManager {
}
Class<?> logicalType = paramTypes[0];
Class<?> persistType = paramTypes[1];
ScalarType<?> wrappedType = getScalarType(persistType);
ScalarType<?> wrappedType = type(persistType);
if (wrappedType == null) {
throw new IllegalStateException("Could not find ScalarType for: " + paramTypes[1]);
}
@@ -709,29 +672,9 @@ public final class DefaultTypeManager implements TypeManager {
}
}
/**
* Add support for Jackson's JsonNode mapping to Clob, Blob, Varchar, JSON and JSONB.
*/
private void initialiseJacksonTypes() {
if (objectMapper != null) {
ObjectMapper mapper = (ObjectMapper) objectMapper;
jsonNodeClob = new ScalarTypeJsonNode.Clob(mapper);
jsonNodeBlob = new ScalarTypeJsonNode.Blob(mapper);
jsonNodeVarchar = new ScalarTypeJsonNode.Varchar(mapper);
jsonNodeJson = jsonNodeClob; // Default for non-Postgres databases
jsonNodeJsonb = jsonNodeClob; // Default for non-Postgres databases
if (postgres) {
jsonNodeJson = new ScalarTypeJsonNodePostgres.JSON(mapper);
jsonNodeJsonb = new ScalarTypeJsonNodePostgres.JSONB(mapper);
}
// add as default mapping for JsonNode (when not annotated with @DbJson etc)
typeMap.put(JsonNode.class, jsonNodeJson);
}
}
private void initialiseJavaTimeTypes(DatabaseConfig config) {
ZoneId zoneId = getZoneId(config);
ZoneId zoneId = zoneId(config);
typeMap.put(java.nio.file.Path.class, new ScalarTypePath());
addType(java.time.Period.class, new ScalarTypePeriod());
@@ -758,7 +701,7 @@ public final class DefaultTypeManager implements TypeManager {
addType(Duration.class, (durationNanos) ? new ScalarTypeDurationWithNanos() : new ScalarTypeDuration());
}
private ZoneId getZoneId(DatabaseConfig config) {
private ZoneId zoneId(DatabaseConfig config) {
final String dataTimeZone = config.getDataTimeZone();
return (dataTimeZone == null) ? ZoneOffset.systemDefault() : TimeZone.getTimeZone(dataTimeZone).toZoneId();
}
@@ -10,6 +10,8 @@ import java.sql.Types;
abstract class ScalarTypeArrayBase<T> extends ScalarTypeJsonCollection<T> {
static final Object[] EMPTY_ARRAY = new Object[]{};
ScalarTypeArrayBase(Class<T> type, int dbType, DocPropertyType docPropertyType, boolean nullable) {
super(type, dbType, docPropertyType, nullable);
}
@@ -16,15 +16,9 @@ import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import static java.util.Collections.EMPTY_LIST;
/**
* Type mapped for DB ARRAY type (Postgres only effectively).
*/
@@ -136,7 +130,7 @@ class ScalarTypeArrayList extends ScalarTypeArrayBase<List> implements ScalarTyp
if (nullable) {
binder.setNull(Types.ARRAY);
} else {
binder.setArray(arrayType, toArray(EMPTY_LIST));
binder.setArray(arrayType, EMPTY_ARRAY);
}
}
@@ -14,8 +14,6 @@ import java.util.Map;
import java.util.UUID;
import java.util.concurrent.locks.ReentrantLock;
import static java.util.Collections.EMPTY_LIST;
/**
* H2 database support for DB ARRAY.
*/
@@ -90,7 +88,7 @@ final class ScalarTypeArrayListH2 extends ScalarTypeArrayList {
if (nullable) {
binder.setNull(Types.ARRAY);
} else {
binder.setObject(toArray(EMPTY_LIST));
binder.setObject(EMPTY_ARRAY);
}
}
}
@@ -15,16 +15,9 @@ import java.io.IOException;
import java.lang.reflect.Type;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import static java.util.Collections.EMPTY_SET;
/**
* Type mapped for DB ARRAY type (Postgres only effectively).
*/
@@ -125,7 +118,7 @@ class ScalarTypeArraySet extends ScalarTypeArrayBase<Set> implements ScalarTypeA
if (nullable) {
binder.setNull(Types.ARRAY);
} else {
binder.setArray(arrayType, toArray(EMPTY_SET));
binder.setArray(arrayType, EMPTY_ARRAY);
}
}
@@ -13,8 +13,6 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.locks.ReentrantLock;
import static java.util.Collections.EMPTY_SET;
/**
* H2 database support for DB ARRAY.
*/
@@ -84,7 +82,7 @@ final class ScalarTypeArraySetH2 extends ScalarTypeArraySet {
if (nullable) {
binder.setNull(Types.ARRAY);
} else {
binder.setObject(toArray(EMPTY_SET));
binder.setObject(EMPTY_ARRAY);
}
}
}
@@ -2,6 +2,7 @@ package io.ebeaninternal.server.type;
import io.ebean.config.dbplatform.ExtraDbTypes;
import io.ebean.core.type.DataBinder;
import io.ebean.core.type.PostgresHelper;
import io.ebean.core.type.ScalarTypeBaseVarchar;
import io.ebean.types.Cidr;
@@ -2,6 +2,7 @@ package io.ebeaninternal.server.type;
import io.ebean.config.dbplatform.ExtraDbTypes;
import io.ebean.core.type.DataBinder;
import io.ebean.core.type.PostgresHelper;
import io.ebean.core.type.ScalarTypeBaseVarchar;
import io.ebean.types.Inet;
@@ -2,6 +2,7 @@ package io.ebeaninternal.server.type;
import io.ebean.config.dbplatform.ExtraDbTypes;
import io.ebean.core.type.DataBinder;
import io.ebean.core.type.PostgresHelper;
import io.ebean.core.type.ScalarTypeBaseVarchar;
import io.ebean.text.TextException;
@@ -3,10 +3,7 @@ package io.ebeaninternal.server.type;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.core.type.DataBinder;
import io.ebean.core.type.DataReader;
import io.ebean.core.type.DocPropertyType;
import io.ebean.core.type.ScalarType;
import io.ebean.core.type.*;
import io.ebean.text.TextException;
import io.ebean.text.json.EJson;
import io.ebeaninternal.json.ModifyAwareList;
@@ -2,6 +2,7 @@ package io.ebeaninternal.server.type;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.core.type.DataBinder;
import io.ebean.core.type.PostgresHelper;
import java.sql.SQLException;
@@ -3,10 +3,7 @@ package io.ebeaninternal.server.type;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.core.type.DataBinder;
import io.ebean.core.type.DataReader;
import io.ebean.core.type.DocPropertyType;
import io.ebean.core.type.ScalarType;
import io.ebean.core.type.*;
import io.ebean.text.TextException;
import io.ebean.text.json.EJson;
import io.ebeaninternal.json.ModifyAwareSet;
@@ -3,6 +3,7 @@ package io.ebeaninternal.server.type;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.config.dbplatform.ExtraDbTypes;
import io.ebean.core.type.DataBinder;
import io.ebean.core.type.PostgresHelper;
import io.ebean.core.type.ScalarType;
import java.sql.SQLException;
@@ -1,43 +1,35 @@
package io.ebeaninternal.server.type;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.ebean.ModifyAwareType;
import io.ebean.annotation.MutationDetection;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
import io.ebean.core.type.PostgresHelper;
import io.ebean.core.type.ScalarJsonManager;
final class TypeJsonManager {
final class TypeJsonManager implements ScalarJsonManager {
private final boolean postgres;
private final ObjectMapper objectMapper;
private final Object mapper;
private final MutationDetection mutationDetection;
TypeJsonManager(boolean postgres, Object objectMapper, MutationDetection mutationDetection) {
TypeJsonManager(boolean postgres, Object mapper, MutationDetection mutationDetection) {
this.postgres = postgres;
this.objectMapper = (ObjectMapper) objectMapper;
this.mapper = mapper;
this.mutationDetection = mutationDetection;
}
MutationDetection mutationDetection() {
@Override
public MutationDetection mutationDetection() {
return mutationDetection;
}
ObjectMapper objectMapper() {
return objectMapper;
@Override
public Object mapper() {
return mapper;
}
boolean keepSource(DeployBeanProperty prop) {
if (prop.getMutationDetection() == MutationDetection.SOURCE) {
return true;
} else if (prop.getMutationDetection() == MutationDetection.DEFAULT) {
prop.setMutationDetection(mutationDetection);
return mutationDetection == MutationDetection.SOURCE;
} else {
return false;
}
}
String postgresType(int dbType) {
@Override
public String postgresType(int dbType) {
if (postgres) {
switch (dbType) {
case DbPlatformType.JSON:
@@ -11,47 +11,41 @@ import java.lang.reflect.Type;
*/
public interface TypeManager {
/**
* Register a ScalarType with the system.
*/
void add(ScalarType<?> scalarType);
/**
* Return the scalar type for the given logical type.
*/
ScalarType<?> getScalarType(String cast);
ScalarType<?> type(String cast);
/**
* Return the ScalarType for a given jdbc type.
*
* @param jdbcType as per java.sql.Types
*/
ScalarType<?> getScalarType(int jdbcType);
ScalarType<?> type(int jdbcType);
/**
* Return the ScalarType for a given logical type.
*/
ScalarType<?> getScalarType(Class<?> type);
ScalarType<?> type(Class<?> type);
/**
* For java.util.Date and java.util.Calendar additionally pass the jdbc type
* that you would like the ScalarType to map to. This is because these types
* can map to different java.sql.Types depending on the property.
*/
ScalarType<?> getScalarType(Class<?> type, int jdbcType);
ScalarType<?> type(Class<?> type, int jdbcType);
/**
* Find and return the ScalarType taking into account the property type with generics.
* <p>
* For example Array based ScalarType for types like {@code List<String>}.
*/
ScalarType<?> getScalarType(Type propertyType, Class<?> type);
ScalarType<?> type(Type propertyType, Class<?> type);
/**
* Create a ScalarType for an Enum using a mapping (rather than JPA Ordinal
* or String which has limitations).
* Create a ScalarType for an Enum using a mapping (rather than JPA Ordinal or String which has limitations).
*/
ScalarType<?> createEnumScalarType(Class<? extends Enum<?>> enumType, EnumType enumerated);
ScalarType<?> enumType(Class<? extends Enum<?>> enumType, EnumType enumerated);
/**
* Return the ScalarType used to handle JSON content.
@@ -59,20 +53,20 @@ public interface TypeManager {
* Note that type expected to be JsonNode or Map.
* </p>
*/
ScalarType<?> getJsonScalarType(DeployBeanProperty prop, int dbType, int dbLength);
ScalarType<?> dbJsonType(DeployBeanProperty prop, int dbType, int dbLength);
/**
* Return the ScalarType used to handle DB ARRAY.
*/
ScalarType<?> getArrayScalarType(Class<?> type, Type genericType, boolean nullable);
ScalarType<?> dbArrayType(Class<?> type, Type genericType, boolean nullable);
/**
* Return the ScalarType used to handle HSTORE (Map<String,String>).
*/
ScalarType<?> getDbMapScalarType();
ScalarType<?> dbMapType();
/**
* Return the Geometry type binder if provided.
*/
GeoTypeBinder getGeoTypeBinder();
GeoTypeBinder geoTypeBinder();
}
@@ -8,6 +8,8 @@ module io.ebean.core {
uses io.ebean.config.dbplatform.DatabasePlatformProvider;
uses io.ebean.datasource.DataSourceAlertFactory;
uses io.ebean.core.type.ExtraTypeFactory;
uses io.ebean.core.type.ScalarTypeSetFactory;
uses io.ebean.core.type.ScalarJsonMapper;
uses io.ebeanservice.docstore.api.DocStoreFactory;
uses io.ebean.migration.auto.AutoMigrationRunner;
uses io.avaje.classpath.scanner.ClassPathScannerFactory;
@@ -46,14 +46,14 @@ public class DefaultTypeManagerTest {
public void enumDayMonth_builtIn_overrideAsString() {
DefaultTypeManager typeManager = create();
ScalarType<?> type = typeManager.createEnumScalarType(Month.class, null);
ScalarType<?> type = typeManager.enumType(Month.class, null);
assertThat(type).isInstanceOf(ScalarTypeEnumWithMapping.class).as("built in type");
// mapped explicitly as JPA EnumType.STRING
type = typeManager.createEnumScalarType(Month.class, EnumType.STRING);
type = typeManager.enumType(Month.class, EnumType.STRING);
assertThat(type).isInstanceOf(ScalarTypeEnumStandard.StringEnum.class).as("override built in type");
try {
typeManager.createEnumScalarType(Month.class, EnumType.ORDINAL);
typeManager.enumType(Month.class, EnumType.ORDINAL);
assertThat(true).isFalse().as("never get here");
} catch (IllegalStateException e) {
@@ -66,10 +66,10 @@ public class DefaultTypeManagerTest {
DefaultTypeManager typeManager = create();
// mapped explicitly as JPA EnumType.STRING
ScalarType<?> type = typeManager.createEnumScalarType(Month.class, EnumType.ORDINAL);
ScalarType<?> type = typeManager.enumType(Month.class, EnumType.ORDINAL);
assertThat(type).isInstanceOf(ScalarTypeEnumStandard.OrdinalEnum.class).as("override built in type");
try {
typeManager.createEnumScalarType(Month.class, EnumType.STRING);
typeManager.enumType(Month.class, EnumType.STRING);
assertThat(true).isFalse().as("never get here");
} catch (IllegalStateException e) {
assertThat(e.getMessage()).contains("It is mapped using 2 different modes when only one is supported");
@@ -80,14 +80,14 @@ public class DefaultTypeManagerTest {
public void enumDayOfWeek_builtIn_overrideAsString() {
DefaultTypeManager typeManager = create();
ScalarType<?> type = typeManager.createEnumScalarType(DayOfWeek.class, null);
ScalarType<?> type = typeManager.enumType(DayOfWeek.class, null);
assertThat(type).isInstanceOf(ScalarTypeEnumWithMapping.class).as("built in type");
// mapped explicitly as JPA EnumType.STRING
type = typeManager.createEnumScalarType(DayOfWeek.class, EnumType.STRING);
type = typeManager.enumType(DayOfWeek.class, EnumType.STRING);
assertThat(type).isInstanceOf(ScalarTypeEnumStandard.StringEnum.class).as("override built in type");
try {
typeManager.createEnumScalarType(DayOfWeek.class, EnumType.ORDINAL);
typeManager.enumType(DayOfWeek.class, EnumType.ORDINAL);
assertThat(true).isFalse().as("never get here");
} catch (IllegalStateException e) {
assertThat(e.getMessage()).contains("It is mapped using 2 different modes when only one is supported");
@@ -99,10 +99,10 @@ public class DefaultTypeManagerTest {
DefaultTypeManager typeManager = create();
// mapped explicitly as JPA EnumType.STRING
ScalarType<?> type = typeManager.createEnumScalarType(DayOfWeek.class, EnumType.ORDINAL);
ScalarType<?> type = typeManager.enumType(DayOfWeek.class, EnumType.ORDINAL);
assertThat(type).isInstanceOf(ScalarTypeEnumStandard.OrdinalEnum.class).as("override built in type");
try {
typeManager.createEnumScalarType(DayOfWeek.class, EnumType.STRING);
typeManager.enumType(DayOfWeek.class, EnumType.STRING);
assertThat(true).isFalse().as("never get here");
} catch (IllegalStateException e) {
assertThat(e.getMessage()).contains("It is mapped using 2 different modes when only one is supported");
@@ -113,19 +113,19 @@ public class DefaultTypeManagerTest {
public void createEnumScalarTypePerExtentions() {
DefaultTypeManager typeManager = create();
ScalarType<?> type = typeManager.createEnumScalarType(VarcharEnum.class, EnumType.ORDINAL);
ScalarType<?> type = typeManager.enumType(VarcharEnum.class, EnumType.ORDINAL);
assertThat(type).isInstanceOf(ScalarTypeEnumWithMapping.class);
// withConstraint false
assertThat(((ScalarTypeEnumWithMapping) type).getDbCheckConstraintValues()).isNull();
type = typeManager.createEnumScalarType(IntEnum.class, EnumType.ORDINAL);
type = typeManager.enumType(IntEnum.class, EnumType.ORDINAL);
assertThat(type).isInstanceOf(ScalarTypeEnumWithMapping.class);
ScalarTypeEnumWithMapping enumWithMapping = (ScalarTypeEnumWithMapping) type;
// withConstraint true
assertThat(enumWithMapping.getDbCheckConstraintValues()).hasSize(3);
assertThat(enumWithMapping.getDbCheckConstraintValues()).contains("100", "101", "102");
type = typeManager.createEnumScalarType(Car.Size.class, EnumType.ORDINAL);
type = typeManager.enumType(Car.Size.class, EnumType.ORDINAL);
assertThat(type).isInstanceOf(ScalarTypeEnumWithMapping.class);
enumWithMapping = (ScalarTypeEnumWithMapping) type;
// withConstraint true
@@ -31,7 +31,7 @@ class TestTypeManager extends BaseTest {
void testEnumWithSubclasses() throws SQLException {
DefaultTypeManager typeManager = createTypeManager();
ScalarType<?> type = typeManager.createEnumScalarType(MyEnum.class, null);
ScalarType<?> type = typeManager.enumType(MyEnum.class, null);
DataReader reader = mock(DataReader.class);
when(reader.getString()).thenReturn("A");
@@ -44,17 +44,17 @@ class TestTypeManager extends BaseTest {
val = type.read(reader);
assertThat(val).isEqualTo(MyEnum.Cval);
ScalarType<?> typeGeneral = typeManager.getScalarType(MyEnum.class);
ScalarType<?> typeGeneral = typeManager.type(MyEnum.class);
assertThat(typeGeneral).isNotNull();
ScalarType<?> typeB = typeManager.getScalarType(MyEnum.Bval.getClass());
ScalarType<?> typeB = typeManager.type(MyEnum.Bval.getClass());
assertThat(typeB).isNotNull();
ScalarType<?> typeA = typeManager.getScalarType(MyEnum.Aval.getClass());
ScalarType<?> typeA = typeManager.type(MyEnum.Aval.getClass());
assertThat(typeA).isNotNull();
ScalarType<?> typeC = typeManager.getScalarType(MyEnum.Cval.getClass());
ScalarType<?> typeC = typeManager.type(MyEnum.Cval.getClass());
assertThat(typeC).isNotNull();
try {
typeManager.createEnumScalarType(MyEnum.class, EnumType.STRING);
typeManager.enumType(MyEnum.class, EnumType.STRING);
fail("never get here");
} catch (IllegalStateException e) {
assertThat(e.getMessage()).contains("It is mapped using 2 different modes when only one is supported");
@@ -65,7 +65,7 @@ class TestTypeManager extends BaseTest {
void testEnumWithChar() throws SQLException {
DefaultTypeManager typeManager = createTypeManager();
ScalarType<?> dayOfWeekType = typeManager.createEnumScalarType(MyDayOfWeek.class, null);
ScalarType<?> dayOfWeekType = typeManager.enumType(MyDayOfWeek.class, null);
DataReader reader = mock(DataReader.class);
when(reader.getString()).thenReturn("MONDAY ");
Object val = dayOfWeekType.read(reader);
@@ -88,7 +88,7 @@ class TestTypeManager extends BaseTest {
assertThat(val).isEqualTo(MyDayOfWeek.FRIDAY);
try {
typeManager.createEnumScalarType(MyDayOfWeek.class, EnumType.ORDINAL);
typeManager.enumType(MyDayOfWeek.class, EnumType.ORDINAL);
fail("never get here");
} catch (IllegalStateException e) {
assertThat(e.getMessage()).contains("It is mapped using 2 different modes when only one is supported");
@@ -99,7 +99,7 @@ class TestTypeManager extends BaseTest {
void test() {
DefaultTypeManager typeManager = createTypeManager();
ScalarType<?> scalarType = typeManager.getScalarType(Money.class);
ScalarType<?> scalarType = typeManager.type(Money.class);
assertEquals(Types.DECIMAL, scalarType.jdbcType());
assertFalse(scalarType.jdbcNative());
assertEquals(Money.class, scalarType.type());
@@ -108,15 +108,15 @@ class TestTypeManager extends BaseTest {
@Test
void testWithConfig() {
DefaultTypeManager typeManager1 = createTypeManager();
ScalarType<?> type1 = typeManager1.createEnumScalarType(MySex.class, null);
ScalarType<?> type1 = typeManager1.enumType(MySex.class, null);
assertThat(type1).isInstanceOf(ScalarTypeEnumStandard.OrdinalEnum.class);
//
DefaultTypeManager typeManager2 = createTypeManagerDefaultEnumTypeString();
ScalarType<?> type2 = typeManager2.createEnumScalarType(MySex.class, null);
ScalarType<?> type2 = typeManager2.enumType(MySex.class, null);
assertThat(type2).isInstanceOf(ScalarTypeEnumStandard.StringEnum.class);
//
DefaultTypeManager typeManager3 = createTypeManagerDefaultEnumTypeString();
ScalarType<?> type3 = typeManager3.createEnumScalarType(MySex.class, EnumType.ORDINAL);
ScalarType<?> type3 = typeManager3.enumType(MySex.class, EnumType.ORDINAL);
assertThat(type3).isInstanceOf(ScalarTypeEnumStandard.OrdinalEnum.class);
}
@@ -144,7 +144,7 @@ class TestTypeManager extends BaseTest {
@Test
void testCalendar() {
DefaultTypeManager typeManager = createTypeManager();
ScalarType<?> typeB = typeManager.getScalarType(GregorianCalendar.class);
ScalarType<?> typeB = typeManager.type(GregorianCalendar.class);
assertThat(typeB).isInstanceOf(ScalarTypeCalendar.class);
}
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<artifactId>ebean-csv-reader</artifactId>
@@ -14,21 +14,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean ddl generation</name>
@@ -28,14 +28,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
@@ -58,7 +58,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
@@ -161,7 +161,9 @@ public class ModelContainer {
applyChange((AlterForeignKey) change);
} else if (change instanceof AddTableComment) {
applyChange((AddTableComment) change);
} else if (change instanceof Sql || change instanceof CreateSchema) {
} else if (change instanceof CreateSchema) {
applyChange((CreateSchema)change);
} else if (change instanceof Sql) {
// do nothing
} else {
throw new IllegalArgumentException("No rule for " + change);
@@ -173,7 +175,6 @@ public class ModelContainer {
* Set the withHistory flag on the associated base table.
*/
private void applyChange(AddHistoryTable change) {
MTable table = tables.get(change.getBaseTable());
if (table == null) {
throw new IllegalStateException("Table [" + change.getBaseTable() + "] does not exist in model?");
@@ -185,7 +186,6 @@ public class ModelContainer {
* Unset the withHistory flag on the associated base table.
*/
protected void applyChange(DropHistoryTable change) {
MTable table = tables.get(change.getBaseTable());
if (table != null) {
table.setWithHistory(false);
@@ -228,6 +228,10 @@ public class ModelContainer {
}
}
protected void applyChange(CreateSchema createSchema) {
schemas.add(createSchema.getName());
}
/**
* Apply a CreateTable change to the model.
*/
@@ -426,7 +430,6 @@ public class ModelContainer {
* Register a drop column on a history tables that has not been applied yet.
*/
private void registerPendingDropColumn(DropColumn dropColumn) {
MTable table = getTable(dropColumn.getTableName());
if (table == null) {
throw new IllegalArgumentException("Table [" + dropColumn.getTableName() + "] not found?");
@@ -45,6 +45,8 @@ class ModelContainerApplyTest {
ModelContainer model = new ModelContainer();
model.apply(migration, MigrationVersion.parse("1.1"));
assertThat(model.getSchemas()).contains("foo");
}
private Migration newMigration(Object change) {
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean external mapping api</name>
+6 -6
View File
@@ -4,12 +4,12 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
<name>ebean external mapping xml</name>
@@ -21,7 +21,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -54,21 +54,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
+43
View File
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.10.0</version>
</parent>
<artifactId>ebean-jackson-jsonnode</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.avaje</groupId>
<artifactId>junit</artifactId>
<version>1.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,51 @@
package io.ebean.jackson.jsonnode;
import com.fasterxml.jackson.databind.JsonNode;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.core.type.ScalarType;
import io.ebean.core.type.ScalarTypeSet;
import java.sql.Types;
class JsonNodeSet implements ScalarTypeSet<JsonNode> {
final ScalarType<JsonNode> varchar;
final ScalarType<JsonNode> clob;
final ScalarType<JsonNode> blob;
final ScalarType<JsonNode> jsonb;
final ScalarType<JsonNode> json;
JsonNodeSet(ScalarType<JsonNode> varchar, ScalarType<JsonNode> clob, ScalarType<JsonNode> blob, ScalarType<JsonNode> jsonb, ScalarType<JsonNode> json) {
this.varchar = varchar;
this.clob = clob;
this.blob = blob;
this.jsonb = jsonb;
this.json = json;
}
@Override
public Class<?> type() {
return JsonNode.class;
}
@Override
public ScalarType<?> defaultType() {
return json;
}
@Override
public ScalarType<JsonNode> forType(int dbType) {
switch (dbType) {
case Types.VARCHAR:
return varchar;
case Types.BLOB:
return blob;
case Types.CLOB:
return clob;
case DbPlatformType.JSONB:
return jsonb;
default:
return json;
}
}
}
@@ -0,0 +1,31 @@
package io.ebean.jackson.jsonnode;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.ebean.config.DatabaseConfig;
import io.ebean.core.type.PostgresHelper;
import io.ebean.core.type.ScalarType;
import io.ebean.core.type.ScalarTypeSet;
import io.ebean.core.type.ScalarTypeSetFactory;
public class JsonNodeTypeFactory implements ScalarTypeSetFactory {
@Override
public ScalarTypeSet<?> createTypeSet(DatabaseConfig config, Object objectMapper) {
if (objectMapper == null) {
return null;
}
ObjectMapper mapper = (ObjectMapper) objectMapper;
var varchar = new ScalarTypeJsonNode.Varchar(mapper);
var clob = new ScalarTypeJsonNode.Clob(mapper);
var blob = new ScalarTypeJsonNode.Blob(mapper);
ScalarType<JsonNode> json = clob; // Default for non-Postgres databases
ScalarType<JsonNode> jsonb = clob; // Default for non-Postgres databases
if (PostgresHelper.isPostgresCompatible(config.getDatabasePlatform())) {
json = new ScalarTypeJsonNodePostgres.JSON(mapper);
jsonb = new ScalarTypeJsonNodePostgres.JSONB(mapper);
}
return new JsonNodeSet(varchar, clob, blob, jsonb, json);
}
}
@@ -1,4 +1,4 @@
package io.ebeaninternal.server.type;
package io.ebean.jackson.jsonnode;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
@@ -11,11 +11,7 @@ import io.ebean.core.type.ScalarTypeBase;
import io.ebean.text.TextException;
import io.ebean.util.IOUtils;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
import java.sql.Types;
@@ -182,7 +178,8 @@ abstract class ScalarTypeJsonNode extends ScalarTypeBase<JsonNode> {
if (value == null) {
dataOutput.writeBoolean(false);
} else {
ScalarHelp.writeUTF(dataOutput, format(value));
dataOutput.writeBoolean(true);
dataOutput.writeUTF(format(value));
}
}
@@ -1,9 +1,10 @@
package io.ebeaninternal.server.type;
package io.ebean.jackson.jsonnode;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.core.type.DataBinder;
import io.ebean.core.type.PostgresHelper;
import java.sql.SQLException;
@@ -0,0 +1,10 @@
import io.ebean.jackson.jsonnode.JsonNodeTypeFactory;
module io.ebean.jackson.jsonnode {
requires io.ebean.core.type;
requires com.fasterxml.jackson.core;
requires com.fasterxml.jackson.databind;
provides io.ebean.core.type.ScalarTypeSetFactory with JsonNodeTypeFactory;
}
@@ -0,0 +1 @@
io.ebean.jackson.jsonnode.JsonNodeTypeFactory
+44
View File
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.10.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ebean-jackson-mapper</artifactId>
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.avaje</groupId>
<artifactId>junit</artifactId>
<version>1.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
@@ -1,28 +1,19 @@
package io.ebeaninternal.server.deploy.meta;
package io.ebean.jackson.mapper;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
import com.fasterxml.jackson.databind.introspect.AnnotatedClassResolver;
import io.ebean.config.DatabaseConfig;
/**
* Used to obtain the Jackson AnnotatedClass for a given bean type utlimately to obtain field level Jackson annotations.
*/
final class DeployBeanObtainJackson<T> {
private final DatabaseConfig config;
private final Class<T> beanType;
DeployBeanObtainJackson(DatabaseConfig config, Class<T> beanType) {
this.config = config;
this.beanType = beanType;
}
final class AnnotatedClassUtil {
/**
* Return the Jackson AnnotatedClass for the given bean type.
*/
Object obtain() {
ObjectMapper objectMapper = (ObjectMapper) config.getObjectMapper();
static AnnotatedClass obtain(ObjectMapper objectMapper, Class<?> beanType) {
JavaType javaType = objectMapper.getTypeFactory().constructType(beanType);
return AnnotatedClassResolver.resolve(objectMapper.getDeserializationConfig(), javaType, objectMapper.getDeserializationConfig());
}
@@ -1,4 +1,4 @@
package io.ebeaninternal.server.type;
package io.ebean.jackson.mapper;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
@@ -1,4 +1,4 @@
package io.ebeaninternal.server.type;
package io.ebean.jackson.mapper;
/**
* Helper that removes whitespace from JSON. Used to normalise Postgres JSONB content.
@@ -1,4 +1,4 @@
package io.ebeaninternal.server.type;
package io.ebean.jackson.mapper;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
@@ -6,42 +6,63 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import io.ebean.annotation.MutationDetection;
import io.ebean.core.type.*;
import io.ebean.text.TextException;
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
import javax.persistence.PersistenceException;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Supports @DbJson properties using Jackson ObjectMapper.
*/
final class ScalarTypeJsonObjectMapper {
public final class ScalarJsonJacksonMapper implements ScalarJsonMapper {
private final Map<Class<?>, AnnotatedClass> jacksonClasses = new ConcurrentHashMap<>();
@SuppressWarnings("unchecked")
@Override
public <A extends Annotation> Class<A> markerAnnotation() {
return (Class<A>)com.fasterxml.jackson.annotation.JacksonAnnotation.class;
}
/**
* Create and return the appropriate ScalarType.
*/
static ScalarType<?> createTypeFor(TypeJsonManager jsonManager, DeployBeanProperty prop, int dbType, DocPropertyType docType) {
AnnotatedField field = (AnnotatedField) prop.getJacksonField();
MutationDetection mode = prop.getMutationDetection();
if (mode == MutationDetection.NONE) {
return new NoMutationDetection(jsonManager, field, dbType, docType);
} else if (mode != MutationDetection.DEFAULT) {
return new GenericObject(jsonManager, field, dbType, docType);
@Override
public ScalarType<?> createType(ScalarJsonRequest req) {
AnnotatedClass annotatedClass = annotatedClass(req);
AnnotatedField field = annotatedField(annotatedClass, req);
if (req.mode() == MutationDetection.NONE) {
return new NoMutationDetection(req.manager(), field, req.dbType(), req.docType());
} else {
return new GenericObject(req.manager(), field, req.dbType(), req.docType());
}
// using the global default MutationDetection mode (defaults to HASH)
final MutationDetection defaultMode = jsonManager.mutationDetection();
prop.setMutationDetection(defaultMode);
if (MutationDetection.NONE == defaultMode) {
return new NoMutationDetection(jsonManager, field, dbType, docType);
}
private AnnotatedField annotatedField(AnnotatedClass annotatedClass, ScalarJsonRequest req) {
for (AnnotatedField field : annotatedClass.fields()) {
if (field.getName().equals(req.name())) {
return field;
}
}
return new GenericObject(jsonManager, field, dbType, docType);
throw new IllegalStateException("AnnotatedField not found to match " + req.name());
}
private AnnotatedClass annotatedClass(ScalarJsonRequest req) {
return jacksonClasses.computeIfAbsent(req.beanType(), key -> {
ObjectMapper mapper = (ObjectMapper) req.manager().mapper();
return AnnotatedClassUtil.obtain(mapper, req.beanType());
});
}
/**
@@ -49,7 +70,7 @@ final class ScalarTypeJsonObjectMapper {
*/
private static final class NoMutationDetection extends Base<Object> {
NoMutationDetection(TypeJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType) {
NoMutationDetection(ScalarJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType) {
super(Object.class, jsonManager, field, dbType, docType);
}
}
@@ -61,7 +82,7 @@ final class ScalarTypeJsonObjectMapper {
private final boolean jsonb;
GenericObject(TypeJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType) {
GenericObject(ScalarJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType) {
super(Object.class, jsonManager, field, dbType, docType);
this.jsonb = "jsonb".equals(pgType);
}
@@ -126,9 +147,9 @@ final class ScalarTypeJsonObjectMapper {
protected final String pgType;
private final DocPropertyType docType;
Base(Class<T> cls, TypeJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType) {
Base(Class<T> cls, ScalarJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType) {
super(cls, false, dbType);
this.objectReader = jsonManager.objectMapper();
this.objectReader = (ObjectMapper)jsonManager.mapper();
this.pgType = jsonManager.postgresType(dbType);
this.docType = docType;
final JacksonTypeHelper helper = new JacksonTypeHelper(field, objectReader);
@@ -223,7 +244,8 @@ final class ScalarTypeJsonObjectMapper {
if (value == null) {
dataOutput.writeBoolean(false);
} else {
ScalarHelp.writeUTF(dataOutput, format(value));
dataOutput.writeBoolean(true);
dataOutput.writeUTF(format(value));
}
}
}
@@ -0,0 +1,11 @@
import io.ebean.jackson.mapper.ScalarJsonJacksonMapper;
module io.ebean.jackson.mapper {
requires io.ebean.core.type;
requires com.fasterxml.jackson.annotation;
requires com.fasterxml.jackson.core;
requires com.fasterxml.jackson.databind;
provides io.ebean.core.type.ScalarJsonMapper with ScalarJsonJacksonMapper;
}
@@ -0,0 +1 @@
io.ebean.jackson.mapper.ScalarJsonJacksonMapper
@@ -1,4 +1,4 @@
package io.ebeaninternal.server.type;
package io.ebean.jackson.mapper;
import org.junit.jupiter.api.Test;
+2 -2
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -14,7 +14,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
+3 -3
View File
@@ -6,7 +6,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2-SNAPSHOT</version>
<version>13.10.0-SNAPSHOT</version>
</parent>
<artifactId>ebean-kotlin</artifactId>
@@ -28,7 +28,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2-SNAPSHOT</version>
<version>13.10.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
@@ -50,7 +50,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.9.2-SNAPSHOT</version>
<version>13.10.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean postgis</name>
@@ -22,14 +22,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<!-- provided scope -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
@@ -50,7 +50,7 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.4.1</version>
<version>42.5.0</version>
<scope>provided</scope>
</dependency>
@@ -65,7 +65,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean querybean</name>
@@ -17,7 +17,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
@@ -63,21 +63,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
@@ -107,7 +107,7 @@
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:13.6.5</tile>
<tile>io.ebean.tile:enhancement:13.10.0</tile>
</tiles>
</configuration>
</plugin>
@@ -46,12 +46,12 @@ public class Customer extends BaseModel {
boolean inactive;
PhoneNumber phoneNumber;
public PhoneNumber phoneNumber;
ValidEmail email;
@Column(length = 100)
String name;
public String name;
Date registered;
@@ -215,10 +215,9 @@ public class QOrderTest {
}
private static void setupData() {
customer = new Customer();
customer.setName("Fred");
customer.setPhoneNumber(new PhoneNumber("Ph1"));
customer.name = "Fred";
customer.phoneNumber = new PhoneNumber("Ph1");
customer.save();
order = new Order();
@@ -2,3 +2,4 @@ entity-packages: org.example.domain
querybean-packages: org.example.domain,org.querytest
debug: 0
synthetic: false
entity-field-access: true
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<artifactId>ebean-redis</artifactId>
@@ -22,35 +22,35 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
+22 -8
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>ebean test</name>
@@ -28,20 +28,20 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
@@ -105,14 +105,28 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
@@ -169,7 +183,7 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.4.1</version>
<version>42.5.0</version>
<exclusions>
<exclusion>
<groupId>org.checkerframework</groupId>
@@ -272,7 +286,7 @@
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:13.6.5</tile>
<tile>io.ebean.tile:enhancement:13.10.0</tile>
</tiles>
</configuration>
</plugin>
@@ -54,37 +54,37 @@ public class ExtendedServerTest extends BaseTestCase {
@Test
public void mockClock() {
Database server = DB.getDefault();
Database database = DB.getDefault();
final Instant snapshot = Instant.now();
Instant backedSnapshot = snapshot.minus(1, ChronoUnit.DAYS);
Clock snapshotClock = Clock.fixed(backedSnapshot, Clock.systemUTC().getZone());
server.extended().setClock(snapshotClock);
database.extended().setClock(snapshotClock);
ResetBasicData.reset();
int count = server
int count = database
.find(Customer.class)
.where()
.gt("cretime", snapshot)
.findCount();
assertThat(count).isEqualTo(0);
int count2 = server
int count2 = database
.find(Customer.class)
.where()
.ge("cretime", backedSnapshot)
.findCount();
assertThat(count2).isGreaterThan(0);
int count3 = server
int count3 = database
.find(Customer.class)
.where()
.gt("updtime", snapshot)
.findCount();
assertThat(count3).isEqualTo(0);
int count4 = server
int count4 = database
.find(Customer.class)
.where()
.ge("updtime", backedSnapshot)
@@ -46,14 +46,14 @@ public class EArrayBean {
@DbArray
List<Float> floats;
@DbArray
List<Status> statuses;
@DbArray(nullable = false)
List<Status> statuses = new ArrayList<>();
@DbArray
List<VarcharEnum> vcEnums = new ArrayList<>();
@DbArray
List<IntEnum> intEnums = new ArrayList<>();
@DbArray @NotNull
List<IntEnum> intEnums;
@DbArray
Set<Status> status2;
@@ -28,6 +28,8 @@ class TestDbArray_basic extends BaseTestCase {
DB.find(EArrayBean.class).delete();
bean.setName("some stuff");
assertThat(bean.getStatuses()).as("DbArray is auto initialised").isNotNull();
assertThat(bean.getIntEnums()).as("DbArray is auto initialised").isNotNull();
assertThat(bean.getUids()).as("DbArray is auto initialised").isNotNull();
List<String> phNumbers = bean.getPhoneNumbers();
phNumbers.add("4321");
@@ -170,7 +172,26 @@ class TestDbArray_basic extends BaseTestCase {
bean.setOtherIds(null);
DB.save(bean);
DB.delete(bean);
EArrayBean found = DB.find(EArrayBean.class, bean.getId());
assertThat(found.getPhoneNumbers()).isNull();
assertThat(found.getStatuses()).isEmpty();
assertThat(found.getIntEnums()).isEmpty();
assertThat(found.getUids()).isEmpty();
found.setName("some nulls 2");
DB.save(found);
EArrayBean found2 = DB.find(EArrayBean.class)
.where()
.eq("id", bean.getId())
.isNull("phoneNumbers")
.findOne();
assertThat(found2).isNotNull();
assertThat(found2.getPhoneNumbers()).isNull();
DB.delete(found);
}
@Test
@@ -4,7 +4,7 @@ import javax.persistence.Embeddable;
import java.util.Objects;
@Embeddable
public class UserInterestLiveKey {
public final class UserInterestLiveKey {
private long userId;
private long liveId;
@@ -14,13 +14,20 @@ public class UserInterestLiveKey {
this.liveId = liveId;
}
public long userId() {
return userId;
}
public long liveId() {
return liveId;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserInterestLiveKey that = (UserInterestLiveKey) o;
return userId == that.userId &&
liveId == that.liveId;
return userId == that.userId && liveId == that.liveId;
}
@Override
+1
View File
@@ -4,4 +4,5 @@ entity-packages: org,misc
transactional-packages: org
querybean-packages: none
synthetic: true
allow-nullable-dbarray: true
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<name>kotlin querybean generator</name>
@@ -29,7 +29,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
@@ -43,7 +43,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
@@ -64,14 +64,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
<scope>test</scope>
</dependency>
+15 -15
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>platforms</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<artifactId>ebean-platform-all</artifactId>
@@ -14,72 +14,72 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hsqldb</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlanywhere</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+3 -3
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>platforms</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<artifactId>ebean-platform-clickhouse</artifactId>
@@ -14,12 +14,12 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+3 -3
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>platforms</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<artifactId>ebean-platform-db2</artifactId>
@@ -14,12 +14,12 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+3 -3
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>platforms</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<artifactId>ebean-platform-h2</artifactId>
@@ -14,7 +14,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
<!-- Provided scope so that the H2HistoryTrigger can live in Ebean core
@@ -36,6 +36,6 @@
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>
+3 -3
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>platforms</artifactId>
<groupId>io.ebean</groupId>
<version>13.9.2</version>
<version>13.10.0</version>
</parent>
<artifactId>ebean-platform-hana</artifactId>
@@ -14,12 +14,12 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.9.2</version>
<version>13.10.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.9.2</tag>
<tag>ebean-parent-13.10.0</tag>
</scm>
</project>

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