Compare commits

..
96 Commits
Author SHA1 Message Date
Rob Bygrave 3a84695130 Version 13.18.0 2023-05-31 22:06:30 +12:00
Rob BygraveandGitHub 3f6d6908e2 Merge pull request #3081 from ebean-orm/feature/bump-migration-2
Bump ebean-migration to 13.9.0 - changes API for checkState()
2023-05-31 20:53:24 +12:00
Rob Bygrave 9f4bf6103f Bump ebean-migration to 13.9.0 - changes API for checkState()
Code using ebean-migration checkState() methods needs to change
as those methods now return a new MigrationResource interface type
2023-05-31 20:51:28 +12:00
Rob BygraveandGitHub ad7bb7063d Merge pull request #3079 from ebean-orm/feature/bump-migration
Bump ebean-migration to 13.8.0 and ebean-ddl-runner to 2.3
2023-05-29 16:28:44 +12:00
Rob Bygrave 04b4fea559 Bump ebean-migration to 13.8.0 and ebean-ddl-runner to 2.3 2023-05-29 16:27:54 +12:00
Rob BygraveandGitHub eb824949fe Merge pull request #3078 from ebean-orm/feature/refactor-renameDtoMethodUsingAccessors
Refactor internal dto methods to use accessors
2023-05-26 15:24:40 +12:00
robin.bygrave 34db4d0c1f Refactor internal dto methods to use accessors 2023-05-26 15:09:11 +12:00
Rob BygraveandGitHub 54a3113dbc Merge pull request #3077 from ebean-orm/feature/3062-dtoQuery
Use Statement for truncate table and postgres version query
2023-05-26 15:03:52 +12:00
robin.bygrave 7635630808 Use Statement for truncate table and postgres version query 2023-05-26 15:03:13 +12:00
Rob BygraveandGitHub e4018864ac Merge pull request #3075 from ebean-orm/feature/3062-dtoQuery
#3062 - DtoQuery may match the wrong constructor
2023-05-25 21:58:52 +12:00
robin.bygrave 75e69a0a23 #3062 - DtoQuery may match the wrong constructor
When 2 or more Dto constructors clash by argument count
then we need to ignore those constructors.
2023-05-25 21:57:54 +12:00
Rob BygraveandGitHub 6061f80dcc Merge pull request #3074 from ebean-orm/feature/toString_roundBrackets
Change toString to use (trimmed) with round brackets
2023-05-25 21:15:31 +12:00
robin.bygrave c60525a685 Change toString to use (trimmed) with round brackets
Change from use <> angle brackets as with json logger these are escaped which is a little ugly
2023-05-25 21:14:51 +12:00
Rob BygraveandGitHub eef628531a Merge pull request #3073 from ebean-orm/feature/bump-yugabyte
Bump yugabyte version to 2.18.0.0
2023-05-25 21:04:07 +12:00
robin.bygrave 33d9257a61 Bump yugabyte version to 2.18.0.0 2023-05-25 20:56:10 +12:00
robin.bygrave 7b032351b1 Bump yugabyte version to 2.18.0.0 2023-05-25 20:48:50 +12:00
robin.bygrave 265f865a7d Postgres DDL - Use IF NOT EXISTS with ADD COLUMN
Update generated hashes
2023-05-25 20:30:47 +12:00
Rob BygraveandGitHub 73d30310fd Merge pull request #3072 from ebean-orm/feature/postgres-dll-addColumn-ifNotExists
Postgres DDL - Use IF NOT EXISTS with ADD COLUMN
2023-05-25 20:28:41 +12:00
Rob BygraveandGitHub e26fbbb11f Merge branch 'master' into feature/postgres-dll-addColumn-ifNotExists 2023-05-25 20:25:54 +12:00
Rob BygraveandGitHub a548c16789 Merge pull request #3071 from ebean-orm/feature/postres-ddl-varchar-changeSize
Postgres DDL - Don't use cast when just changing varchar column size
2023-05-25 20:23:04 +12:00
robin.bygrave ecf650c9bc Postgres DDL - Use IF NOT EXISTS with ADD COLUMN 2023-05-25 20:22:18 +12:00
robin.bygrave b27b4e7038 Postgres DDL - Don't use cast when just changing varchar column size 2023-05-25 20:00:36 +12:00
Rob BygraveandGitHub 58d190ef12 Merge pull request #3070 from ebean-orm/dependabot/maven/ebean-test/org.xerial-sqlite-jdbc-3.41.2.2
Bump sqlite-jdbc from 3.36.0.3 to 3.41.2.2 in /ebean-test
2023-05-24 09:28:05 +12:00
dependabot[bot]andGitHub bffc9108f9 Bump sqlite-jdbc from 3.36.0.3 to 3.41.2.2 in /ebean-test
Bumps [sqlite-jdbc](https://github.com/xerial/sqlite-jdbc) from 3.36.0.3 to 3.41.2.2.
- [Release notes](https://github.com/xerial/sqlite-jdbc/releases)
- [Changelog](https://github.com/xerial/sqlite-jdbc/blob/master/CHANGELOG)
- [Commits](https://github.com/xerial/sqlite-jdbc/compare/3.36.0.3...3.41.2.2)

---
updated-dependencies:
- dependency-name: org.xerial:sqlite-jdbc
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-23 20:15:29 +00:00
Rob BygraveandGitHub 114a715432 Merge pull request #3068 from FOCONIS/throw-exceptions
DB.refrence throws EntityNotFoundException instead returning null
2023-05-23 19:29:51 +12:00
Rob BygraveandGitHub 67d98954b2 Merge pull request #3069 from ebean-orm/feature/bump-avaje-config
Bump avaje-config to 3.4
2023-05-23 19:28:47 +12:00
Rob Bygrave 53e7aafb06 Bump avaje-config to 3.4 2023-05-23 19:26:29 +12:00
Roland Praml e207b4720b DB.refrence throws EntityNotFoundException instead returning null 2023-05-23 08:37:52 +02:00
Rob BygraveandGitHub af6da23411 Merge pull request #3067 from ebean-orm/feature/2064-jakarta-transaction
#3064 - JtaTransaction does not use jarkarta prefix for javax.transaction classes
2023-05-23 17:11:38 +12:00
robin.bygrave 21f274fd34 #3064 - JtaTransaction does not use jarkarta prefix for javax.transaction classes 2023-05-23 17:09:53 +12:00
Rob BygraveandGitHub 1b8df12a01 Merge pull request #3066 from ebean-orm/feature/3060-part2
From #3060 - Add missing @Nullable to ExpressionList.findSingleAttribute()
2023-05-23 17:00:14 +12:00
robin.bygrave b210d1a6a7 From #3060 - Add missing @Nullable to ExpressionList.findSingleAttribute() 2023-05-23 16:12:13 +12:00
Rob BygraveandGitHub d53ca87d43 Merge pull request #3057 from FOCONIS/property-value-intercept
Property.value use intercept to trigger lazy load
2023-05-23 13:36:09 +12:00
Rob BygraveandGitHub 635820cab5 Merge pull request #3058 from ebean-orm/feature/BeanProperty-value-to-getValue
No functional change, change use of BeanProperty.value() to BeanProperty.getValue()
2023-05-19 16:09:37 +12:00
Rob BygraveandGitHub aedb0fdcac Merge pull request #3063 from ebean-orm/feature/improve-error-message-no-join-columns
Use DeployBeanProperty toString() removing getFullBeanName()
2023-05-19 16:08:54 +12:00
robin.bygrave 4db1925328 No functional change, change use of BeanProperty.value() to BeanProperty.getValue()
Noting that value() currently calls through to getValue() hence
this is no real change. This is done because value() is also
a public method Property.value() [and this should probably
change to use getValueIntercept() rather than getValue()]
2023-05-17 15:31:52 +12:00
Roland Praml 6f2a444954 Property.value use intercept 2023-05-16 15:28:30 +02:00
Rob BygraveandGitHub 59b6621077 Merge pull request #3055 from ebean-orm/feature/queryPlanCaptureMicros
ENH: Add captureMicros and whenCaptured to MetaQueryPlan
2023-05-16 15:38:05 +12:00
Rob BygraveandGitHub 15a39f62e6 Merge pull request #3056 from ebean-orm/bump/yugabyte
Testing - Bump YugabyteDB version for testing to 2.17.3.0-b152
2023-05-16 15:37:29 +12:00
robin.bygrave 40489706ce Testing - Bump YugabyteDB version for testing to 2.17.3.0-b152 2023-05-16 14:39:46 +12:00
robin.bygrave 742f3b6dc4 ENH: Add captureMicros and whenCaptured to MetaQueryPlan
- captureMicros is the time taken to capture the specific query plan
- whenCaptured is the time when the bind values were taken

The DefaultQueryPlanListener logging will include these in the
output it logs
2023-05-16 13:47:27 +12:00
Rob BygraveandGitHub 753617a616 Merge pull request #3039 from FOCONIS/detailed-error-message
Throw excepction when trying to create unregistered bean
2023-05-10 16:37:18 +12:00
Rob BygraveandGitHub 114da00d98 Merge pull request #3040 from FOCONIS/correct-quotes
FIX: Use correct quotes when logging
2023-05-10 16:36:27 +12:00
Rob BygraveandGitHub 283ab7a1ac Merge pull request #3038 from FOCONIS/fix-javadoc-plugin
FIX build on system without JAVA_HOME set
2023-05-10 16:35:39 +12:00
Rob BygraveandGitHub 096988c19f Merge pull request #3052 from ebean-orm/feature/dep-config
Bump jackson dependency to 2.15.0
2023-05-10 16:34:06 +12:00
Rob Bygrave baf727e8ea Bump jackson dependency to 2.15.0 2023-05-10 16:33:38 +12:00
Rob BygraveandGitHub 2eb6558145 Merge pull request #3051 from ebean-orm/feature/dep-config
Bump avaje-config dependency to 3.2
2023-05-10 16:30:39 +12:00
Rob Bygrave d946504503 Bump avaje-config dependency to 3.2 2023-05-10 16:30:03 +12:00
Rob Bygrave ed94edd96b Bump to next snapshot version 2023-05-10 16:26:03 +12:00
Rob BygraveandGitHub 6441030161 Merge pull request #3030 from ebean-orm/feature/bump-avaje-config
Included ebean-migration as a dependency of ebean, ebean-postgres etc
2023-05-10 16:24:54 +12:00
Rob Bygrave 588527a5b9 Version 13.17.4 2023-05-10 00:34:53 +12:00
Rob Bygrave 06cad500c1 #3031 Improve error message 2023-05-10 00:34:27 +12:00
Rob Bygrave e29b57811b Update README add end 2023-05-10 00:30:07 +12:00
Rob Bygrave e6bf46e8c4 Improve error message for #3031 2023-05-09 23:37:05 +12:00
Rob BygraveandGitHub 646f8cc66b Merge pull request #3050 from ebean-orm/feature/LoadBeanRequest
Fix SqlTreeLoadBean to only register new beans into load context
2023-05-09 23:23:31 +12:00
Rob Bygrave 4c9f0f23f0 Fix SqlTreeLoadBean to only register new beans into load context
Additionally, refactor LoadBeanRequest moving the MarkedAsDeleted logging
2023-05-09 22:49:17 +12:00
Rob Bygrave ecfd831603 #3049 - Support for ebean.test.containers.mirror 2023-05-08 17:22:41 +12:00
Rob BygraveandGitHub b8324905ae Merge pull request #3036 from Ryszard-Trojnacki/postgis
Implemented missing cache functions for Postgis module.
2023-05-08 17:15:14 +12:00
Rob BygraveandGitHub 8cbcd1afad Merge pull request #3049 from ebean-orm/feature/ebean.test.containers.mirror
[ebean-test] Add support for ebean.test.containers.mirror
2023-05-08 17:12:22 +12:00
Rob Bygrave 7970ea39f3 Bump to next snapshot version 2023-05-08 17:11:24 +12:00
robin.bygrave a399d4f2cd [ebean-test] Add support for ebean.test.containers.mirror
Can use this property to specify a mirror to use for test images when running in CI

Currently, we assume that for local builds we actually prefer to not use the mirror (for Arm64 support etc)
2023-05-08 14:35:14 +12:00
Rob Bygrave 5b91e671dd Version 13.17.3 2023-05-01 14:51:33 +12:00
Rob Bygrave 547843fd52 Bump ebean-agent to 13.17.3 (no effective change) 2023-05-01 13:30:39 +12:00
Rob BygraveandGitHub 21e9c5c3d4 Merge pull request #3044 from ebean-orm/feature/markedAsDeleted-v3
Modify MarkedAsDeleted to ignore beans added during load
2023-05-01 13:21:36 +12:00
Rob Bygrave 05ab1ba25e Modify MarkedAsDeleted to ignore beans added during load
Adds the additional queryIds.contains(id) check
2023-05-01 13:11:03 +12:00
Roland Praml 82a6ec6957 Fix also other places 2023-04-26 11:11:12 +02:00
Roland Praml cf1c08c4ac FIX: Use correct quotes when logging 2023-04-26 10:59:41 +02:00
Roland Praml d32df16137 Throw excepction when trying to create unregistered bean 2023-04-26 10:56:14 +02:00
Roland Praml 2bcbc6fa07 FIX also other plugin versions 2023-04-26 10:39:18 +02:00
Roland Praml ba9158ec9c Javadoc POM fixes 2023-04-26 10:22:27 +02:00
Ryszard Trojnacki 40a6693a4c Implemented missing cache functions for Postgis module. 2023-04-21 08:58:44 +02:00
Rob Bygrave e04f33aaf0 Bump to next snapshot version 2023-04-21 16:53:12 +12:00
Rob Bygrave e4162a5b03 Version 13.17.2 2023-04-21 16:14:48 +12:00
Rob BygraveandGitHub 23e6b18262 Merge pull request #3035 from ebean-orm/feature/markedAsDeleted-mutateAfterLoadingFlag
Update MarkedAsDeleted logging to included check for loadingStarted
2023-04-21 02:44:39 +12:00
Rob Bygrave c8852c521e Update MarkedAsDeleted logging to included check for loadingStarted 2023-04-21 02:43:34 +12:00
Rob Bygrave 7351258d99 Bump ebean-agent to 13.17.2 (no functional change) 2023-04-21 00:51:57 +12:00
Rob BygraveandGitHub af9f9585fb Merge pull request #3034 from ebean-orm/feature/3033
#3033 - Fix for ConcurrentModificationException introduced in 13.17.1
2023-04-21 00:50:23 +12:00
Rob Bygrave d7f9dd40a0 #3033 - Fix for ConcurrentModificationException introduced in 13.17.1
java.util.ConcurrentModificationException
	at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1493)
	at java.base/java.util.HashMap$KeyIterator.next(HashMap.java:1516)
	at java.base/java.util.AbstractCollection.toString(AbstractCollection.java:472)
	at java.base/java.lang.String.valueOf(String.java:2951)
	at io.ebeaninternal.server.core.DefaultBeanLoader.loadBean(DefaultBeanLoader.java:134)
	at io.ebeaninternal.server.core.DefaultServer.loadBean(DefaultServer.java:475)
	at io.ebeaninternal.server.loadcontext.DLoadBeanContext$LoadBuffer.loadBean(DLoadBeanContext.java:217)
	at io.ebean.bean.InterceptReadWrite.loadBeanInternal(InterceptReadWrite.java:742)
	at io.ebean.bean.InterceptReadWrite.loadBean(InterceptReadWrite.java:724)
	at io.ebean.bean.InterceptReadWrite.preGetter(InterceptReadWrite.java:837)
	at ...
2023-04-21 00:49:41 +12:00
Rob Bygrave 1ec389864d Included ebean-migration as a dependency of ebean, ebean-postgres etc
Include ebean-migration as a dependency of all the composites. The thinking here is that we now expect to prefer ebean-migration over flyway or liquibase as the migration runner of choice. Including it means one less thing for folks to worry about in terms of syncing the versions to use etc.
2023-04-18 00:12:44 +12:00
Rob BygraveandGitHub d353b98307 Merge pull request #3029 from ebean-orm/feature/bump-avaje-config
Bump avaje-config to version 3.1
2023-04-18 00:04:14 +12:00
Rob Bygrave 3ddd7b4b2b Bump avaje-config to version 3.1 2023-04-18 00:03:35 +12:00
Rob Bygrave 3960e1deb5 Bump test tile use to 13.17.1 2023-04-17 23:56:20 +12:00
Rob Bygrave 84af78e43c Bump parent pom to 3.10 2023-04-17 23:52:36 +12:00
Rob Bygrave cbdbf6d2e0 Bump to next snapshot version 2023-04-17 23:51:58 +12:00
Rob Bygrave 548bf871a9 Version 13.17.1 2023-04-17 23:31:00 +12:00
Rob BygraveandGitHub b5245544d2 Merge pull request #3028 from ebean-orm/feature/markedAsDeleted-beforeState
Change MarkedAsDeleted to log batch before state
2023-04-17 22:40:29 +12:00
Rob Bygrave a986d0c8cd Change MarkedAsDeleted to log batch before state 2023-04-17 22:18:33 +12:00
Rob BygraveandGitHub 0e02449f67 Merge pull request #3027 from rvowles/docs/update-ebean-test
Update the documentation for test tenants
2023-04-17 17:52:48 +12:00
Richard Vowles 19389fb9d4 Update the documentation for test tenants
The existing docs for test tenants is no
longer correct and additional class level
docs point users in the right direction.
2023-04-17 16:22:06 +12:00
Rob BygraveandGitHub ab1a79281b Merge pull request #3023 from ebean-orm/feature/profileLabel-withQueryType
Add the [+query,+cache,+lazy] query type to the profile label
2023-04-13 19:46:27 +12:00
Rob BygraveandGitHub 073669d312 Merge pull request #3025 from ebean-orm/fix/3024
Fix for #3024 NPE when lazy loading after deserialising an entity bean
2023-04-13 19:46:08 +12:00
Rob Bygrave f66662fdfa Fix for #3024 NPE when lazy loading after deserialising an entity bean 2023-04-13 19:42:14 +12:00
Rob Bygrave 04b0d23932 Update tiles-maven-plugin to version 2.34 2023-04-11 10:34:52 +12:00
Rob Bygrave af613d3096 Add the [+query,+cache,+lazy] query type to the profile label 2023-04-06 21:59:51 +12:00
Rob Bygrave ecd27e145e bump to next snapshot version 2023-04-06 17:07:52 +12:00
Rob Bygrave 2d03421de4 Use DeployBeanProperty toString() removing getFullBeanName() 2023-03-28 18:44:00 +13:00
135 changed files with 1081 additions and 619 deletions
+1
View File
@@ -120,3 +120,4 @@ To set this option as the global default for IntelliJ use:
`Run - Edit Configurations -> Edit configuration templates -> JUnit -> modify options - Do not use module-path option`
end
+11 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean-clickhouse</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -31,17 +31,23 @@
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+11 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean-cockroach</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -31,17 +31,23 @@
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+11 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean-db2</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -31,17 +31,23 @@
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+11 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean-h2</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -31,17 +31,23 @@
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+11 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean-hana</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -31,17 +31,23 @@
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+11 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean-mariadb</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -31,17 +31,23 @@
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+11 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean-mysql</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -31,17 +31,23 @@
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+11 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean-nuodb</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -31,17 +31,23 @@
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+11 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean-oracle</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -31,17 +31,23 @@
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+11 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean-postgres</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -31,17 +31,23 @@
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+11 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean-sqlite</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -31,17 +31,23 @@
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+11 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean-sqlserver</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -31,17 +31,23 @@
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+11 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean-yugabyte</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -31,17 +31,23 @@
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+14 -8
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean (all platforms)</name>
@@ -16,31 +16,31 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -49,17 +49,23 @@
<version>${ebean-datasource.version}</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>${ebean-migration.version}</version>
</dependency>
<!-- Technically optional but most expected to use query beans -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<artifactId>composites</artifactId>
+7 -7
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean api</name>
@@ -26,12 +26,6 @@
<version>1.0</version>
</dependency>
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-config</artifactId>
<version>2.4</version>
</dependency>
<!--
Class retention Nonnull and Nullable annotations
to assist with IDE auto-completion with Ebean API
@@ -42,6 +36,12 @@
<version>1.1</version>
</dependency>
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-config</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>persistence-api</artifactId>
@@ -35,7 +35,7 @@ import java.util.concurrent.Callable;
* <h5>The 'default' Database</h5>
* <p>
* One Database can be designated as the 'default' or 'primary' Database
* (see {@link DatabaseConfig#setDefaultServer(boolean)}. Many methods on DB
* (see {@link DatabaseConfig#setDefaultServer(boolean)}). Many methods on DB
* such as {@link DB#find(Class)} etc are actually just a convenient way to
* call methods on the 'default/primary' Database.
*
@@ -166,7 +166,7 @@ public interface Database {
/**
* Return the BeanState for a given entity bean.
* <p>
* This will return null if the bean is not an enhanced entity bean.
* This will throw an IllegalArgumentException if the bean is not an enhanced entity bean.
*/
BeanState beanState(Object bean);
@@ -404,6 +404,7 @@ public interface ExpressionList<T> {
*
* }</pre>
*/
@Nullable
default <A> A findSingleAttribute() {
List<A> list = findSingleAttributeList();
return !list.isEmpty() ? list.get(0) : null;
@@ -47,7 +47,7 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
*/
private static final byte FLAG_MUTABLE_HASH_SET = 16;
private transient final ReentrantLock lock = new ReentrantLock();
private final ReentrantLock lock = new ReentrantLock();
private transient NodeUsageCollector nodeUsageCollector;
private transient PersistenceContext persistenceContext;
private transient BeanLoader beanLoader;
@@ -115,7 +115,7 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
@Override
public String toString() {
return "InterceptReadWrite{state=" + state +
return "InterceptReadWrite@" + hashCode() + "{state=" + state +
(dirty ? " dirty;" : "") +
(forceUpdate ? " forceUpdate;" : "") +
(readOnly ? " readOnly;" : "") +
@@ -128,7 +128,6 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
(lazyLoadProperty > -1 ? (", lazyLoadProperty=" + lazyLoadProperty) : "") +
", loader=" + beanLoader +
(ownerId != null ? (", ownerId=" + ownerId) : "") +
", owner=" + owner +
'}';
}
@@ -110,7 +110,7 @@ public final class ToStringBuilder {
} else {
String content = String.valueOf(value);
if (content.length() > TRIM_LENGTH) {
content = content.substring(0, TRIM_LENGTH) + " <trimmed>";
content = content.substring(0, TRIM_LENGTH) + " (trimmed)";
}
sb.append(content);
if (sb.length() >= MAX_TOTAL_CONTENT) {
@@ -673,7 +673,7 @@ public class DatabasePlatform {
protected String withForUpdate(String sql, Query.LockWait lockWait, Query.LockType lockType) {
// silently assume the database does not support the "for update" clause.
log.log(INFO, "it seems your database does not support the 'for update' clause");
log.log(INFO, "it seems your database does not support the ''for update'' clause");
return sql;
}
@@ -2,6 +2,8 @@ package io.ebean.meta;
import io.ebean.ProfileLocation;
import java.time.Instant;
/**
* Meta data for captured query plan.
*/
@@ -51,4 +53,14 @@ public interface MetaQueryPlan {
* Return the total count of times bind capture has occurred.
*/
long captureCount();
/**
* Return the time taken to capture this plan in microseconds.
*/
long captureMicros();
/**
* Return the instant when the bind values were captured.
*/
Instant whenCaptured();
}
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<!-- <parent>-->
<!-- <groupId>org.avaje</groupId>-->
@@ -26,7 +26,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
@@ -62,7 +62,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
@@ -76,7 +76,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
@@ -87,11 +87,11 @@
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.24</version>
<version>2.34</version>
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:13.12.0</tile>
<tile>io.ebean.tile:enhancement:13.17.1</tile>
</tiles>
</configuration>
</plugin>
+30 -30
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean bom</name>
@@ -89,112 +89,112 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-xml</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-autotune</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>kotlin-querybean-generator</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-redis</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-spring-txn</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<!-- platforms -->
@@ -202,67 +202,67 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-clickhouse</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-db2</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-h2</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-hana</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mariadb</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mysql</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-nuodb</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-oracle</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgres</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlite</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlserver</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<artifactId>ebean-core-type</artifactId>
@@ -16,7 +16,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
+7 -9
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<artifactId>ebean-core</artifactId>
@@ -22,7 +22,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -46,13 +46,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -143,21 +143,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
@@ -201,7 +201,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
<trimStackTrace>false</trimStackTrace>
@@ -229,7 +228,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<doctitle>Ebean 12</doctitle>
<overview>src/main/java/io/ebean/overview.html</overview>
@@ -23,4 +23,9 @@ public interface LoadBeanBuffer {
void configureQuery(SpiQuery<?> query, String lazyLoadProperty);
boolean isCache();
void loadingStarted();
void loadingStopped();
}
@@ -6,7 +6,13 @@ import io.ebeaninternal.api.SpiQuery.Mode;
import io.ebeaninternal.server.core.OrmQueryRequest;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import java.util.*;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static java.lang.System.Logger.Level.DEBUG;
/**
* Request for loading ManyToOne and OneToOne relationships.
@@ -18,12 +24,16 @@ public final class LoadBeanRequest extends LoadRequest {
private final String lazyLoadProperty;
private final boolean loadCache;
private final boolean alreadyLoaded;
private String triggerEbi;
private String batchBefore;
private List<Object> queryIds;
/**
* Construct for lazy load request.
*/
public LoadBeanRequest(LoadBeanBuffer loadBuffer, EntityBeanIntercept ebi, boolean loadCache) {
this(loadBuffer, null, true, ebi.lazyLoadProperty(), ebi.isLoaded(), loadCache || ebi.isLoadedFromCache());
this.triggerEbi = String.valueOf(ebi);
}
/**
@@ -53,16 +63,19 @@ public final class LoadBeanRequest extends LoadRequest {
}
/**
* Return the batch of beans to actually load.
* Return true if the batch is empty.
*/
public Set<EntityBeanIntercept> batch() {
return batch;
public boolean checkEmpty() {
loadBuffer.loadingStarted();
batchBefore = String.valueOf(batch);
queryIds = ids();
return batch.isEmpty();
}
/**
* Return the list of Id values for the beans in the lazy load buffer.
*/
public List<Object> ids() {
private List<Object> ids() {
final List<Object> idList = new ArrayList<>(batch.size());
final BeanDescriptor<?> desc = loadBuffer.descriptor();
for (EntityBeanIntercept ebi : batch) {
@@ -74,10 +87,10 @@ public final class LoadBeanRequest extends LoadRequest {
/**
* Configure the query for lazy loading execution.
*/
public void configureQuery(SpiQuery<?> query, List<Object> idList) {
public void configureQuery(SpiQuery<?> query) {
query.setMode(Mode.LAZYLOAD_BEAN);
query.setPersistenceContext(loadBuffer.persistenceContext());
query.setLoadDescription(lazy ? "+lazy" : "+query", description());
query.setLoadDescription(mode(), description());
if (lazy) {
query.setLazyLoadBatchSize(loadBuffer.batchSize());
if (alreadyLoaded) {
@@ -90,17 +103,22 @@ public final class LoadBeanRequest extends LoadRequest {
if (loadCache) {
query.setBeanCacheMode(CacheMode.PUT);
}
if (idList.size() == 1) {
query.where().idEq(idList.get(0));
if (queryIds.size() == 1) {
query.where().idEq(queryIds.get(0));
} else {
query.where().idIn(idList);
query.where().idIn(queryIds);
}
}
private String mode() {
return lazy ? "+lazy" : loadBuffer.isCache() ? "+cache" : "+query";
}
/**
* Load the beans into the L2 cache if that is requested and check for load failures due to deletes.
*/
public Result postLoad(List<?> list) {
public void postLoad(List<?> list) {
loadBuffer.loadingStopped();
Set<Object> loadedIds = new HashSet<>();
BeanDescriptor<?> desc = loadBuffer.descriptor();
// collect Ids and maybe load bean cache
@@ -118,45 +136,26 @@ public final class LoadBeanRequest extends LoadRequest {
// necessary but allow processing to continue until it is accessed by client code
Object id = desc.getId(ebi.owner());
if (!loadedIds.contains(id)) {
// assume this is logically deleted (hence not found)
desc.markAsDeleted(ebi.owner());
missedIds.add(id);
missed.add(ebi);
if (queryIds.contains(id)) {
// assume this is logically deleted (hence not found)
desc.markAsDeleted(ebi.owner());
} else {
// unexpected, added to batch during loading
missedIds.add(id);
missed.add(ebi);
}
}
if (!missed.isEmpty()) {
if (CoreLog.markedAsDeleted.isLoggable(DEBUG)) {
CoreLog.markedAsDeleted.log(DEBUG, "Loaded bean batch triggered by ebi:{0} property:{1}", triggerEbi, lazyLoadProperty);
CoreLog.markedAsDeleted.log(DEBUG, "Loaded bean batch BEFORE {0}", batchBefore);
CoreLog.markedAsDeleted.log(DEBUG, "Loaded bean batch AFTER {0}", batch);
String msg = MessageFormat.format("Bean added to batch during load for {0} missedIds:{1} queryIds:{2} missed:{3}",
beanType(), missedIds, queryIds, missed);
CoreLog.markedAsDeleted.log(DEBUG, msg, new RuntimeException("LoadBeanRequest - Bean added to batch during load"));
}
}
}
return new Result(loadedIds, missedIds, missed);
}
return EMPTY_RESULT;
}
static final Result EMPTY_RESULT = new Result(Collections.emptySet(),Collections.emptySet(), Collections.emptyList());
public static class Result {
private final Set<Object> loadedIds;
private final Set<Object> missedIds;
private final List<EntityBeanIntercept> missed;
Result(Set<Object> loadedIds, Set<Object> missedIds, List<EntityBeanIntercept> missed) {
this.loadedIds = loadedIds;
this.missedIds = missedIds;
this.missed = missed;
}
public boolean markedDeleted() {
return !missedIds.isEmpty();
}
public Set<Object> missedIds() {
return missedIds;
}
public Set<Object> loadedIds() {
return loadedIds;
}
public List<EntityBeanIntercept> missed() {
return missed;
}
}
}
@@ -2,14 +2,16 @@ package io.ebeaninternal.api;
import io.ebean.meta.MetaQueryPlan;
import java.time.Instant;
/**
* Internal database query plan being capture.
*/
public interface SpiDbQueryPlan extends MetaQueryPlan {
/**
* Extend with queryTimeMicros and captureCount.
* Extend with queryTimeMicros, captureCount, captureMicros and when the bind values were captured.
*/
SpiDbQueryPlan with(long queryTimeMicros, long captureCount);
SpiDbQueryPlan with(long queryTimeMicros, long captureCount, long captureMicros, Instant whenCaptured);
}
@@ -1,5 +1,6 @@
package io.ebeaninternal.api;
import io.avaje.lang.Nullable;
import io.ebean.*;
import io.ebean.bean.BeanCollectionLoader;
import io.ebean.bean.CallOrigin;
@@ -14,7 +15,6 @@ import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.query.CQuery;
import io.ebeaninternal.server.transaction.RemoteTransactionEvent;
import javax.annotation.Nullable;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -14,12 +14,9 @@ import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
import io.ebeaninternal.server.transaction.DefaultPersistenceContext;
import javax.persistence.EntityNotFoundException;
import java.text.MessageFormat;
import java.util.List;
import java.util.Set;
import static java.lang.System.Logger.Level.DEBUG;
import static java.lang.System.Logger.Level.ERROR;
/**
* Helper to handle lazy loading and refreshing of beans.
@@ -126,28 +123,12 @@ final class DefaultBeanLoader {
* Load a batch of beans for +query or +lazy loading.
*/
void loadBean(LoadBeanRequest loadRequest) {
final Set<EntityBeanIntercept> batch = loadRequest.batch();
if (batch.isEmpty()) {
if (loadRequest.checkEmpty()) {
throw new RuntimeException("Nothing in batch?");
}
final List<Object> ids = loadRequest.ids();
if (ids.isEmpty()) {
// this should never happen given the batch is not empty
CoreLog.internal.log(ERROR, "No Ids when loading Batch buffer");
return;
}
final SpiQuery<?> query = server.createQuery(loadRequest.beanType());
loadRequest.configureQuery(query, ids);
final List<?> list = executeQuery(loadRequest, query);
final LoadBeanRequest.Result result = loadRequest.postLoad(list);
if (result.markedDeleted() && CoreLog.markedAsDeleted.isLoggable(DEBUG)) {
CoreLog.markedAsDeleted.log(DEBUG, "Loaded bean batch {0}", batch);
String msg = MessageFormat.format("Loaded bean marked as deleted for {0} ids:{1} missedIds:{2} loadedIds:{3} sql:{4} loadedList:{5} missed:{6}",
loadRequest.beanType(), ids, result.missedIds(), result.loadedIds(), query.getGeneratedSql(), list, result.missed());
CoreLog.markedAsDeleted.log(DEBUG, msg, new RuntimeException("LoadBeanRequest markedAsDeleted"));
}
loadRequest.configureQuery(query);
loadRequest.postLoad(executeQuery(loadRequest, query));
}
/**
@@ -137,7 +137,7 @@ public final class DefaultContainer implements SpiContainer {
private void checkMissingModulePathProvides() {
URL servicesFile = ClassLoader.getSystemResource("META-INF/services/io.ebean.config.EntityClassRegister");
if (servicesFile != null) {
log.log(ERROR, "module-info.java is probably missing 'provides io.ebean.config.EntityClassRegister with EbeanEntityRegister' clause. EntityClassRegister exists but was not service loaded.");
log.log(ERROR, "module-info.java is probably missing ''provides io.ebean.config.EntityClassRegister with EbeanEntityRegister'' clause. EntityClassRegister exists but was not service loaded.");
}
}
@@ -18,9 +18,9 @@ final class DefaultQueryPlanListener implements QueryPlanListener {
// better to log this in JSON form?
String dbName = capture.database().name();
for (MetaQueryPlan plan : capture.plans()) {
log.log(INFO, "queryPlan db:{0} label:{1} queryTimeMicros:{2} loc:{3} sql:{4} bind:{5} plan:{6}",
dbName, plan.label(), plan.queryTimeMicros(), plan.profileLocation(),
plan.sql(), plan.bind(), plan.plan());
log.log(INFO, "queryPlan db:{0} label:{1} queryTimeMicros:{2} captureMicros:{3} whenCaptured:{4} captureCount:{5} loc:{6} sql:{7} bind:{8} plan:{9}",
dbName, plan.label(), plan.queryTimeMicros(), plan.captureMicros(), plan.whenCaptured(), plan.captureCount(),
plan.profileLocation(), plan.sql(), plan.bind(), plan.plan());
}
}
}
@@ -45,13 +45,14 @@ import io.ebeaninternal.util.ParamTypeHelper;
import io.ebeaninternal.util.ParamTypeHelper.TypeInfo;
import io.ebeanservice.docstore.api.DocStoreIntegration;
import javax.persistence.EntityNotFoundException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.Clock;
import java.util.*;
import java.util.concurrent.Callable;
@@ -559,9 +560,9 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
private void executeSql(Connection connection, @Nullable String sql) throws SQLException {
if (sql != null) {
try (PreparedStatement stmt = connection.prepareStatement(sql)) {
try (Statement stmt = connection.createStatement()) {
transactionManager.log().sql().debug(sql);
stmt.execute();
stmt.execute(sql);
}
}
}
@@ -586,7 +587,11 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
*/
@Override
public <T> T createEntityBean(Class<T> type) {
return descriptor(type).createBean();
final BeanDescriptor<T> desc = descriptor(type);
if (desc == null) {
throw new IllegalArgumentException("No bean type " + type.getName() + " registered");
}
return desc.createBean();
}
/**
@@ -626,7 +631,11 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
// we actually need to do a query because we don't know the type without the discriminator
// value, just select the id property and discriminator column (auto added)
return find(type).select(idProp.name()).setId(id).findOne();
T bean = find(type).select(idProp.name()).setId(id).findOne();
if (bean == null) {
throw new EntityNotFoundException("Could not find reference bean " + id + " for " + desc);
}
return bean;
}
@Override
@@ -873,13 +882,13 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
public <T> DtoQuery<T> findDto(Class<T> dtoType, String sql) {
DtoBeanDescriptor<T> descriptor = dtoBeanManager.getDescriptor(dtoType);
DtoBeanDescriptor<T> descriptor = dtoBeanManager.descriptor(dtoType);
return new DefaultDtoQuery<>(this, descriptor, sql.trim());
}
@Override
public <T> DtoQuery<T> createNamedDtoQuery(Class<T> dtoType, String namedQuery) {
DtoBeanDescriptor<T> descriptor = dtoBeanManager.getDescriptor(dtoType);
DtoBeanDescriptor<T> descriptor = dtoBeanManager.descriptor(dtoType);
String sql = descriptor.getNamedRawSql(namedQuery);
if (sql == null) {
throw new PersistenceException("No named query called " + namedQuery + " for bean:" + dtoType.getName());
@@ -889,7 +898,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
public <T> DtoQuery<T> findDto(Class<T> dtoType, SpiQuery<?> ormQuery) {
DtoBeanDescriptor<T> descriptor = dtoBeanManager.getDescriptor(dtoType);
DtoBeanDescriptor<T> descriptor = dtoBeanManager.descriptor(dtoType);
return new DefaultDtoQuery<>(this, descriptor, ormQuery);
}
@@ -2167,7 +2176,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
if (idProperty == null) {
return Collections.emptySet();
}
Object id = idProperty.value(entityBean);
Object id = idProperty.getValue(entityBean);
if (entityBean._ebean_getIntercept().isNew() && id != null) {
// Primary Key is changeable only on new models - so skip check if we are not new
Query<?> query = new DefaultOrmQuery<>(beanDesc, this, expressionFactory);
@@ -2195,10 +2204,10 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
ExpressionList<?> exprList = query.where();
if (!entityBean._ebean_getIntercept().isNew()) {
// if model is not new, exclude ourself.
exprList.ne(idProperty.name(), idProperty.value(entityBean));
exprList.ne(idProperty.name(), idProperty.getValue(entityBean));
}
for (Property prop : props) {
Object value = prop.value(entityBean);
for (BeanProperty prop : props) {
Object value = prop.getValue(entityBean);
if (value == null) {
return null;
}
@@ -768,7 +768,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
// find a join to that table...
DeployBeanPropertyAssocOne<?> assocOne = descriptor.findJoinToTable(tableName);
if (assocOne == null) {
String msg = "Error with property " + prop.getFullBeanName() + ". Could not find a Relationship to table " + tableName
String msg = "Error with property " + prop+ ". Could not find a Relationship to table " + tableName
+ ". Perhaps you could use a @JoinColumn instead.";
throw new RuntimeException(msg);
}
@@ -811,7 +811,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
Class<?> targetType = prop.getTargetType();
DeployBeanInfo<?> info = deployInfoMap.get(targetType);
if (info == null) {
throw new PersistenceException("Can not find descriptor [" + targetType + "] for " + prop.getFullBeanName());
throw new PersistenceException("Can not find descriptor [" + targetType + "] for " + prop);
}
return info.getDescriptor();
}
@@ -874,7 +874,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
}
}
// multiple options so should specify mappedBy property
String msg = "Error on " + prop.getFullBeanName() + " missing mappedBy.";
String msg = "Error on " + prop + " missing mappedBy.";
msg += " There are [" + matchSet.size() + "] possible properties in " + targetDesc;
msg += " that this association could be mapped to. Please specify one using ";
msg += "the mappedBy attribute on @OneToMany.";
@@ -919,7 +919,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
if (!oneToMany.getCascadeInfo().isSave()) {
// The property MUST have persist cascading so that inserts work.
Class<?> targetType = oneToMany.getTargetType();
String msg = "Error on " + oneToMany.getFullBeanName() + ". @OneToMany MUST have ";
String msg = "Error on " + oneToMany + ". @OneToMany MUST have ";
msg += "Cascade.PERSIST or Cascade.ALL because this is a unidirectional ";
msg += "relationship. That is, there is no property of type " + owningType + " on " + targetType;
throw new PersistenceException(msg);
@@ -983,14 +983,14 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
private DeployBeanPropertyAssocOne<?> mappedOneToOne(DeployBeanPropertyAssocOne<?> prop, String mappedBy, DeployBeanDescriptor<?> targetDesc) {
DeployBeanProperty mappedProp = targetDesc.getBeanProperty(mappedBy);
if (mappedProp == null) {
throw new PersistenceException("Error on " + prop.getFullBeanName() + " Can not find mappedBy property " + targetDesc + "." + mappedBy);
throw new PersistenceException("Error on " + prop + " Can not find mappedBy property " + targetDesc + "." + mappedBy);
}
if (!(mappedProp instanceof DeployBeanPropertyAssocOne<?>)) {
throw new PersistenceException("Error on " + prop.getFullBeanName() + ". mappedBy property " + targetDesc + "." + mappedBy + " is not a OneToOne?");
throw new PersistenceException("Error on " + prop + ". mappedBy property " + targetDesc + "." + mappedBy + " is not a OneToOne?");
}
DeployBeanPropertyAssocOne<?> mappedAssocOne = (DeployBeanPropertyAssocOne<?>) mappedProp;
if (!mappedAssocOne.isOneToOne()) {
throw new PersistenceException("Error on " + prop.getFullBeanName() + ". mappedBy property " + targetDesc + "." + mappedBy + " is not a OneToOne?");
throw new PersistenceException("Error on " + prop + ". mappedBy property " + targetDesc + "." + mappedBy + " is not a OneToOne?");
}
return mappedAssocOne;
}
@@ -1073,10 +1073,10 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
private DeployBeanPropertyAssocOne<?> mappedManyToOne(DeployBeanPropertyAssocMany<?> prop, DeployBeanDescriptor<?> targetDesc, String mappedBy) {
DeployBeanProperty mappedProp = targetDesc.getBeanProperty(mappedBy);
if (mappedProp == null) {
throw new PersistenceException("Error on " + prop.getFullBeanName() + " Can not find mappedBy property " + mappedBy + " in " + targetDesc);
throw new PersistenceException("Error on " + prop + " Can not find mappedBy property " + mappedBy + " in " + targetDesc);
}
if (!(mappedProp instanceof DeployBeanPropertyAssocOne<?>)) {
throw new PersistenceException("Error on " + prop.getFullBeanName() + ". mappedBy property " + mappedBy + " is not a ManyToOne? in " + targetDesc);
throw new PersistenceException("Error on " + prop + ". mappedBy property " + mappedBy + " is not a ManyToOne? in " + targetDesc);
}
return (DeployBeanPropertyAssocOne<?>) mappedProp;
}
@@ -1124,15 +1124,15 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
private DeployBeanPropertyAssocMany<?> mappedManyToMany(DeployBeanPropertyAssocMany<?> prop, String mappedBy, DeployBeanDescriptor<?> targetDesc) {
DeployBeanProperty mappedProp = targetDesc.getBeanProperty(mappedBy);
if (mappedProp == null) {
throw new PersistenceException("Error on " + prop.getFullBeanName() + " Can not find mappedBy property " + mappedBy + " in " + targetDesc);
throw new PersistenceException("Error on " + prop + " Can not find mappedBy property " + mappedBy + " in " + targetDesc);
}
if (!(mappedProp instanceof DeployBeanPropertyAssocMany<?>)) {
throw new PersistenceException("Error on " + prop.getFullBeanName() + ". mappedBy property " + targetDesc + "." + mappedBy + " is not a ManyToMany?");
throw new PersistenceException("Error on " + prop + ". mappedBy property " + targetDesc + "." + mappedBy + " is not a ManyToMany?");
}
DeployBeanPropertyAssocMany<?> mappedAssocMany = (DeployBeanPropertyAssocMany<?>) mappedProp;
if (!mappedAssocMany.isManyToMany()) {
throw new PersistenceException("Error on " + prop.getFullBeanName() + ". mappedBy property " + targetDesc + "." + mappedBy + " is not a ManyToMany?");
throw new PersistenceException("Error on " + prop + ". mappedBy property " + targetDesc + "." + mappedBy + " is not a ManyToMany?");
}
return mappedAssocMany;
}
@@ -756,7 +756,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
@Override
public Object value(Object bean) {
return getValue((EntityBean) bean);
return getValueIntercept((EntityBean) bean);
}
/**
@@ -203,7 +203,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
*/
@SuppressWarnings("rawtypes")
public Collection rawCollection(EntityBean bean) {
return help.underlying(value(bean));
return help.underlying(getValue(bean));
}
/**
@@ -211,11 +211,11 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
*/
@Override
public void merge(EntityBean bean, EntityBean existing) {
Object existingCollection = value(existing);
Object existingCollection = getValue(existing);
if (existingCollection instanceof BeanCollection<?>) {
BeanCollection<?> toBC = (BeanCollection<?>) existingCollection;
if (!toBC.isPopulated()) {
Object fromCollection = value(bean);
Object fromCollection = getValue(bean);
if (fromCollection instanceof BeanCollection<?>) {
BeanCollection<?> fromBC = (BeanCollection<?>) fromCollection;
if (fromBC.isPopulated()) {
@@ -51,7 +51,7 @@ class BeanPropertyAssocManyJsonHelp {
throw new JsonParseException(parser, "Unexpected token " + event + " - expecting start array or object");
}
if (readJson.update()) {
many.setValueIntercept(parentBean, many.jsonReadCollection(readJson, parentBean, many.value(parentBean)));
many.setValueIntercept(parentBean, many.jsonReadCollection(readJson, parentBean, many.getValue(parentBean)));
} else {
many.setValue(parentBean, many.jsonReadCollection(readJson, parentBean, null));
}
@@ -788,7 +788,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
public void jsonRead(SpiJsonReader readJson, EntityBean bean) throws IOException {
if (jsonDeserialize && targetDescriptor != null) {
// CHECKME: may we skip reading the object from the json stream?
T target = readJson.update() ? (T) value(bean) : null;
T target = readJson.update() ? (T) getValue(bean) : null;
T assocBean = targetDescriptor.jsonRead(readJson, name, target);
if (readJson.update()) {
setValueIntercept(bean, assocBean);
@@ -222,10 +222,6 @@ public class DeployBeanProperty {
|| AnnotationUtil.has(field, WhoCreated.class));
}
public String getFullBeanName() {
return desc.getFullName() + "." + name;
}
public DeployBeanDescriptor<?> getDesc() {
return desc;
}
@@ -23,7 +23,7 @@ abstract class AnnotationAssoc extends AnnotationParser {
void setBeanTable(DeployBeanPropertyAssoc<?> prop) {
BeanTable assoc = getBeanTable(prop);
if (assoc == null) {
throw new BeanNotRegisteredException(errorMsgMissingBeanTable(prop.getTargetType(), prop.getFullBeanName()));
throw new BeanNotRegisteredException(errorMsgMissingBeanTable(prop.getTargetType(), prop.toString()));
}
prop.setBeanTable(assoc);
}
@@ -167,7 +167,7 @@ final class AnnotationAssocManys extends AnnotationAssoc {
private void checkSelfManyToMany(DeployBeanPropertyAssocMany<?> prop) {
if (prop.getTargetType().equals(descriptor.getBeanType())) {
throw new IllegalStateException("@ManyToMany mapping for " + prop.getFullBeanName() + " requires explicit @JoinTable with joinColumns & inverseJoinColumns. Refer issue #2157");
throw new IllegalStateException("@ManyToMany mapping for " + prop + " requires explicit @JoinTable with joinColumns & inverseJoinColumns. Refer issue #2157");
}
}
@@ -266,8 +266,7 @@ final class AnnotationAssocManys extends AnnotationAssoc {
elementDescriptor.addBeanProperty(valueProp);
}
elementDescriptor.setName(prop.getFullBeanName());
elementDescriptor.setName(prop.toString());
factory.createUnidirectional(elementDescriptor, prop.getOwningType(), beanTable, prop.getTableJoin());
prop.setElementDescriptor(factory.createElementDescriptor(elementDescriptor, prop.getManyType(), scalar));
}
@@ -148,7 +148,7 @@ final class AnnotationAssocOnes extends AnnotationAssoc {
private void setFromJoinColumn(DeployBeanPropertyAssocOne<?> prop, BeanTable beanTable, JoinColumn joinColumn) {
if (beanTable == null) {
throw new IllegalStateException("Looks like a missing @ManyToOne or @OneToOne on property " + prop.getFullBeanName() + " - no related 'BeanTable'");
throw new IllegalStateException("Looks like a missing @ManyToOne or @OneToOne on property " + prop + " - no related 'BeanTable'");
}
prop.getTableJoin().addJoinColumn(util, false, joinColumn, beanTable);
if (!joinColumn.updatable()) {
@@ -210,15 +210,15 @@ final class AnnotationAssocOnes extends AnnotationAssoc {
private void readPrimaryKeyJoin(PrimaryKeyJoinColumn primaryKeyJoin, DeployBeanPropertyAssocOne<?> prop) {
if (!prop.isOneToOne()) {
throw new IllegalStateException("Expecting property " + prop.getFullBeanName() + " with PrimaryKeyJoinColumn to be a OneToOne?");
throw new IllegalStateException("Expecting property " + prop + " with PrimaryKeyJoinColumn to be a OneToOne?");
}
prop.setPrimaryKeyJoin(true);
if (!primaryKeyJoin.name().isEmpty()) {
CoreLog.internal.log(INFO, "Automatically determining join columns for @PrimaryKeyJoinColumn - ignoring PrimaryKeyJoinColumn.name attribute [{0}] on {1}", primaryKeyJoin.name(), prop.getFullBeanName());
CoreLog.internal.log(INFO, "Automatically determining join columns for @PrimaryKeyJoinColumn - ignoring PrimaryKeyJoinColumn.name attribute [{0}] on {1}", primaryKeyJoin.name(), prop);
}
if (!primaryKeyJoin.referencedColumnName().isEmpty()) {
CoreLog.internal.log(INFO, "Automatically determining join columns for @PrimaryKeyJoinColumn - Ignoring PrimaryKeyJoinColumn.referencedColumnName attribute [{0}] on {1}", primaryKeyJoin.referencedColumnName(), prop.getFullBeanName());
CoreLog.internal.log(INFO, "Automatically determining join columns for @PrimaryKeyJoinColumn - Ignoring PrimaryKeyJoinColumn.referencedColumnName attribute [{0}] on {1}", primaryKeyJoin.referencedColumnName(), prop);
}
BeanTable baseBeanTable = factory.beanTable(info.getDescriptor().getBeanType());
String localPrimaryKey = baseBeanTable.getIdColumn();
@@ -384,7 +384,7 @@ final class AnnotationFields extends AnnotationParser {
}
private void setEncryption(DeployBeanProperty prop, boolean dbEncString, int dbLen) {
util.checkEncryptKeyManagerDefined(prop.getFullBeanName());
util.checkEncryptKeyManagerDefined(prop.toString());
ScalarType<?> st = prop.getScalarType();
if (byte[].class.equals(st.type())) {
// Always using Java client encryption rather than DB for encryption
@@ -83,7 +83,7 @@ public final class DeployCreateProperties {
DeployBeanProperty replaced = desc.addBeanProperty(prop);
if (replaced != null && !replaced.isTransient()) {
String msg = "Huh??? property " + prop.getFullBeanName() + " being defined twice";
String msg = "Huh??? property " + prop + " being defined twice";
msg += " but replaced property was not transient? This is not expected?";
CoreLog.log.log(WARNING, msg);
}
@@ -106,7 +106,7 @@ public final class DeployUtil {
prop.setScalarType(scalarType);
prop.setDbType(scalarType.jdbcType());
} catch (IllegalStateException e) {
throw new PersistenceException("Error mapping property " + prop.getFullBeanName() + " - " + e.getMessage());
throw new PersistenceException("Error mapping property " + prop + " - " + e.getMessage());
}
}
@@ -141,7 +141,7 @@ public final class DeployUtil {
if (scalarType != null || property.isTransient()) {
return scalarType;
}
throw new PersistenceException(property.getFullBeanName() + " has no ScalarType - type " + propType.getName());
throw new PersistenceException(property + " has no ScalarType - type " + propType.getName());
} catch (IllegalArgumentException e) {
if (property.isTransient()) {
// expected for transient properties with unknown/non-mapped types
@@ -179,7 +179,7 @@ public final class DeployUtil {
Class<?> type = prop.getPropertyType();
ScalarType<?> scalarType = typeManager.dbArrayType(type, prop.getGenericType(), prop.isNullable());
if (scalarType == null) {
throw new RuntimeException("No ScalarType for @DbArray type for " + prop.getFullBeanName());
throw new RuntimeException("No ScalarType for @DbArray type for " + prop);
}
int dbType = scalarType.jdbcType();
prop.setDbType(dbType);
@@ -21,11 +21,11 @@ public final class DtoBeanDescriptor<T> {
this.namedQueries = namedQueries;
}
public Class<T> getType() {
public Class<T> type() {
return dtoType;
}
public DtoQueryPlan getQueryPlan(Object planKey) {
public DtoQueryPlan queryPlan(Object planKey) {
return plans.get(planKey);
}
@@ -28,13 +28,11 @@ public final class DtoBeanManager {
* Return the descriptor for the given DTO bean class.
*/
@SuppressWarnings("unchecked")
public <T> DtoBeanDescriptor<T> getDescriptor(Class<T> dtoType) {
public <T> DtoBeanDescriptor<T> descriptor(Class<T> dtoType) {
return descriptorMap.computeIfAbsent(dtoType, this::createDescriptor);
}
private <T> DtoBeanDescriptor createDescriptor(Class<T> dtoType) {
try {
DtoMeta meta = new DtoMetaBuilder(dtoType, typeManager).build();
return new DtoBeanDescriptor<>(dtoType, meta, namedQueries(dtoType));
@@ -11,7 +11,7 @@ public final class DtoColumn {
this.label = label;
}
public String getLabel() {
public String label() {
return label;
}
@@ -26,19 +26,19 @@ public final class DtoMappingRequest {
this.columnMeta = columnMeta;
}
public DtoColumn[] getColumnMeta() {
public DtoColumn[] columnMeta() {
return columnMeta;
}
public boolean isRelaxedMode() {
public boolean relaxedMode() {
return relaxedMode;
}
public String getLabel() {
public String label() {
return label;
}
public String getSql() {
public String sql() {
return sql;
}
@@ -70,10 +70,10 @@ public final class DtoMappingRequest {
}
private DtoReadSet mapColumn(int pos, DtoMeta meta) {
String label = columnMeta[pos].getLabel();
String label = columnMeta[pos].label();
DtoReadSet property = meta.findProperty(label);
if (property == null || property.isReadOnly()) {
if (isRelaxedMode()) {
if (relaxedMode()) {
property = DtoReadSetColumnSkip.INSTANCE;
} else {
throw new IllegalStateException(unableToMapColumnMessage(columnMeta[pos], meta));
@@ -1,9 +1,6 @@
package io.ebeaninternal.server.dto;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* Holds property and constructor meta-data for a given DTO bean type.
@@ -18,16 +15,16 @@ final class DtoMeta {
private final DtoMetaConstructor defaultConstructor;
private final DtoMetaConstructor maxArgConstructor;
DtoMeta(Class<?> dtoType, List<DtoMetaConstructor> constructors, List<DtoMetaProperty> properties) {
DtoMeta(Class<?> dtoType, Collection<DtoMetaConstructor> constructors, List<DtoMetaProperty> properties) {
this.dtoType = dtoType;
for (DtoMetaProperty property : properties) {
propMap.put(property.getName().toUpperCase(), property);
propMap.put(property.name().toUpperCase(), property);
}
int maxArg = 0;
DtoMetaConstructor defaultConstructor = null;
DtoMetaConstructor maxArgConstructor = null;
for (DtoMetaConstructor constructor : constructors) {
int args = constructor.getArgCount();
int args = constructor.argCount();
constructorMap.put(args, constructor);
if (args == 0) {
defaultConstructor = constructor;
@@ -41,13 +38,13 @@ final class DtoMeta {
}
public DtoQueryPlan match(DtoMappingRequest request) {
DtoColumn[] cols = request.getColumnMeta();
DtoColumn[] cols = request.columnMeta();
int colLen = cols.length;
DtoMetaConstructor constructor = constructorMap.get(colLen);
if (constructor != null) {
return new DtoQueryPlanConstructor(request, constructor);
}
if (maxArgConstructor != null && colLen > maxArgConstructor.getArgCount()) {
if (maxArgConstructor != null && colLen > maxArgConstructor.argCount()) {
// maxArgConst + setters
return matchMaxArgPlusSetters(request);
}
@@ -61,7 +58,7 @@ final class DtoMeta {
}
private DtoQueryPlanConPlus matchMaxArgPlusSetters(DtoMappingRequest request) {
DtoReadSet[] setterProps = request.mapArgPlusSetters(this, maxArgConstructor.getArgCount());
DtoReadSet[] setterProps = request.mapArgPlusSetters(this, maxArgConstructor.argCount());
return new DtoQueryPlanConPlus(request, maxArgConstructor, setterProps);
}
@@ -6,8 +6,7 @@ import io.ebeaninternal.server.type.TypeManager;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import static java.lang.System.Logger.Level.DEBUG;
@@ -21,7 +20,7 @@ final class DtoMetaBuilder {
private final TypeManager typeManager;
private final Class<?> dtoType;
private final List<DtoMetaProperty> properties = new ArrayList<>();
private final List<DtoMetaConstructor> constructorList = new ArrayList<>();
private final Map<Integer, DtoMetaConstructor> constructorMap = new HashMap<>();
DtoMetaBuilder(Class<?> dtoType, TypeManager typeManager) {
this.dtoType = dtoType;
@@ -31,7 +30,7 @@ final class DtoMetaBuilder {
DtoMeta build() {
readConstructors();
readProperties();
return new DtoMeta(dtoType, constructorList, properties);
return new DtoMeta(dtoType, constructorMap.values(), properties);
}
private void readProperties() {
@@ -74,14 +73,23 @@ final class DtoMetaBuilder {
}
private void readConstructors() {
final Set<Integer> removal = new HashSet<>();
for (Constructor<?> constructor : dtoType.getConstructors()) {
try {
constructorList.add(new DtoMetaConstructor(typeManager, constructor, dtoType));
final var meta = new DtoMetaConstructor(typeManager, constructor, dtoType);
final var conflicting = constructorMap.put(meta.argCount(), meta);
if (conflicting != null) {
removal.add(meta.argCount());
}
} catch (Exception e) {
// we don't want that constructor
CoreLog.log.log(DEBUG, "exclude on " + dtoType + " constructor " + constructor, e);
}
}
// remove the constructors that conflicted by argument count
for (Integer key : removal) {
constructorMap.remove(key);
}
}
}
@@ -30,11 +30,7 @@ final class DtoMetaConstructor {
return MethodType.methodType(void.class, types);
}
Class<?>[] getTypes() {
return types;
}
int getArgCount() {
int argCount() {
return types.length;
}
@@ -44,7 +44,7 @@ final class DtoMetaProperty implements DtoReadSet {
return method.getParameterTypes()[0];
}
String getName() {
String name() {
return name;
}
@@ -130,7 +130,7 @@ public class UuidV1IdGenerator extends UuidV1RndIdGenerator {
saveState();
log.log(DEBUG, "Saved state: clockSeq {0}, timestamp {1}, uuid {2}, stateFile: {3})", clockSeq.get(), new Date(ts), uuid, stateFile);
} catch (IOException e) {
log.log(ERROR, "There was a problem while detecting the nodeId. Falling back to random mode. Try using to specify 'ebean.uuidNodeId' property", e);
log.log(ERROR, "There was a problem while detecting the nodeId. Falling back to random mode. Try using to specify ''ebean.uuidNodeId'' property", e);
useRandomMode();
}
}
@@ -147,7 +147,7 @@ public class UuidV1IdGenerator extends UuidV1RndIdGenerator {
try {
nodeId = getHardwareId();
} catch (IOException e) {
log.log(ERROR, "Error while reading MAC address. Fall back to 'generate' mode", e);
log.log(ERROR, "Error while reading MAC address. Fall back to ''generate'' mode", e);
tryGenerateMode();
}
@@ -156,7 +156,7 @@ public class UuidV1IdGenerator extends UuidV1RndIdGenerator {
log.log(INFO, "Using MAC {0} to generate Type 1 UUIDs", getNodeIdentifier());
return;
}
log.log(WARNING, "No suitable network interface found. Fall back to 'generate' mode");
log.log(WARNING, "No suitable network interface found. Fall back to ''generate'' mode");
tryGenerateMode();
}
@@ -212,7 +212,7 @@ public class UuidV1IdGenerator extends UuidV1RndIdGenerator {
String propNodeId = prop.getProperty("nodeId");
if (propNodeId == null || propNodeId.isEmpty()) {
log.log(WARNING, "State file '{0}' is incomplete", stateFile);
log.log(WARNING, "State file ''{0}'' is incomplete", stateFile);
return false; // we cannot restore
}
try {
@@ -220,7 +220,7 @@ public class UuidV1IdGenerator extends UuidV1RndIdGenerator {
nodeId = parseAlternativeNodeId(propNodeId);
} else if (!getNodeIdentifier().equals(propNodeId)) {
log.log(WARNING,
"The nodeId in the state file '{0}' has changed from {1} to {2}. "
"The nodeId in the state file ''{0}'' has changed from {1} to {2}. "
+ "This can happen when MAC address changes or when two containers share the same state file",
stateFile, propNodeId, getNodeIdentifier());
return false;
@@ -52,7 +52,7 @@ abstract class DLoadBaseContext {
void setLabel(SpiQuery<?> query) {
String label = parent.planLabel();
if (label != null) {
query.setProfilePath(label, fullPath, parent.profileLocation());
query.setProfilePath(label, fullPath + "(" + query.getLoadMode() + ")", parent.profileLocation());
}
}
@@ -5,22 +5,23 @@ import io.ebean.bean.BeanCollection;
import io.ebean.bean.BeanLoader;
import io.ebean.bean.EntityBeanIntercept;
import io.ebean.bean.PersistenceContext;
import io.ebeaninternal.api.LoadBeanBuffer;
import io.ebeaninternal.api.LoadBeanContext;
import io.ebeaninternal.api.LoadBeanRequest;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.api.*;
import io.ebeaninternal.server.core.OrmQueryRequest;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
import io.ebeaninternal.server.querydefn.OrmQueryProperties;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import static java.lang.System.Logger.Level.DEBUG;
/**
* ToOne bean load context.
*/
@@ -71,6 +72,9 @@ final class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext
if (currentBuffer.isFull()) {
currentBuffer = createBuffer(batchSize);
}
if (currentBuffer.addWhenLoading()) {
CoreLog.markedAsDeleted.log(DEBUG, "Adding " + ebi + " to batch " + currentBuffer + " after loadingStarted(1)", new RuntimeException("Adding to batch after load(1)"));
}
ebi.setBeanLoader(currentBuffer, persistenceContext());
currentBuffer.add(ebi);
}
@@ -117,6 +121,7 @@ final class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext
private final DLoadBeanContext context;
private final int batchSize;
private final Set<EntityBeanIntercept> batch;
private final Instant whenCreated = Instant.now();
private PersistenceContext persistenceContext;
LoadBuffer(DLoadBeanContext context, int batchSize) {
@@ -127,7 +132,8 @@ final class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext
@Override
public String toString() {
return "LoadBuffer@" + hashCode();
return "LoadBuffer@" + hashCode() + ":" + whenCreated + ":size=" + batch.size()
+":locked=" +bufferLock.isLocked()+ "/currentThread=" + bufferLock.isHeldByCurrentThread();
}
@Override
@@ -148,6 +154,10 @@ final class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext
return batchSize == batch.size();
}
final boolean addWhenLoading() {
return loadingStarted.get() && CoreLog.markedAsDeleted.isLoggable(DEBUG);
}
/**
* Add the bean to the load buffer.
*/
@@ -189,6 +199,23 @@ final class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext
context.configureQuery(query, lazyLoadProperty);
}
@Override
public boolean isCache() {
return context.cache;
}
private final AtomicBoolean loadingStarted = new AtomicBoolean();
@Override
public void loadingStarted() {
loadingStarted.set(true);
}
@Override
public void loadingStopped() {
loadingStarted.set(false);
}
@Override
public void loadBean(EntityBeanIntercept ebi) {
// A lock is effectively held by EntityBeanIntercept.loadBean()
@@ -198,6 +225,11 @@ final class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext
}
if (!batch.contains(ebi)) {
// re-add to the batch and lazy load from DB skipping l2 cache
if (loadingStarted.get()) {
if (CoreLog.markedAsDeleted.isLoggable(DEBUG)) {
CoreLog.markedAsDeleted.log(DEBUG, "Adding " + ebi + "to batch " + this + "after loadingStarted(2) ", new RuntimeException("Adding to batch after load(2"));
}
}
batch.add(ebi);
} else if (context.hitCache) {
Set<EntityBeanIntercept> hits = context.desc.cacheBeanLoadAll(batch, persistenceContext, ebi.lazyLoadPropertyIndex(), ebi.lazyLoadProperty());
@@ -208,8 +240,7 @@ final class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext
}
}
LoadBeanRequest req = new LoadBeanRequest(this, ebi, context.hitCache);
context.desc.ebeanServer().loadBean(req);
context.desc.ebeanServer().loadBean(new LoadBeanRequest(this, ebi, context.hitCache));
batch.clear();
}
}
@@ -55,6 +55,6 @@ final class MergeNodeAssocOne extends MergeNode {
}
private EntityBean getEntityBean(Object bean) {
return (EntityBean) one.value(bean);
return (EntityBean) one.getValue((EntityBean)bean);
}
}
@@ -5,6 +5,8 @@ import io.ebeaninternal.api.SpiQueryBindCapture;
import io.ebeaninternal.api.SpiQueryPlan;
import io.ebeaninternal.server.bind.capture.BindCapture;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
final class CQueryBindCapture implements SpiQueryBindCapture {
@@ -53,9 +55,14 @@ final class CQueryBindCapture implements SpiQueryBindCapture {
@Override
public void queryPlanInit(long thresholdMicros) {
// effective enable bind capture for this plan
this.thresholdMicros = thresholdMicros;
this.captureCount = 0;
lock.lock();
try {
// effective enable bind capture for this plan
this.thresholdMicros = thresholdMicros;
this.captureCount = 0;
} finally {
lock.unlock();
}
}
/**
@@ -67,11 +74,13 @@ final class CQueryBindCapture implements SpiQueryBindCapture {
return false;
}
final Instant whenCaptured = Instant.ofEpochMilli(this.lastBindCapture);
final BindCapture last = this.bindCapture;
final long startNanos = System.nanoTime();
SpiDbQueryPlan queryPlan = manager.collectPlan(request.connection(), this.queryPlan, last);
if (queryPlan != null) {
request.add(queryPlan.with(queryTimeMicros, captureCount));
final long captureMicros = TimeUnit.MICROSECONDS.convert(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
request.add(queryPlan.with(queryTimeMicros, captureCount, captureMicros, whenCaptured));
// effectively turn off bind capture for this plan
thresholdMicros = Long.MAX_VALUE;
return true;
@@ -4,6 +4,8 @@ import io.ebean.ProfileLocation;
import io.ebean.meta.MetaQueryPlan;
import io.ebeaninternal.api.SpiDbQueryPlan;
import java.time.Instant;
/**
* Captured query plan details.
*/
@@ -19,6 +21,8 @@ final class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan {
private final String hash;
private long queryTimeMicros;
private long captureCount;
private long captureMicros;
private Instant whenCaptured;
DQueryPlanOutput(Class<?> beanType, String label, String hash, String sql, ProfileLocation profileLocation, String bind, String plan) {
this.beanType = beanType;
@@ -97,6 +101,16 @@ final class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan {
return captureCount;
}
@Override
public long captureMicros() {
return captureMicros;
}
@Override
public Instant whenCaptured() {
return whenCaptured;
}
@Override
public String toString() {
return " BeanType:" + ((beanType == null) ? "" : beanType.getSimpleName()) + " planHash:" + hash + " label:" + label + " queryTimeMicros:" + queryTimeMicros + " captureCount:" + captureCount + "\n SQL:" + sql + "\nBIND:" + bind + "\nPLAN:" + plan;
@@ -106,9 +120,11 @@ final class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan {
* Additionally set the query execution time and the number of bind captures.
*/
@Override
public DQueryPlanOutput with(long queryTimeMicros, long captureCount) {
public DQueryPlanOutput with(long queryTimeMicros, long captureCount, long captureMicros, Instant whenCaptured) {
this.queryTimeMicros = queryTimeMicros;
this.captureCount = captureCount;
this.captureMicros = captureMicros;
this.whenCaptured = whenCaptured;
return this;
}
}
@@ -147,6 +147,7 @@ class SqlTreeLoadBean implements SqlTreeLoad {
EntityBean contextBean;
SqlBeanLoad sqlBeanLoad;
boolean lazyLoadMany;
boolean usingContextBean;
private Load(DbReadContext ctx, EntityBean parentBean) {
this.ctx = ctx;
@@ -189,6 +190,7 @@ class SqlTreeLoadBean implements SqlTreeLoad {
contextBean = localBean;
} else {
// bean already exists in persistenceContext
usingContextBean = true;
if (ctx.isLoadContextBean()) {
// if explicitly set loadContextBean to true, then reload
localBean = contextBean;
@@ -247,7 +249,7 @@ class SqlTreeLoadBean implements SqlTreeLoad {
return queryMode == Mode.LAZYLOAD_MANY && isRoot();
}
private EntityBean getContextBean() {
private EntityBean contextBean() {
return contextBean;
}
@@ -278,13 +280,11 @@ class SqlTreeLoadBean implements SqlTreeLoad {
if (!partialObject) {
ebi.setFullyLoadedBean(true);
}
} else if (partialObject) {
if (readId) {
// register for lazy loading
ctx.register(null, ebi);
}
} else {
} else if (!partialObject) {
ebi.setFullyLoadedBean(true);
} else if (readId && !usingContextBean) {
// register for lazy loading if bean is new
ctx.register(null, ebi);
}
if (ctx.isAutoTuneProfiling() && !disableLazyLoad) {
@@ -358,7 +358,7 @@ class SqlTreeLoadBean implements SqlTreeLoad {
final EntityBean perform() throws SQLException {
initialise();
if (isLazyLoadManyRoot()) {
return getContextBean();
return contextBean();
}
postLoad();
setBeanToParent();
@@ -370,7 +370,7 @@ class SqlTreeLoadBean implements SqlTreeLoad {
* context we need to check if it is already contained in the collection.
*/
final boolean isContextBean() {
return localBean == null || queryMode == Mode.LAZYLOAD_BEAN;
return usingContextBean;
}
}
@@ -69,7 +69,7 @@ public final class DefaultDtoQuery<T> extends AbstractQuery implements SpiDtoQue
@Override
public DtoQueryPlan getQueryPlan(Object planKey) {
return descriptor.getQueryPlan(planKey);
return descriptor.queryPlan(planKey);
}
@Override
@@ -206,7 +206,7 @@ public final class DefaultDtoQuery<T> extends AbstractQuery implements SpiDtoQue
@Override
public Class<T> getType() {
return descriptor.getType();
return descriptor.type();
}
@Override
@@ -511,7 +511,7 @@ public final class DefaultTypeManager implements TypeManager {
ScalarTypeEnum<?> scalarEnum = (ScalarTypeEnum<?>) scalarType;
if (scalarEnum != null && !scalarEnum.isOverrideBy(type)) {
if (type != null && !scalarEnum.isCompatible(type)) {
throw new IllegalStateException("Error mapping Enum type:" + enumType + " It is mapped using 2 different modes when only one is supported (ORDINAL, STRING or an Ebean mapping)");
throw new IllegalStateException("Error mapping Enum type:" + enumType + " It is mapped using 2 of (ORDINAL, STRING or an Ebean mapping) when only one is supported.");
}
return scalarEnum;
}
@@ -57,7 +57,7 @@ public class DefaultTypeManagerTest {
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");
assertThat(e.getMessage()).contains("It is mapped using 2 of (ORDINAL, STRING or an Ebean mapping) when only one is supported.");
}
}
@@ -72,7 +72,7 @@ public class DefaultTypeManagerTest {
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");
assertThat(e.getMessage()).contains("It is mapped using 2 of (ORDINAL, STRING or an Ebean mapping) when only one is supported.");
}
}
@@ -90,7 +90,7 @@ public class DefaultTypeManagerTest {
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");
assertThat(e.getMessage()).contains("It is mapped using 2 of (ORDINAL, STRING or an Ebean mapping) when only one is supported.");
}
}
@@ -105,7 +105,7 @@ public class DefaultTypeManagerTest {
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");
assertThat(e.getMessage()).contains("It is mapped using 2 of (ORDINAL, STRING or an Ebean mapping) when only one is supported.");
}
}
@@ -57,7 +57,7 @@ class TestTypeManager extends BaseTest {
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");
assertThat(e.getMessage()).contains("It is mapped using 2 of (ORDINAL, STRING or an Ebean mapping) when only one is supported.");
}
}
@@ -91,7 +91,7 @@ class TestTypeManager extends BaseTest {
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");
assertThat(e.getMessage()).contains("It is mapped using 2 of (ORDINAL, STRING or an Ebean mapping) when only one is supported.");
}
}
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<artifactId>ebean-csv-reader</artifactId>
@@ -14,21 +14,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
@@ -48,11 +48,11 @@
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.24</version>
<version>2.34</version>
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:13.12.0</tile>
<tile>io.ebean.tile:enhancement:13.17.1</tile>
</tiles>
</configuration>
</plugin>
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean ddl generation</name>
@@ -28,14 +28,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
@@ -72,7 +72,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
@@ -61,7 +61,7 @@ public class DdlGenerator implements SpiDdlGenerator {
this.platform = databasePlatform.platform();
this.platformName = platform.base().name();
if (!config.getTenantMode().isDdlEnabled() && config.isDdlRun()) {
log.log(WARNING, "DDL can't be run on startup with TenantMode " + config.getTenantMode());
log.log(WARNING, "DDL can''t be run on startup with TenantMode " + config.getTenantMode());
this.runDdl = false;
this.useMigrationStoredProcedures = false;
} else {
@@ -9,7 +9,7 @@ import io.ebeaninternal.dbmigration.migration.Column;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.regex.Pattern;
import static java.util.stream.Collectors.toList;
@@ -18,6 +18,8 @@ import static java.util.stream.Collectors.toList;
*/
public class PostgresDdl extends PlatformDdl {
private static final Pattern PLAIN_VARCHAR = Pattern.compile("(varchar\\()(\\d+)(\\))");
private static final String dropIndexConcurrentlyIfExists = "drop index concurrently if exists ";
public PostgresDdl(DatabasePlatform platform) {
@@ -31,6 +33,7 @@ public class PostgresDdl extends PlatformDdl {
this.columnSetNull = "drop not null";
this.addForeignKeySkipCheck = " not valid";
this.indexConcurrent = "concurrently ";
this.addColumn = "add column if not exists";
}
@Override
@@ -74,9 +77,20 @@ public class PostgresDdl extends PlatformDdl {
@Override
protected void alterColumnType(DdlWrite writer, AlterColumn alter) {
String type = convert(alter.getType());
alterTable(writer, alter.getTableName()).append(alterColumn, alter.getColumnName())
.append(columnSetType).append(type)
.append(" using ").append(alter.getColumnName()).append("::").append(type);
var alterTable = alterTable(writer, alter.getTableName())
.append(alterColumn, alter.getColumnName())
.append(columnSetType).append(type);
if (useCast(type, alter.getCurrentType())) {
alterTable.append(" using ").append(alter.getColumnName()).append("::").append(type);
}
}
static boolean useCast(String newType, String currentType) {
return currentType == null || !isPlainVarchar(newType) || !isPlainVarchar(currentType);
}
static boolean isPlainVarchar(String type) {
return PLAIN_VARCHAR.matcher(type).matches();
}
@Override
@@ -87,7 +87,7 @@ public class BaseDdlHandlerTest extends BaseTestCase {
DdlHandler postgresHandler = postgresHandler();
postgresHandler.generate(writer, Helper.getAlterTableAddDbArrayColumn());
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_added_to_foo varchar[];\n");
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column if not exists dbarray_added_to_foo varchar[];\n");
writer = new DdlWrite();
@@ -109,7 +109,7 @@ public class BaseDdlHandlerTest extends BaseTestCase {
DdlWrite writer = new DdlWrite();
postgresHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnWithLength());
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_ninety varchar[];\n");
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column if not exists dbarray_ninety varchar[];\n");
writer = new DdlWrite();
h2Handler().generate(writer, Helper.getAlterTableAddDbArrayColumnWithLength());
@@ -134,7 +134,7 @@ public class BaseDdlHandlerTest extends BaseTestCase {
DdlWrite writer = new DdlWrite();
postgresHandler().generate(writer, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column dbarray_integer integer[];\n");
assertThat(writer.toString()).isEqualTo("-- apply alter tables\nalter table foo add column if not exists dbarray_integer integer[];\n");
writer = new DdlWrite();
h2Handler().generate(writer, Helper.getAlterTableAddDbArrayColumnIntegerWithLength());
@@ -107,7 +107,7 @@ public class PlatformDdl_AlterColumnTest {
sql = alterColumn(pgDdl, alter);
softly.assertThat(sql).isEqualTo("-- apply alter tables\n"
+ "alter table mytab alter column acol type varchar(50) using acol::varchar(50);\n"
+ "alter table mytab alter column acol type varchar(50);\n"
+ "alter table mytab alter column acol set default 'hi';\n"
+ "alter table mytab alter column acol set not null;\n");
@@ -13,6 +13,41 @@ class PostgresDdlTest {
final PostgresDdl postgresDdl = new PostgresDdl(new PostgresPlatform());
@Test
void useCast_notWhenSimpleVarcharLengthChange() {
assertThat(PostgresDdl.useCast("varchar(10)", "varchar(150)")).isFalse();
}
@Test
void useCast() {
assertThat(PostgresDdl.useCast("varchar", "varchar(150)")).isTrue();
assertThat(PostgresDdl.useCast("varchar(1)", "varchar")).isTrue();
assertThat(PostgresDdl.useCast("varchar(1)[]", "varchar(2)[]")).isTrue();
}
@Test
void useCastTrue() {
assertThat(PostgresDdl.useCast("text(10)", "text(150)")).isTrue();
assertThat(PostgresDdl.useCast("number(5)", "number(10)")).isTrue();
assertThat(PostgresDdl.useCast("number(5,3)", "number(10,2)")).isTrue();
}
@Test
void isPlainVarchar() {
assertThat(PostgresDdl.isPlainVarchar("varchar(1)")).isTrue();
assertThat(PostgresDdl.isPlainVarchar("varchar(10)")).isTrue();
assertThat(PostgresDdl.isPlainVarchar("varchar(150)")).isTrue();
}
@Test
void isPlainVarchar_false() {
assertThat(PostgresDdl.isPlainVarchar("varcha(10)")).isFalse();
assertThat(PostgresDdl.isPlainVarchar("text(10)")).isFalse();
assertThat(PostgresDdl.isPlainVarchar("number(10)")).isFalse();
assertThat(PostgresDdl.isPlainVarchar("varchar(10)[]")).isFalse();
assertThat(PostgresDdl.isPlainVarchar("varchar")).isFalse();
}
@Test
void setLockTimeout() {
final String sql = postgresDdl.setLockTimeout(5);
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean external mapping api</name>
+7 -7
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<scm>
@@ -21,7 +21,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<!-- JAVAX-DEPENDENCY-START -->
@@ -68,21 +68,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
@@ -100,12 +100,12 @@
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.24</version>
<version>2.34</version>
<extensions>true</extensions>
<configuration>
<tiles>
<!-- other tiles ... -->
<tile>io.ebean.tile:enhancement:13.12.0</tile>
<tile>io.ebean.tile:enhancement:13.17.1</tile>
</tiles>
</configuration>
</plugin>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<artifactId>ebean-jackson-jsonnode</artifactId>
@@ -14,7 +14,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
+2 -2
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -14,7 +14,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
+2 -2
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -14,7 +14,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
+5 -5
View File
@@ -6,7 +6,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<artifactId>ebean-kotlin</artifactId>
@@ -28,7 +28,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
@@ -50,7 +50,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
@@ -88,11 +88,11 @@
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.24</version>
<version>2.34</version>
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:13.12.0</tile>
<tile>io.ebean.tile:enhancement:13.17.1</tile>
</tiles>
</configuration>
</plugin>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean postgis</name>
@@ -22,14 +22,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<!-- provided scope -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
@@ -65,7 +65,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
@@ -92,11 +92,11 @@
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.24</version>
<version>2.34</version>
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:13.12.0</tile>
<tile>io.ebean.tile:enhancement:13.17.1</tile>
</tiles>
</configuration>
</plugin>
@@ -98,12 +98,7 @@ abstract class ScalarTypePgisBase<T extends Geometry> implements ScalarType<T> {
@Override
public String formatValue(T value) {
return null;
}
@Override
public T parse(String value) {
return null;
return value.toString();
}
@Override
@@ -3,10 +3,20 @@ package io.ebean.postgis;
import io.ebean.config.dbplatform.ExtraDbTypes;
import org.postgis.LineString;
import java.sql.SQLException;
public class ScalarTypePgisLineString extends ScalarTypePgisBase<LineString> {
public ScalarTypePgisLineString() {
super(ExtraDbTypes.LINESTRING, LineString.class);
}
@Override
public LineString parse(String value) {
try {
return new LineString(value);
} catch (SQLException e) {
throw new IllegalStateException(e);
}
}
}
@@ -3,10 +3,20 @@ package io.ebean.postgis;
import io.ebean.config.dbplatform.ExtraDbTypes;
import org.postgis.MultiLineString;
import java.sql.SQLException;
public class ScalarTypePgisMultiLineString extends ScalarTypePgisBase<MultiLineString> {
public ScalarTypePgisMultiLineString() {
super(ExtraDbTypes.MULTILINESTRING, MultiLineString.class);
}
@Override
public MultiLineString parse(String value) {
try {
return new MultiLineString(value);
} catch (SQLException e) {
throw new IllegalStateException(e);
}
}
}
@@ -3,10 +3,20 @@ package io.ebean.postgis;
import io.ebean.config.dbplatform.ExtraDbTypes;
import org.postgis.MultiPoint;
import java.sql.SQLException;
public class ScalarTypePgisMultiPoint extends ScalarTypePgisBase<MultiPoint> {
public ScalarTypePgisMultiPoint() {
super(ExtraDbTypes.MULTIPOINT, MultiPoint.class);
}
@Override
public MultiPoint parse(String value) {
try {
return new MultiPoint(value);
} catch (SQLException e) {
throw new IllegalStateException(e);
}
}
}
@@ -3,10 +3,20 @@ package io.ebean.postgis;
import io.ebean.config.dbplatform.ExtraDbTypes;
import org.postgis.MultiPolygon;
import java.sql.SQLException;
public class ScalarTypePgisMultiPolygon extends ScalarTypePgisBase<MultiPolygon> {
public ScalarTypePgisMultiPolygon() {
super(ExtraDbTypes.MULTIPOLYGON, MultiPolygon.class);
}
@Override
public MultiPolygon parse(String value) {
try {
return new MultiPolygon(value);
} catch (SQLException e) {
throw new IllegalStateException(e);
}
}
}
@@ -3,10 +3,20 @@ package io.ebean.postgis;
import io.ebean.config.dbplatform.ExtraDbTypes;
import org.postgis.Point;
import java.sql.SQLException;
public class ScalarTypePgisPoint extends ScalarTypePgisBase<Point> {
public ScalarTypePgisPoint() {
super(ExtraDbTypes.POINT, Point.class);
}
@Override
public Point parse(String value) {
try {
return new Point(value);
} catch (SQLException e) {
throw new IllegalStateException(e);
}
}
}
@@ -3,9 +3,20 @@ package io.ebean.postgis;
import io.ebean.config.dbplatform.ExtraDbTypes;
import org.postgis.Polygon;
import java.sql.SQLException;
public class ScalarTypePgisPolygon extends ScalarTypePgisBase<Polygon> {
public ScalarTypePgisPolygon() {
super(ExtraDbTypes.POLYGON, Polygon.class);
}
@Override
public Polygon parse(String value) {
try {
return new Polygon(value);
} catch (SQLException e) {
throw new IllegalStateException(e);
}
}
}
@@ -0,0 +1,43 @@
package org.example.domain;
import io.ebean.annotation.Cache;
import org.postgis.Point;
import org.postgis.Polygon;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name="mybean_cached")
@Cache
public class CachedBean extends BaseEntity {
String name;
Point point;
Polygon polygon;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public Polygon getPolygon() {
return polygon;
}
public void setPolygon(Polygon polygon) {
this.polygon = polygon;
}
}
@@ -0,0 +1,80 @@
package org.example.domain;
import io.ebean.DB;
import org.junit.jupiter.api.Test;
import org.postgis.Point;
import org.postgis.Polygon;
import java.sql.SQLException;
import static org.junit.jupiter.api.Assertions.*;
public class TestCacheSerialization {
@Test
public void testCache() throws SQLException {
Point p1=new Point(1.0, 2.0);
p1.setSrid(4674);
Polygon pol=new Polygon("SRID=4674;POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1))");
CachedBean tb=new CachedBean();
tb.setId(2080L);
tb.setName("Serialize Test");
tb.setPoint(p1);
tb.setPolygon(pol);
DB.insert(tb);
CachedBean r1=DB.find(CachedBean.class, tb.getId());
assertNotNull(r1);
assertEquals(p1, r1.getPoint());
assertEquals(pol, r1.getPolygon());
CachedBean r2=DB.find(CachedBean.class, tb.getId()); // this is returned from cache
assertNotNull(r2);
assertEquals(p1, r2.getPoint()); // and did fail https://github.com/ebean-orm/ebean/issues/3026
assertEquals(pol, r2.getPolygon());
}
@Test
public void testNullCache() throws SQLException {
Point p1=new Point(1.0, 2.0);
p1.setSrid(4674);
Polygon pol=new Polygon("SRID=4674;POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1))");
CachedBean tb=new CachedBean();
tb.setId(2081L);
tb.setName("Serialize Test");
tb.setPoint(p1);
tb.setPolygon(null);
DB.insert(tb);
CachedBean r1=DB.find(CachedBean.class, tb.getId());
assertNotNull(r1);
assertEquals(p1, r1.getPoint());
assertNull(r1.getPolygon());
CachedBean r2=DB.find(CachedBean.class, tb.getId()); // this is returned from cache
assertNotNull(r2);
assertEquals(p1, r2.getPoint()); // and did fail https://github.com/ebean-orm/ebean/issues/3026
assertNull(r1.getPolygon());
tb.setPoint(null);
tb.setPolygon(pol);
DB.save(tb);
r1=DB.find(CachedBean.class, tb.getId());
assertNotNull(r1);
assertEquals(pol, r1.getPolygon());
assertNull(r1.getPoint());
r2=DB.find(CachedBean.class, tb.getId()); // this is returned from cache
assertNotNull(r2);
assertEquals(pol, r2.getPolygon()); // and did fail https://github.com/ebean-orm/ebean/issues/3026
assertNull(r1.getPoint());
}
}
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean querybean</name>
@@ -17,7 +17,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
@@ -63,21 +63,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
@@ -107,7 +107,7 @@
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:13.13.2</tile>
<tile>io.ebean.tile:enhancement:13.17.1</tile>
</tiles>
</configuration>
</plugin>
+8 -8
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<artifactId>ebean-redis</artifactId>
@@ -22,35 +22,35 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
@@ -76,11 +76,11 @@
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.24</version>
<version>2.34</version>
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:13.12.0</tile>
<tile>io.ebean.tile:enhancement:13.17.1</tile>
</tiles>
</configuration>
</plugin>
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<artifactId>ebean-spring-txn</artifactId>
@@ -28,7 +28,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
@@ -77,7 +77,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
@@ -102,7 +102,7 @@
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.24</version>
<version>2.34</version>
<extensions>true</extensions>
<configuration>
<tiles>
+11 -11
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.17.0</version>
<version>13.18.0</version>
</parent>
<name>ebean test</name>
@@ -28,20 +28,20 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -118,28 +118,28 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>13.17.0</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
@@ -254,7 +254,7 @@
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.36.0.3</version>
<version>3.41.2.2</version>
<scope>test</scope>
</dependency>
@@ -295,11 +295,11 @@
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.24</version>
<version>2.34</version>
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:13.12.0</tile>
<tile>io.ebean.tile:enhancement:13.17.1</tile>
</tiles>
</configuration>
</plugin>
@@ -4,7 +4,20 @@ package io.ebean.test;
* Use in test code when the CurrentUserProvider and/or CurrentTenantProvider were configured by
* this ebean-test-config plugin.
* <p>
* That is, the ebean-test-config plugin will check if there ia a CurrentUserProvider and if not
* This is not automatically available. If you wish to use this class in your Tenant testing, you must set the
* application.properties setting to:
*
* <pre>
* ebean.test.registerTestTenantProvider=true
* </pre>
*
* or application-test.yaml:
* <pre>
* ebean:
* test:
* registerTestTenantProvider: true
* </pre>.
* If set to true, the ebean-test-config plugin will check if there is a CurrentUserProvider and if not
* automatically set one and that provider reads the 'current user' from this UserContext.
* <pre>{@code
*
@@ -399,6 +399,11 @@ class Config {
}
private void setDockerOptionalParameters() {
String mirror = properties.getProperty("ebean.test.containers.mirror");
if (mirror != null) {
// use a image mirror (when not running locally, i.e. CI)
dockerProperties.setProperty("ebean.test.containers.mirror", mirror);
}
// check for shutdown mode on all containers
String mode = properties.getProperty("ebean.test.shutdownMode");
if (mode != null) {
@@ -0,0 +1,76 @@
package io.ebean.xtest.base;
import io.ebean.xtest.BaseTestCase;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.ResetBasicData;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class DtoQuery3Test extends BaseTestCase {
@Test
void dtoQuery_when_constructorsClash() {
ResetBasicData.reset();
List<DCust> list = server().findDto(DCust.class, "select id, name, status from o_customer where status is not null").findList();
assertThat(list).isNotEmpty();
for (DCust cust: list) {
assertThat(cust.id()).isNotNull();
assertThat(cust.name()).isNotNull();
assertThat(cust.status()).isNotNull();
}
}
public static class DCust {
final Integer id;
String name;
String status;
public DCust(Integer id) {
this.id = id;
}
/** Constructor with 3 args - clashes with the one below */
public DCust(Integer id, String name, List<String> notUsed) {
this.id = id;
this.name = name;
}
/** Constructor with 3 args - clashes with the one above */
public DCust(Integer id, String name, String status) {
this.id = id;
this.name = name;
this.status = status;
}
@Override
public String toString() {
return "id:" + id + " name:" + name;
}
public Integer id() {
return id;
}
public String name() {
return name;
}
public void name(String name) {
this.name = name;
}
public String status() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
}
@@ -94,18 +94,16 @@ public class TestInsertCheckUnique extends BaseTestCase {
StringBuilder msg = new StringBuilder();
properties.forEach((it)-> {
properties.forEach((it) -> {
Object propertyValue = it.value(doc2);
String propertyName = it.name();
msg.append(" property["+propertyName+"] value["+propertyValue+"]");
msg.append(" property[" + propertyName + "] value[" + propertyValue + "]");
});
System.out.println("uniqueProperties > "+uniqueProperties);
System.out.println(" custom msg > " + msg.toString());
System.out.println("uniqueProperties > " + uniqueProperties);
System.out.println(" custom msg > " + msg);
}
assertThat(DB.checkUniqueness(doc2).toString()).contains("title");
}
}
@@ -170,20 +170,20 @@ public class TestCustomerFinder extends BaseTestCase {
ResetBasicData.reset();
// change default collect query plan threshold to 200 micros
// change default collect query plan threshold to 20 micros
QueryPlanInit init0 = new QueryPlanInit();
init0.setAll(true);
init0.thresholdMicros(2);
init0.thresholdMicros(20);
final List<MetaQueryPlan> plans = server().metaInfo().queryPlanInit(init0);
assertThat(plans.size()).isGreaterThan(1);
// the server has some plans
runQueries();
// change query plan threshold to 100 micros
// change query plan threshold to 10 micros
QueryPlanInit init = new QueryPlanInit();
init.setAll(true);
init.thresholdMicros(1);
init.thresholdMicros(10);
final List<MetaQueryPlan> appliedToPlans = server().metaInfo().queryPlanInit(init);
assertThat(appliedToPlans.size()).isGreaterThan(4);
@@ -212,9 +212,9 @@ public class TestCustomerFinder extends BaseTestCase {
List<MetaQueryPlan> plans0 = server().metaInfo().queryPlanCollectNow(request);
assertThat(plans0).isNotEmpty();
for (MetaQueryPlan plan : plans) {
logger.info("queryPlan label:{}, queryTimeMicros:{} loc:{} sql:{} bind:{} plan:{}",
plan.label(), plan.queryTimeMicros(), plan.profileLocation(),
for (MetaQueryPlan plan : plans0) {
logger.info("queryPlan label:{}, queryTimeMicros:{} captureMicros:{} whenCaptured:{} captureCount:{} loc:{} sql:{} bind:{} plan:{}",
plan.label(), plan.queryTimeMicros(), plan.captureMicros(), plan.whenCaptured(), plan.captureCount(), plan.profileLocation(),
plan.sql(), plan.bind(), plan.plan());
System.out.println(plan);
}
@@ -210,12 +210,12 @@ create table migtest_oto_master (
);
-- apply alter tables
alter table "table" add column sys_period tstzrange not null default tstzrange(current_timestamp, null);
alter table migtest_e_history2 add column sys_period tstzrange not null default tstzrange(current_timestamp, null);
alter table migtest_e_history3 add column sys_period tstzrange not null default tstzrange(current_timestamp, null);
alter table migtest_e_history4 add column sys_period tstzrange not null default tstzrange(current_timestamp, null);
alter table migtest_e_history5 add column sys_period tstzrange not null default tstzrange(current_timestamp, null);
alter table migtest_e_history6 add column sys_period tstzrange not null default tstzrange(current_timestamp, null);
alter table "table" add column if not exists sys_period tstzrange not null default tstzrange(current_timestamp, null);
alter table migtest_e_history2 add column if not exists sys_period tstzrange not null default tstzrange(current_timestamp, null);
alter table migtest_e_history3 add column if not exists sys_period tstzrange not null default tstzrange(current_timestamp, null);
alter table migtest_e_history4 add column if not exists sys_period tstzrange not null default tstzrange(current_timestamp, null);
alter table migtest_e_history5 add column if not exists sys_period tstzrange not null default tstzrange(current_timestamp, null);
alter table migtest_e_history6 add column if not exists sys_period tstzrange not null default tstzrange(current_timestamp, null);
-- apply post alter
create table migtest_e_history2_history(like migtest_e_history2);
create view migtest_e_history2_with_history as select * from migtest_e_history2 union all select * from migtest_e_history2_history;
@@ -79,47 +79,47 @@ drop function if exists table_history_version();
drop view table_with_history;
-- apply alter tables
alter table "table" alter column textfield drop not null;
alter table "table" add column "select" varchar(255);
alter table "table" add column textfield2 varchar(255);
alter table migtest_ckey_detail add column one_key integer;
alter table migtest_ckey_detail add column two_key varchar(127);
alter table migtest_ckey_parent add column assoc_id integer;
alter table "table" add column if not exists "select" varchar(255);
alter table "table" add column if not exists textfield2 varchar(255);
alter table migtest_ckey_detail add column if not exists one_key integer;
alter table migtest_ckey_detail add column if not exists two_key varchar(127);
alter table migtest_ckey_parent add column if not exists assoc_id integer;
alter table migtest_e_basic alter column status set default 'A';
alter table migtest_e_basic alter column status set not null;
alter table migtest_e_basic alter column status2 type varchar(127) using status2::varchar(127);
alter table migtest_e_basic alter column status2 type varchar(127);
alter table migtest_e_basic alter column status2 drop default;
alter table migtest_e_basic alter column status2 drop not null;
alter table migtest_e_basic alter column a_lob drop default;
alter table migtest_e_basic alter column a_lob drop not null;
alter table migtest_e_basic alter column user_id drop not null;
alter table migtest_e_basic add column new_string_field varchar(255) default 'foo''bar' not null;
alter table migtest_e_basic add column new_boolean_field boolean default true not null;
alter table migtest_e_basic add column new_boolean_field2 boolean default true not null;
alter table migtest_e_basic add column progress integer default 0 not null;
alter table migtest_e_basic add column new_integer integer default 42 not null;
alter table migtest_e_history add column sys_period tstzrange not null default tstzrange(current_timestamp, null);
alter table migtest_e_basic add column if not exists new_string_field varchar(255) default 'foo''bar' not null;
alter table migtest_e_basic add column if not exists new_boolean_field boolean default true not null;
alter table migtest_e_basic add column if not exists new_boolean_field2 boolean default true not null;
alter table migtest_e_basic add column if not exists progress integer default 0 not null;
alter table migtest_e_basic add column if not exists new_integer integer default 42 not null;
alter table migtest_e_history add column if not exists sys_period tstzrange not null default tstzrange(current_timestamp, null);
alter table migtest_e_history alter column test_string type bigint using test_string::bigint;
alter table migtest_e_history2 alter column test_string set default 'unknown';
alter table migtest_e_history2 alter column test_string set not null;
alter table migtest_e_history2 add column test_string2 varchar(255);
alter table migtest_e_history2 add column test_string3 varchar(255) default 'unknown' not null;
alter table migtest_e_history2 add column new_column varchar(20);
alter table migtest_e_history2_history add column test_string2 varchar(255);
alter table migtest_e_history2_history add column test_string3 varchar(255) default 'unknown';
alter table migtest_e_history2_history add column new_column varchar(20);
alter table migtest_e_history2 add column if not exists test_string2 varchar(255);
alter table migtest_e_history2 add column if not exists test_string3 varchar(255) default 'unknown' not null;
alter table migtest_e_history2 add column if not exists new_column varchar(20);
alter table migtest_e_history2_history add column if not exists test_string2 varchar(255);
alter table migtest_e_history2_history add column if not exists test_string3 varchar(255) default 'unknown';
alter table migtest_e_history2_history add column if not exists new_column varchar(20);
alter table migtest_e_history4 alter column test_number type bigint using test_number::bigint;
alter table migtest_e_history4_history alter column test_number type bigint using test_number::bigint;
alter table migtest_e_history5 add column test_boolean boolean default false not null;
alter table migtest_e_history5_history add column test_boolean boolean default false;
alter table migtest_e_history5 add column if not exists test_boolean boolean default false not null;
alter table migtest_e_history5_history add column if not exists test_boolean boolean default false;
alter table migtest_e_history6 alter column test_number1 set default 42;
alter table migtest_e_history6 alter column test_number1 set not null;
alter table migtest_e_history6 alter column test_number2 drop not null;
alter table migtest_e_history6_history alter column test_number2 drop not null;
alter table migtest_e_softdelete add column deleted boolean default false not null;
alter table migtest_oto_child add column master_id bigint;
alter table migtest_e_softdelete add column if not exists deleted boolean default false not null;
alter table migtest_oto_child add column if not exists master_id bigint;
alter table table_history alter column textfield drop not null;
alter table table_history add column "select" varchar(255);
alter table table_history add column textfield2 varchar(255);
alter table table_history add column if not exists "select" varchar(255);
alter table table_history add column if not exists textfield2 varchar(255);
-- apply post alter
alter table migtest_e_basic add constraint ck_migtest_e_basic_status check ( status in ('N','A','I','?'));
alter table migtest_e_basic add constraint uq_migtest_e_basic_description unique (description);

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