Compare commits

...
171 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 5f6b4a7795 Version 13.17.0 2023-04-06 15:34:50 +12:00
Rob Bygrave 3d890f5383 Bump ebean-agent to 13.17.0 2023-04-06 15:06:05 +12:00
Rob Bygrave 31a0d9b6a6 Add test only - add PathStackTest 2023-04-06 15:03:14 +12:00
Rob BygraveandGitHub 95fbdf37c6 Merge pull request #3021 from ebean-orm/feature/3020-forUpdateRefresh
#3020 Query.forUpdate() works like REFRESH
2023-04-06 14:11:43 +12:00
Rob BygraveandGitHub 1d09c0864d Merge pull request #3019 from ebean-orm/refactor/method-names-ObjectGraphOrigin
Refactor rename getters to accessors for ObjectGraphOrigin etc
2023-04-06 14:11:23 +12:00
Rob BygraveandGitHub 02f7815e73 Merge pull request #3018 from ebean-orm/refactor/add-final-remove-public-platformHelpers
Refactor platforms adding final and removing public from sequence, history, encryption helpers
2023-04-06 14:11:02 +12:00
Rob BygraveandGitHub 85b700757d Merge pull request #3010 from ebean-orm/feature/support-dynamicFormulaWithIncludes
Add support for dynamic formula with includes
2023-04-06 14:10:26 +12:00
Rob BygraveandGitHub d5838e3d64 Merge pull request #3009 from ebean-orm/build/13-16
Build 13.17.0
2023-04-06 14:09:53 +12:00
Rob Bygrave 01e9eb81cf For testing PostGIS use ghcr.io/baosystems/postgis:15 docker image
This is a fork of the official PostGIS docker that support multi-architectures
and more specifically ARM
2023-04-04 22:40:02 +12:00
Rob Bygrave 1daad7af06 #3020 Query.forUpdate() works like REFRESH
Query.forUpdate() will load data into beans existing in the persistence context.
In discussion the thinking is that we can think of this as a bug fix.
2023-04-01 13:24:37 +13:00
Rob Bygrave e51d6984fe Refactor rename getters to accessors for BeanCollection, EntityBeanIntercept etc 2023-03-31 10:42:21 +13:00
Rob Bygrave c2777b0e27 Refactor rename getters to accessors for ObjectGraphOrigin etc 2023-03-30 23:58:22 +13:00
Rob Bygrave 505f87c524 Refactor platforms adding final and removing public from sequence, history, encryption helpers
In theory no is customising these classes and probably should have their own copy of them if
they are doing do. Thus making these types final and package protected.
2023-03-30 23:40:53 +13:00
Rob Bygrave 4a372a5dc8 Remove unused import 2023-03-30 13:13:09 +13:00
Rob Bygrave 8e864897bd Bump to next snapshot version 2023-03-30 13:00:55 +13:00
Rob Bygrave 87b12cff93 Version 13.16.0 2023-03-29 22:48:06 +13:00
Rob BygraveandGitHub 14ea5521c4 Merge pull request #3015 from ebean-orm/fix/3012-shutdown-leak
Fix for #3012 Manual server shutdown leads to memory leak
2023-03-29 21:11:07 +13:00
Rob Bygrave e1522df8a5 Fix for #3012 Manual server shutdown leads to memory leak
The issue being that shutdown() // with no args was
not calling ShutdownManager.unregisterDatabase(this)
noting that shutdown(boolean, boolean) did.

This change merges the old shutdownInternal(boolean, boolean)
method into shutdown(boolean, boolean) and simplifies
shutdown() to just call shutdown(boolean, boolean).
2023-03-29 20:59:23 +13:00
Rob Bygrave b4f309c219 Bump ebean-agent to 13.16.0 2023-03-29 20:33:40 +13:00
Rob BygraveandGitHub 181c6a9d4b Merge pull request #3014 from ebean-orm/fix/autotune-key
[autotune] Fix key on CallStack - regression from introduction of StackWalker.StackFrame
2023-03-29 20:00:06 +13:00
Rob BygraveandGitHub 203aa52c2f Merge pull request #3013 from ebean-orm/feature/update-autotune-test
Update tests for Autotune
2023-03-29 19:36:42 +13:00
Rob Bygrave ad3e88c562 Update tests for Autotune 2023-03-29 19:31:46 +13:00
Rob Bygrave adb302059b [autotune] Fix key on CallStack - regression from introduction of StackWalker.StackFrame 2023-03-29 19:30:56 +13:00
Rob Bygrave 2d03421de4 Use DeployBeanProperty toString() removing getFullBeanName() 2023-03-28 18:44:00 +13:00
Rob BygraveandGitHub 9506e6456c Merge pull request #3011 from ebean-orm/feature/improve-error-message-no-join-columns
Improve the error message "No join columns found" to include the relationship
2023-03-27 21:45:46 +13:00
Rob Bygrave 4617ea2c1c Improve the error message "No join columns found" to include the relationship 2023-03-27 21:44:23 +13:00
Rob Bygrave 55d7eb55d2 Add support for dynamic formula with includes
e.g.

DB.find(ChildPerson.class)
  .select("name, coalesce(someBean, parent.someBean) as effectiveBean") // include parent
  .findList();
2023-03-25 15:49:17 +13:00
Rob BygraveandGitHub 7feb193e95 Merge pull request #3007 from ebean-orm/refactor/rename-loadContext-methods
Refactor rename methods in LoadContext
2023-03-25 15:39:40 +13:00
Rob BygraveandGitHub ab8915b374 Merge pull request #3008 from ebean-orm/feature/expressionRequest-refactor
Refactor SpiExpressionRequest
2023-03-25 15:31:09 +13:00
Rob Bygrave 79fd689e9a Add support for raw SQL SubQuery expressions IN,EQ,NE,GT,GE,LT,LE,EXISTS,Not IN, Not EXISTS
For these expressions the SQL SubQuery is not parsed by ebean and
just used as is.
2023-03-24 22:38:52 +13:00
Rob Bygrave a68665a37e Refactor rename methods on SpiExpressionRequest, DeployParser etc 2023-03-24 19:57:21 +13:00
Rob Bygrave 9ff240dc10 Refactor SpiExpressionRequest split parse() into property() and path() to have fast path
property() uses a fast path for the common case that the expression is a bean property path.
This will then fall back to using parse() when that isn't the case.
2023-03-24 19:35:11 +13:00
Rob Bygrave 9982fa3682 Refactor SpiExpressionRequest split append() into append() and parse()
- append() adds to the sql with NO parsing
- parse() adds to the sql with parsing to replace logical bean paths into table alias placeholder + db column
2023-03-24 17:37:34 +13:00
Rob Bygrave f7a11135a5 Refactor rename methods in LoadContext
Rename internal methods only
2023-03-23 22:11:02 +13:00
Rob Bygrave c29a81248a Remove internal asserts on DLoadBeanContext bufferLock 2023-03-23 22:07:59 +13:00
Rob Bygrave ef6d1dbca3 Bump to next snapshot version 2023-03-23 01:12:10 +13:00
Rob Bygrave 60a84b7a38 Version 13.15.2 2023-03-22 23:33:48 +13:00
Rob Bygrave fa3e9e6fc6 Bump ebean-agent to 13.15.2 2023-03-22 23:30:28 +13:00
Rob BygraveandGitHub 8ca44edf9c Merge pull request #3006 from ebean-orm/fix/3005-rawSql-select
Fix for #3005 - Regression, Invalid SQL with RawSql in 13.15.0 due o #2996
2023-03-22 23:25:33 +13:00
Rob Bygrave fcefd94086 Fix for #3005 - Regression, Invalid SQL with RawSql in 13.15.0 due to #2996 2023-03-22 23:18:18 +13:00
Rob Bygrave 70e5d57b7e Bump to next snapshot version 2023-03-21 23:32:21 +13:00
Rob Bygrave cc3b9c9508 Version 13.15.1 2023-03-21 21:17:08 +13:00
Rob Bygrave be49be38d0 Bump ebean-agent to 13.15.1 2023-03-21 20:45:59 +13:00
Rob BygraveandGitHub dca13db945 Merge pull request #3002 from ebean-orm/feature/improveLogging-markedAsDeleted
Improve the logging around MarkedAsDeleted
2023-03-21 20:43:12 +13:00
Rob Bygrave bd318a5d85 Improve the logging around MarkedAsDeleted 2023-03-21 20:30:39 +13:00
Rob BygraveandGitHub 4c2be2986a Merge pull request #3000 from FOCONIS/bugfix-fix-json-import
FIX: DB.json().toBean(target) can update existing lists (#85)
2023-03-18 10:22:18 +13:00
3d7bebd244 FIX: DB.json().toBean(target) can update existing lists (#85)
* FIX: DB.json().toBean(target) can update existing lists

* remove sys.print, typo

---------

Co-authored-by: Roland Praml <roland.praml@foconis.de>
Co-authored-by: Juri Skrobko <juri.skrobko@foconis.de>
2023-03-17 11:04:53 +01:00
Rob Bygrave e23bbf5f94 Revert test sqlserver docker image to 2017-CU28-ubuntu-16.04 2023-03-17 19:18:53 +13:00
Rob Bygrave 27b0c33a4b Adjustments for SqlServer using BIGINT 2023-03-17 18:51:33 +13:00
Rob Bygrave 53ef159d06 Bump Postgres docker image to 15 2023-03-17 18:50:52 +13:00
Rob Bygrave a7d778d98b Merge branch 'master' of github.com:ebean-orm/ebean 2023-03-17 18:14:17 +13:00
Rob Bygrave 19580ff83d Bump SqlServer docker image to 2022-RTM-CU2-ubuntu-20.04 2023-03-17 18:14:02 +13:00
Rob BygraveandGitHub a79a44c513 Merge pull request #2999 from ebean-orm/feature/2998-sqlserver-bigint
#2998 - SQLServer, map java long to BIGINT for bitwise expressions
2023-03-17 18:04:32 +13:00
Rob Bygrave 184b82e1b2 Fix test TestRawSqlQuerySelect for SqlServer
The order by not supported here by SqlServer
2023-03-17 18:03:37 +13:00
Rob Bygrave 04e935acd0 #2998 - SQLServer, map java long to BIGINT for bitwise expressions 2023-03-17 17:54:25 +13:00
Rob Bygrave 142ffe925c Fix test TestRawSqlQuerySelect to support multiple databases 2023-03-16 09:06:09 +13:00
Rob Bygrave 395505ec0d Bump to 13.15.1-SNAPSHOT 2023-03-14 16:57:17 +13:00
Rob Bygrave c21a76fa5b Version 13.15.0 2023-03-14 12:54:53 +13:00
Rob Bygrave a2690fdccd #2995 - Change DatabaseConfig.getClasses() to return a Set
The thinking is that it is safer to make this API change
rather than to return a shallow copy which you won't be
able to detect.
2023-03-14 11:56:01 +13:00
Rob BygraveandGitHub 4039c20462 Merge pull request #2996 from ebean-orm/buchtajz-query_select_bugs
Add support for specifying select clause with RawSql
2023-03-14 11:48:40 +13:00
Rob BygraveandGitHub 6d43028fba Merge pull request #2995 from ebean-orm/feature/config-isLoadModuleInfo
Change such that querybean generated class registration can be used with explicit class registration
2023-03-14 11:48:09 +13:00
Rob Bygrave efcee7e739 Improve test asserts for lazy loading element collection 2023-03-10 21:33:58 +13:00
Rob Bygrave 523fe6ae54 #2946 - Support specify select clause for RawSql 2023-03-10 20:31:54 +13:00
Rob Bygrave 8ec031bfde Merge branch 'query_select_bugs' of github.com:buchtajz/ebean into buchtajz-query_select_bugs 2023-03-10 19:38:26 +13:00
Rob Bygrave cd938fd659 Bump github actions versions on all build.yml 2023-03-10 14:17:38 +13:00
Rob Bygrave 837e296451 Bump github actions versions on build.yml 2023-03-10 14:14:31 +13:00
Rob Bygrave 52b0bd7b7d Bump kotlin version to 1.8.10 2023-03-10 13:57:14 +13:00
Rob Bygrave a8cad4f3d9 Change such that querybean generated class registration can be used will explicit class registration
In DatabaseConfig.isAutoLoadModuleInfo() it only used the querybean generated class registration is classes.isEmpty(). Changing this so that it only uses the loadModuleInfo flag.

This means, unless loadModuleInfo is set to false the classes that register with ebean will be a combination of both the explicitly registered ones plus the classes from the querybean generated EbeanEntityRegister.

In addition, this changes the classes from List to Set.
2023-03-10 11:01:46 +13:00
Rob Bygrave e4cb81cbba Bump to 13.14.2-SNAPSHOT 2023-03-10 00:26:34 +13:00
Rob Bygrave 08cd0aa4b7 Fix the jakarta <-> javax scripts with space after sed -i 2023-03-10 00:22:13 +13:00
buchtajzandGitHub 8c47ba89d1 Merge branch 'ebean-orm:master' into query_select_bugs 2023-02-21 00:04:39 +01:00
Michal Buchtík 1af3d0bcf3 remove unnecessary replace 2023-02-10 12:27:10 +01:00
Michal Buchtík 01a0cee3c2 patch RawSql query builder, fix tests 2023-02-10 12:17:40 +01:00
Michal Buchtík f26feec3d9 Merge remote-tracking branch 'origin/master' into query_select_bugs 2023-02-10 09:33:28 +01:00
Michal Buchtík 6055a33dc8 fix changes 2023-01-27 12:11:01 +01:00
Michal Buchtík 230d18e48f failing test for rawSql select .asDto query 2023-01-27 11:39:37 +01:00
354 changed files with 3672 additions and 2068 deletions
+3 -3
View File
@@ -17,14 +17,14 @@ jobs:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'zulu'
- name: Maven cache
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
+3 -3
View File
@@ -20,14 +20,14 @@ jobs:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
+3 -3
View File
@@ -20,14 +20,14 @@ jobs:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'zulu'
- name: Maven cache
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
+2 -2
View File
@@ -20,14 +20,14 @@ jobs:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Java
uses: oracle-actions/setup-java@v1
with:
website: jdk.java.net
release: ${{ matrix.java_version }}
- name: Maven cache
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
+3 -3
View File
@@ -20,14 +20,14 @@ jobs:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
+3 -3
View File
@@ -17,14 +17,14 @@ jobs:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
+3 -3
View File
@@ -20,14 +20,14 @@ jobs:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'zulu'
- name: Maven cache
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
+3 -3
View File
@@ -20,14 +20,14 @@ jobs:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
+3 -3
View File
@@ -20,14 +20,14 @@ jobs:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'zulu'
- name: Maven cache
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
+3 -3
View File
@@ -20,14 +20,14 @@ jobs:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
+3 -3
View File
@@ -17,14 +17,14 @@ jobs:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
+3 -3
View File
@@ -20,14 +20,14 @@ jobs:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
+3 -3
View File
@@ -20,14 +20,14 @@ jobs:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java_version }}
distribution: 'adopt'
- name: Maven cache
uses: actions/cache@v2
uses: actions/cache@v3
env:
cache-name: maven-cache
with:
+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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>13.14.1</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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.14.1</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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>13.14.1</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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.14.1</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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>13.14.1</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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>13.14.1</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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>13.14.1</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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>13.14.1</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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>13.14.1</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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.14.1</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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>13.14.1</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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.14.1</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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.14.1</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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>13.14.1</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.14.1</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.14.1</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);
@@ -1,10 +1,6 @@
package io.ebean;
import io.ebean.search.Match;
import io.ebean.search.MultiMatch;
import io.ebean.search.TextCommonTerms;
import io.ebean.search.TextQueryString;
import io.ebean.search.TextSimple;
import io.ebean.search.*;
import java.util.Collection;
import java.util.Map;
@@ -423,6 +419,94 @@ public interface ExpressionFactory {
*/
Expression inOrEmpty(String propertyName, Collection<?> values);
/**
* EXISTS a raw SQL SubQuery.
*
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression exists(String sqlSubQuery, Object... bindValues);
/**
* Not EXISTS a raw SQL SubQuery.
*
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression notExists(String sqlSubQuery, Object... bindValues);
/**
* IN a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression inSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Not IN a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression notInSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Equal To a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression eqSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Not Equal To a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression neSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Greater Than or Equal To a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression geSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Greater Than a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression gtSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Less Than or Equal To a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression leSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Less Than a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
Expression ltSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Not In - property has a value in the array of values.
*/
@@ -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;
@@ -1141,6 +1142,94 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> inPairs(Pairs pairs);
/**
* EXISTS a raw SQL SubQuery.
*
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
ExpressionList<T> exists(String sqlSubQuery, Object... bindValues);
/**
* Not EXISTS a raw SQL SubQuery.
*
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
ExpressionList<T> notExists(String sqlSubQuery, Object... bindValues);
/**
* IN a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
ExpressionList<T> inSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Not IN a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
ExpressionList<T> notInSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Equal To a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
ExpressionList<T> eqSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Not Equal To a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
ExpressionList<T> neSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Greater Than a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
ExpressionList<T> gtSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Greater Than or Equal To a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
ExpressionList<T> geSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Less Than a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
ExpressionList<T> ltSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* Less Than or Equal To a raw SQL SubQuery.
*
* @param propertyName The bean property
* @param sqlSubQuery The SQL SubQuery
* @param bindValues Optional bind values if the SubQuery uses {@code ? } bind values.
*/
ExpressionList<T> leSubQuery(String propertyName, String sqlSubQuery, Object... bindValues);
/**
* In - using a subQuery.
*/
@@ -77,12 +77,12 @@ public interface BeanCollection<E> extends Serializable, ToStringAware {
/**
* Return the bean that owns this collection.
*/
EntityBean getOwnerBean();
EntityBean owner();
/**
* Return the bean property name this collection represents.
*/
String getPropertyName();
String propertyName();
/**
* Check after the lazy load that the underlying collection is not null
@@ -99,7 +99,7 @@ public interface BeanCollection<E> extends Serializable, ToStringAware {
* This is so that the filter can be applied on refresh.
* </p>
*/
ExpressionList<?> getFilterMany();
ExpressionList<?> filterMany();
/**
* Set the filter that was used in building this collection.
@@ -154,7 +154,7 @@ public interface BeanCollection<E> extends Serializable, ToStringAware {
/**
* Returns the underlying collection of beans from the Set, Map or List.
*/
Collection<E> getActualDetails();
Collection<E> actualDetails();
/**
* Returns the underlying entries so for Maps this is a collection of
@@ -162,7 +162,7 @@ public interface BeanCollection<E> extends Serializable, ToStringAware {
* <p>
* For maps this returns the entrySet as we need the keys of the map.
*/
Collection<?> getActualEntries();
Collection<?> actualEntries();
/**
* return true if there are real rows held. Return false is this is using
@@ -195,7 +195,7 @@ public interface BeanCollection<E> extends Serializable, ToStringAware {
/**
* Return the current modify listening mode. Can be null for on newly created beans.
*/
ModifyListenMode getModifyListening();
ModifyListenMode modifyListening();
/**
* Add an object to the additions list.
@@ -217,13 +217,13 @@ public interface BeanCollection<E> extends Serializable, ToStringAware {
* Return the list of objects added to the list set or map. These will used to
* insert rows into the intersection table of a ManyToMany.
*/
Set<E> getModifyAdditions();
Set<E> modifyAdditions();
/**
* Return the list of objects removed from the list set or map. These will
* used to delete rows from the intersection table of a ManyToMany.
*/
Set<E> getModifyRemovals();
Set<E> modifyRemovals();
/**
* Reset the set of additions and deletions. This is called after the
@@ -239,5 +239,5 @@ public interface BeanCollection<E> extends Serializable, ToStringAware {
/**
* Return a shallow copy of this collection that is modifiable.
*/
BeanCollection<E> getShallowCopy();
BeanCollection<E> shallowCopy();
}
@@ -13,7 +13,7 @@ public interface BeanLoader {
/**
* Return the name of the associated Database.
*/
String getName();
String name();
/**
* Invoke the lazy loading for this bean.
@@ -8,15 +8,15 @@ public interface CallOrigin {
/**
* Return the top element. Typically the top stack element with class and line.
*/
String getTopElement();
String top();
/**
* Return the full description of the call origin.
*/
String getFullDescription();
String description();
/**
* Compute and return an origin key based on the query hash.
*/
String getOriginKey(int queryHash);
String key(int queryHash);
}
@@ -41,14 +41,14 @@ public final class CallStack implements Serializable, CallOrigin {
public CallStack(List<StackWalker.StackFrame> frames) {
this.callStack = frames.toArray(new Object[0]);
this.hc = computeHashCode();
this.zeroHash = enc(callStack[0].hashCode());
this.zeroHash = enc(callStack[0].toString().hashCode());
this.pathHash = enc(hc);
}
private int computeHashCode() {
int hc = 0;
for (Object element : callStack) {
hc = 92821 * hc + element.hashCode();
hc = 92821 * hc + element.toString().hashCode();
}
return hc;
}
@@ -79,7 +79,7 @@ public final class CallStack implements Serializable, CallOrigin {
* Return the first element of the call stack.
*/
@Override
public String getTopElement() {
public String top() {
return callStack[0].toString();
}
@@ -87,7 +87,7 @@ public final class CallStack implements Serializable, CallOrigin {
* Return the call stack lines appended with the given newLine string.
*/
@Override
public String getFullDescription() {
public String description() {
StringBuilder sb = new StringBuilder(400);
for (int i = 0; i < callStack.length; i++) {
if (i > 0) {
@@ -99,7 +99,7 @@ public final class CallStack implements Serializable, CallOrigin {
}
@Override
public String getOriginKey(int queryHash) {
public String key(int queryHash) {
return enc(queryHash) + "." + zeroHash + "." + pathHash;
}
@@ -17,12 +17,12 @@ public interface EntityBeanIntercept extends Serializable {
/**
* Return the 'owning' entity bean.
*/
EntityBean getOwner();
EntityBean owner();
/**
* Return the persistenceContext.
*/
PersistenceContext getPersistenceContext();
PersistenceContext persistenceContext();
/**
* Set the persistenceContext.
@@ -37,7 +37,7 @@ public interface EntityBeanIntercept extends Serializable {
/**
* Return the ownerId (IdClass).
*/
Object getOwnerId();
Object ownerId();
/**
* Set the ownerId (IdClass).
@@ -47,12 +47,12 @@ public interface EntityBeanIntercept extends Serializable {
/**
* Return the owning bean for an embedded bean.
*/
Object getEmbeddedOwner();
Object embeddedOwner();
/**
* Return the property index (for the parent) of this embedded bean.
*/
int getEmbeddedOwnerIndex();
int embeddedOwnerIndex();
/**
* Clear the getter callback.
@@ -229,7 +229,7 @@ public interface EntityBeanIntercept extends Serializable {
/**
* Return the original value that was changed via an update.
*/
Object getOrigValue(int propertyIndex);
Object origValue(int propertyIndex);
/**
* Finds the index position of a given property. Returns -1 if the
@@ -240,12 +240,12 @@ public interface EntityBeanIntercept extends Serializable {
/**
* Return the property name for the given property.
*/
String getProperty(int propertyIndex);
String property(int propertyIndex);
/**
* Return the number of properties.
*/
int getPropertyLength();
int propertyLength();
/**
* Set the loaded state of the property given it's name.
@@ -321,17 +321,17 @@ public interface EntityBeanIntercept extends Serializable {
/**
* Return the set of property names for a partially loaded bean.
*/
Set<String> getLoadedPropertyNames();
Set<String> loadedPropertyNames();
/**
* Return the array of flags indicating the dirty properties.
*/
boolean[] getDirtyProperties();
boolean[] dirtyProperties();
/**
* Return the set of dirty properties.
*/
Set<String> getDirtyPropertyNames();
Set<String> dirtyPropertyNames();
/**
* Recursively add dirty properties.
@@ -346,7 +346,7 @@ public interface EntityBeanIntercept extends Serializable {
/**
* Return a map of dirty properties with their new and old values.
*/
Map<String, ValuePair> getDirtyValues();
Map<String, ValuePair> dirtyValues();
/**
* Recursively add dirty properties.
@@ -361,7 +361,7 @@ public interface EntityBeanIntercept extends Serializable {
/**
* Return a dirty property hash taking into account embedded beans.
*/
StringBuilder getDirtyPropertyKey();
StringBuilder dirtyPropertyKey();
/**
* Add and return a dirty property hash.
@@ -371,22 +371,22 @@ public interface EntityBeanIntercept extends Serializable {
/**
* Return a loaded property hash.
*/
StringBuilder getLoadedPropertyKey();
StringBuilder loadedPropertyKey();
/**
* Return the loaded state for all the properties.
*/
boolean[] getLoaded();
boolean[] loaded();
/**
* Return the index of the property that triggered the lazy load.
*/
int getLazyLoadPropertyIndex();
int lazyLoadPropertyIndex();
/**
* Return the property that triggered the lazy load.
*/
String getLazyLoadProperty();
String lazyLoadProperty();
/**
* Load the bean when it is a reference.
@@ -497,7 +497,7 @@ public interface EntityBeanIntercept extends Serializable {
/**
* Return the sort order value for an order column.
*/
int getSortOrder();
int sortOrder();
/**
* Set the sort order value for an order column.
@@ -522,7 +522,7 @@ public interface EntityBeanIntercept extends Serializable {
/**
* Returns the loadErrors.
*/
Map<String, Exception> getLoadErrors();
Map<String, Exception> loadErrors();
/**
* Return true if the property has its changed state set.
@@ -25,12 +25,17 @@ public class InterceptReadOnly implements EntityBeanIntercept {
}
@Override
public EntityBean getOwner() {
public String toString() {
return "InterceptReadOnly{" + owner + '}';
}
@Override
public EntityBean owner() {
return owner;
}
@Override
public PersistenceContext getPersistenceContext() {
public PersistenceContext persistenceContext() {
return null;
}
@@ -45,7 +50,7 @@ public class InterceptReadOnly implements EntityBeanIntercept {
}
@Override
public Object getOwnerId() {
public Object ownerId() {
return null;
}
@@ -55,12 +60,12 @@ public class InterceptReadOnly implements EntityBeanIntercept {
}
@Override
public Object getEmbeddedOwner() {
public Object embeddedOwner() {
return null;
}
@Override
public int getEmbeddedOwnerIndex() {
public int embeddedOwnerIndex() {
return 0;
}
@@ -225,7 +230,7 @@ public class InterceptReadOnly implements EntityBeanIntercept {
}
@Override
public Object getOrigValue(int propertyIndex) {
public Object origValue(int propertyIndex) {
return null;
}
@@ -235,12 +240,12 @@ public class InterceptReadOnly implements EntityBeanIntercept {
}
@Override
public String getProperty(int propertyIndex) {
public String property(int propertyIndex) {
return null;
}
@Override
public int getPropertyLength() {
public int propertyLength() {
return 0;
}
@@ -315,17 +320,17 @@ public class InterceptReadOnly implements EntityBeanIntercept {
}
@Override
public Set<String> getLoadedPropertyNames() {
public Set<String> loadedPropertyNames() {
return Collections.emptySet();
}
@Override
public boolean[] getDirtyProperties() {
public boolean[] dirtyProperties() {
return new boolean[0];
}
@Override
public Set<String> getDirtyPropertyNames() {
public Set<String> dirtyPropertyNames() {
return Collections.emptySet();
}
@@ -340,7 +345,7 @@ public class InterceptReadOnly implements EntityBeanIntercept {
}
@Override
public Map<String, ValuePair> getDirtyValues() {
public Map<String, ValuePair> dirtyValues() {
return Collections.emptyMap();
}
@@ -355,7 +360,7 @@ public class InterceptReadOnly implements EntityBeanIntercept {
}
@Override
public StringBuilder getDirtyPropertyKey() {
public StringBuilder dirtyPropertyKey() {
return null;
}
@@ -365,22 +370,22 @@ public class InterceptReadOnly implements EntityBeanIntercept {
}
@Override
public StringBuilder getLoadedPropertyKey() {
public StringBuilder loadedPropertyKey() {
return null;
}
@Override
public boolean[] getLoaded() {
public boolean[] loaded() {
return new boolean[0];
}
@Override
public int getLazyLoadPropertyIndex() {
public int lazyLoadPropertyIndex() {
return 0;
}
@Override
public String getLazyLoadProperty() {
public String lazyLoadProperty() {
return null;
}
@@ -490,7 +495,7 @@ public class InterceptReadOnly implements EntityBeanIntercept {
}
@Override
public int getSortOrder() {
public int sortOrder() {
return 0;
}
@@ -515,7 +520,7 @@ public class InterceptReadOnly implements EntityBeanIntercept {
}
@Override
public Map<String, Exception> getLoadErrors() {
public Map<String, Exception> loadErrors() {
return 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;
@@ -114,12 +114,30 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
@Override
public EntityBean getOwner() {
public String toString() {
return "InterceptReadWrite@" + hashCode() + "{state=" + state +
(dirty ? " dirty;" : "") +
(forceUpdate ? " forceUpdate;" : "") +
(readOnly ? " readOnly;" : "") +
(disableLazyLoad ? " disableLazyLoad;" : "") +
(lazyLoadFailure ? " lazyLoadFailure;" : "") +
(fullyLoadedBean ? " fullyLoadedBean;" : "") +
(loadedFromCache ? " loadedFromCache;" : "") +
", pc=" + System.identityHashCode(persistenceContext) +
", flags=" + Arrays.toString(flags) +
(lazyLoadProperty > -1 ? (", lazyLoadProperty=" + lazyLoadProperty) : "") +
", loader=" + beanLoader +
(ownerId != null ? (", ownerId=" + ownerId) : "") +
'}';
}
@Override
public EntityBean owner() {
return owner;
}
@Override
public PersistenceContext getPersistenceContext() {
public PersistenceContext persistenceContext() {
return persistenceContext;
}
@@ -134,7 +152,7 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
@Override
public Object getOwnerId() {
public Object ownerId() {
return ownerId;
}
@@ -144,12 +162,12 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
@Override
public Object getEmbeddedOwner() {
public Object embeddedOwner() {
return embeddedOwner;
}
@Override
public int getEmbeddedOwnerIndex() {
public int embeddedOwnerIndex() {
return embeddedOwnerIndex;
}
@@ -173,13 +191,13 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
public void setBeanLoader(BeanLoader beanLoader, PersistenceContext ctx) {
this.beanLoader = beanLoader;
this.persistenceContext = ctx;
this.ebeanServerName = beanLoader.getName();
this.ebeanServerName = beanLoader.name();
}
@Override
public void setBeanLoader(BeanLoader beanLoader) {
this.beanLoader = beanLoader;
this.ebeanServerName = beanLoader.getName();
this.ebeanServerName = beanLoader.name();
}
@Override
@@ -362,8 +380,7 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
@Override
public void setEmbeddedLoaded(Object embeddedBean) {
if (embeddedBean instanceof EntityBean) {
EntityBean eb = (EntityBean) embeddedBean;
eb._ebean_getIntercept().setLoaded();
((EntityBean) embeddedBean)._ebean_getIntercept().setLoaded();
}
}
@@ -383,7 +400,7 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
@Override
public Object getOrigValue(int propertyIndex) {
public Object origValue(int propertyIndex) {
if ((flags[propertyIndex] & (FLAG_ORIG_VALUE_SET | FLAG_MUTABLE_HASH_SET)) == FLAG_MUTABLE_HASH_SET) {
// mutable hash set, but not ORIG_VALUE
setOriginalValue(propertyIndex, mutableInfo[propertyIndex].get());
@@ -396,7 +413,7 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
@Override
public int findProperty(String propertyName) {
String[] names = owner._ebean_getPropertyNames();
final String[] names = owner._ebean_getPropertyNames();
for (int i = 0; i < names.length; i++) {
if (names[i].equals(propertyName)) {
return i;
@@ -406,7 +423,7 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
@Override
public String getProperty(int propertyIndex) {
public String property(int propertyIndex) {
if (propertyIndex == -1) {
return null;
}
@@ -414,13 +431,13 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
@Override
public int getPropertyLength() {
public int propertyLength() {
return flags.length;
}
@Override
public void setPropertyLoaded(String propertyName, boolean loaded) {
int position = findProperty(propertyName);
final int position = findProperty(propertyName);
if (position == -1) {
throw new IllegalArgumentException("Property " + propertyName + " not found");
}
@@ -514,23 +531,23 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
@Override
public Set<String> getLoadedPropertyNames() {
public Set<String> loadedPropertyNames() {
if (fullyLoadedBean) {
return null;
}
Set<String> props = new LinkedHashSet<>();
final Set<String> props = new LinkedHashSet<>();
for (int i = 0; i < flags.length; i++) {
if ((flags[i] & FLAG_LOADED_PROP) != 0) {
props.add(getProperty(i));
props.add(property(i));
}
}
return props;
}
@Override
public boolean[] getDirtyProperties() {
int len = getPropertyLength();
boolean[] dirties = new boolean[len];
public boolean[] dirtyProperties() {
final int len = propertyLength();
final boolean[] dirties = new boolean[len];
for (int i = 0; i < len; i++) {
// this, or an embedded property has been changed - recurse
dirties[i] = (flags[i] & (FLAG_CHANGED_PROP + FLAG_EMBEDDED_DIRTY)) != 0;
@@ -539,31 +556,31 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
@Override
public Set<String> getDirtyPropertyNames() {
Set<String> props = new LinkedHashSet<>();
public Set<String> dirtyPropertyNames() {
final Set<String> props = new LinkedHashSet<>();
addDirtyPropertyNames(props, null);
return props;
}
@Override
public void addDirtyPropertyNames(Set<String> props, String prefix) {
int len = getPropertyLength();
final int len = propertyLength();
for (int i = 0; i < len; i++) {
if (isChangedProp(i)) {
// the property has been changed on this bean
props.add((prefix == null ? getProperty(i) : prefix + getProperty(i)));
props.add((prefix == null ? property(i) : prefix + property(i)));
} else if ((flags[i] & FLAG_EMBEDDED_DIRTY) != 0) {
// an embedded property has been changed - recurse
EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i);
embeddedBean._ebean_getIntercept().addDirtyPropertyNames(props, getProperty(i) + ".");
final EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i);
embeddedBean._ebean_getIntercept().addDirtyPropertyNames(props, property(i) + ".");
}
}
}
@Override
public boolean hasDirtyProperty(Set<String> propertyNames) {
String[] names = owner._ebean_getPropertyNames();
int len = getPropertyLength();
final String[] names = owner._ebean_getPropertyNames();
final int len = propertyLength();
for (int i = 0; i < len; i++) {
if (isChangedProp(i)) {
if (propertyNames.contains(names[i])) {
@@ -579,46 +596,46 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
@Override
public Map<String, ValuePair> getDirtyValues() {
Map<String, ValuePair> dirtyValues = new LinkedHashMap<>();
public Map<String, ValuePair> dirtyValues() {
final Map<String, ValuePair> dirtyValues = new LinkedHashMap<>();
addDirtyPropertyValues(dirtyValues, null);
return dirtyValues;
}
@Override
public void addDirtyPropertyValues(Map<String, ValuePair> dirtyValues, String prefix) {
int len = getPropertyLength();
final int len = propertyLength();
for (int i = 0; i < len; i++) {
if (isChangedProp(i)) {
// the property has been changed on this bean
String propName = (prefix == null ? getProperty(i) : prefix + getProperty(i));
Object newVal = owner._ebean_getField(i);
Object oldVal = getOrigValue(i);
final String propName = (prefix == null ? property(i) : prefix + property(i));
final Object newVal = owner._ebean_getField(i);
final Object oldVal = origValue(i);
if (notEqual(oldVal, newVal)) {
dirtyValues.put(propName, new ValuePair(newVal, oldVal));
}
} else if ((flags[i] & FLAG_EMBEDDED_DIRTY) != 0) {
// an embedded property has been changed - recurse
EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i);
embeddedBean._ebean_getIntercept().addDirtyPropertyValues(dirtyValues, getProperty(i) + ".");
final EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i);
embeddedBean._ebean_getIntercept().addDirtyPropertyValues(dirtyValues, property(i) + ".");
}
}
}
@Override
public void addDirtyPropertyValues(BeanDiffVisitor visitor) {
int len = getPropertyLength();
final int len = propertyLength();
for (int i = 0; i < len; i++) {
if (isChangedProp(i)) {
// the property has been changed on this bean
Object newVal = owner._ebean_getField(i);
Object oldVal = getOrigValue(i);
final Object newVal = owner._ebean_getField(i);
final Object oldVal = origValue(i);
if (notEqual(oldVal, newVal)) {
visitor.visit(i, newVal, oldVal);
}
} else if ((flags[i] & FLAG_EMBEDDED_DIRTY) != 0) {
// an embedded property has been changed - recurse
EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i);
final EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i);
visitor.visitPush(i);
embeddedBean._ebean_getIntercept().addDirtyPropertyValues(visitor);
visitor.visitPop();
@@ -627,8 +644,8 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
@Override
public StringBuilder getDirtyPropertyKey() {
StringBuilder sb = new StringBuilder();
public StringBuilder dirtyPropertyKey() {
final StringBuilder sb = new StringBuilder();
addDirtyPropertyKey(sb);
return sb;
}
@@ -638,24 +655,23 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
if (sortOrder > 0) {
sb.append("s,");
}
int len = getPropertyLength();
final int len = propertyLength();
for (int i = 0; i < len; i++) {
if ((flags[i] & FLAG_CHANGED_PROP) != 0) { // we do not check against mutablecontent here.
sb.append(i).append(',');
} else if ((flags[i] & FLAG_EMBEDDED_DIRTY) != 0) {
// an embedded property has been changed - recurse
EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i);
sb.append(i).append('[');
embeddedBean._ebean_getIntercept().addDirtyPropertyKey(sb);
((EntityBean) owner._ebean_getField(i))._ebean_getIntercept().addDirtyPropertyKey(sb);
sb.append(']');
}
}
}
@Override
public StringBuilder getLoadedPropertyKey() {
StringBuilder sb = new StringBuilder();
int len = getPropertyLength();
public StringBuilder loadedPropertyKey() {
final StringBuilder sb = new StringBuilder();
final int len = propertyLength();
for (int i = 0; i < len; i++) {
if (isLoadedProperty(i)) {
sb.append(i).append(',');
@@ -665,8 +681,8 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
@Override
public boolean[] getLoaded() {
boolean[] ret = new boolean[flags.length];
public boolean[] loaded() {
final boolean[] ret = new boolean[flags.length];
for (int i = 0; i < ret.length; i++) {
ret[i] = (flags[i] & FLAG_LOADED_PROP) != 0;
}
@@ -674,13 +690,13 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
@Override
public int getLazyLoadPropertyIndex() {
public int lazyLoadPropertyIndex() {
return lazyLoadProperty;
}
@Override
public String getLazyLoadProperty() {
return getProperty(lazyLoadProperty);
public String lazyLoadProperty() {
return property(lazyLoadProperty);
}
@Override
@@ -718,7 +734,7 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
if (lazyLoadFailure) {
// failed when batch lazy loaded by another bean in the batch
throw new EntityNotFoundException("(Lazy) loading failed on type:" + owner.getClass().getName() + " id:" + ownerId + " - Bean has been deleted");
throw new EntityNotFoundException("(Lazy) loading failed on type:" + owner.getClass().getName() + " id:" + ownerId + " - Bean has been deleted. BeanLoader: " + beanLoader);
}
if (lazyLoadProperty == -1) {
lazyLoadProperty = loadProperty;
@@ -820,7 +836,7 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
loadBean(propertyIndex);
}
if (nodeUsageCollector != null) {
nodeUsageCollector.addUsed(getProperty(propertyIndex));
nodeUsageCollector.addUsed(property(propertyIndex));
}
}
@@ -969,7 +985,7 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
@Override
public int getSortOrder() {
public int sortOrder() {
return sortOrder;
}
@@ -998,19 +1014,19 @@ public final class InterceptReadWrite implements EntityBeanIntercept {
}
@Override
public Map<String, Exception> getLoadErrors() {
public Map<String, Exception> loadErrors() {
if (loadErrors == null) {
return Collections.emptyMap();
}
Map<String, Exception> ret = null;
int len = getPropertyLength();
int len = propertyLength();
for (int i = 0; i < len; i++) {
Exception loadError = loadErrors[i];
final Exception loadError = loadErrors[i];
if (loadError != null) {
if (ret == null) {
ret = new LinkedHashMap<>();
}
ret.put(getProperty(i), loadError);
ret.put(property(i), loadError);
}
}
return ret;
@@ -8,7 +8,6 @@ import java.util.Objects;
* <p>
* It represents a location relative to the root of an object graph and specific
* to a query and call stack hash.
* </p>
*/
public final class ObjectGraphNode implements Serializable {
@@ -17,7 +16,7 @@ public final class ObjectGraphNode implements Serializable {
/**
* Identifies the origin.
*/
private final ObjectGraphOrigin originQueryPoint;
private final ObjectGraphOrigin origin;
/**
* The path relative to the root.
@@ -28,26 +27,26 @@ public final class ObjectGraphNode implements Serializable {
* Create at a sub level.
*/
public ObjectGraphNode(ObjectGraphNode parent, String path) {
this.originQueryPoint = parent.getOriginQueryPoint();
this.path = parent.getChildPath(path);
this.origin = parent.origin();
this.path = parent.childPath(path);
}
/**
* Create an the root level.
*/
public ObjectGraphNode(ObjectGraphOrigin originQueryPoint, String path) {
this.originQueryPoint = originQueryPoint;
public ObjectGraphNode(ObjectGraphOrigin origin, String path) {
this.origin = origin;
this.path = path;
}
/**
* Return the origin query point.
*/
public ObjectGraphOrigin getOriginQueryPoint() {
return originQueryPoint;
public ObjectGraphOrigin origin() {
return origin;
}
private String getChildPath(String childPath) {
private String childPath(String childPath) {
if (path == null) {
return childPath;
} else if (childPath == null) {
@@ -60,18 +59,18 @@ public final class ObjectGraphNode implements Serializable {
/**
* Return the path relative to the root.
*/
public String getPath() {
public String path() {
return path;
}
@Override
public String toString() {
return "origin:" + originQueryPoint + " path[" + path + "]";
return "origin:" + origin + " path[" + path + "]";
}
@Override
public int hashCode() {
int hc = 92821 * originQueryPoint.hashCode();
int hc = 92821 * origin.hashCode();
hc = 92821 * hc + (path == null ? 0 : path.hashCode());
return hc;
}
@@ -87,6 +86,6 @@ public final class ObjectGraphNode implements Serializable {
ObjectGraphNode e = (ObjectGraphNode) obj;
return (Objects.equals(e.path, path))
&& e.originQueryPoint.equals(originQueryPoint);
&& e.origin.equals(origin);
}
}
@@ -28,38 +28,38 @@ public final class ObjectGraphOrigin implements Serializable {
this.callOrigin = callOrigin;
this.beanType = beanType;
this.queryHash = queryHash;
this.key = callOrigin.getOriginKey(queryHash);
this.key = callOrigin.key(queryHash);
}
/**
* The key includes the queryPlan hash and the callStack hash. This becomes
* the unique identifier for a query point.
*/
public String getKey() {
public String key() {
return key;
}
/**
* The type of bean the query is fetching.
*/
public String getBeanType() {
public String beanType() {
return beanType;
}
/**
* The call stack involved.
*/
public CallOrigin getCallOrigin() {
public CallOrigin callOrigin() {
return callOrigin;
}
public String getTopElement() {
return callOrigin.getTopElement();
public String top() {
return callOrigin.top();
}
@Override
public String toString() {
return "key[" + key + "] type[" + beanType + "] " + callOrigin.getTopElement();
return "key[" + key + "] type[" + beanType + "] " + callOrigin.top();
}
@Override
@@ -19,7 +19,7 @@ public abstract class SingleBeanLoader implements BeanLoader {
}
@Override
public String getName() {
public String name() {
return database.name();
}
@@ -1,7 +1,5 @@
package io.ebean.bean;
import io.ebean.common.BeanMap;
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.Map;
@@ -112,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) {
@@ -59,17 +59,17 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
}
@Override
public EntityBean getOwnerBean() {
public EntityBean owner() {
return ownerBean;
}
@Override
public String getPropertyName() {
public String propertyName() {
return propertyName;
}
@Override
public ExpressionList<?> getFilterMany() {
public ExpressionList<?> filterMany() {
return filterMany;
}
@@ -129,7 +129,7 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
}
@Override
public ModifyListenMode getModifyListening() {
public ModifyListenMode modifyListening() {
return modifyListenMode;
}
@@ -182,7 +182,7 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
}
@Override
public Set<E> getModifyAdditions() {
public Set<E> modifyAdditions() {
if (modifyHolder == null) {
return null;
} else {
@@ -191,7 +191,7 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
}
@Override
public Set<E> getModifyRemovals() {
public Set<E> modifyRemovals() {
if (modifyHolder == null) {
return null;
} else {
@@ -213,7 +213,7 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
}
/**
* Copies all relevant properties for a clone. See {@link #getShallowCopy()}
* Copies all relevant properties for a clone. See {@link #shallowCopy()}
*/
protected void setFromOriginal(AbstractBeanCollection<E> other) {
this.disableLazyLoad = other.disableLazyLoad;
@@ -3,12 +3,7 @@ package io.ebean.common;
import io.ebean.bean.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.*;
/**
* List capable of lazy loading and modification awareness.
@@ -73,7 +68,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
if (list == null) {
list = new ArrayList<>();
}
list.addAll((Collection<? extends E>) other.getActualDetails());
list.addAll((Collection<? extends E>) other.actualDetails());
}
@Override
@@ -159,17 +154,17 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
/**
* Return the actual underlying list.
*/
public List<E> getActualList() {
public List<E> actualList() {
return list;
}
@Override
public Collection<E> getActualDetails() {
public Collection<E> actualDetails() {
return list;
}
@Override
public Collection<?> getActualEntries() {
public Collection<?> actualEntries() {
return list;
}
@@ -538,7 +533,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
}
@Override
public BeanCollection<E> getShallowCopy() {
public BeanCollection<E> shallowCopy() {
BeanList<E> copy = new BeanList<>(new CopyOnFirstWriteList<>(list));
copy.setFromOriginal(this);
return copy;
@@ -5,11 +5,7 @@ import io.ebean.bean.BeanCollectionLoader;
import io.ebean.bean.EntityBean;
import io.ebean.bean.ToStringBuilder;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.*;
/**
* Map capable of lazy loading and modification aware.
@@ -71,7 +67,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
public void loadFrom(BeanCollection<?> other) {
BeanMap<K, E> otherMap = (BeanMap<K, E>) other;
internalPutNull();
map.putAll(otherMap.getActualMap());
map.putAll(otherMap.actualMap());
}
public void internalPutNull() {
@@ -175,7 +171,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
/**
* Return the actual underlying map.
*/
public Map<K, E> getActualMap() {
public Map<K, E> actualMap() {
return map;
}
@@ -183,7 +179,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
* Returns the collection of beans (map values).
*/
@Override
public Collection<E> getActualDetails() {
public Collection<E> actualDetails() {
return map.values();
}
@@ -191,7 +187,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
* Returns the map entrySet.
*/
@Override
public Collection<?> getActualEntries() {
public Collection<?> actualEntries() {
return map.entrySet();
}
@@ -346,7 +342,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
}
@Override
public BeanCollection<E> getShallowCopy() {
public BeanCollection<E> shallowCopy() {
BeanMap<K, E> copy = new BeanMap<>(new LinkedHashMap<>(map));
copy.setFromOriginal(this);
return copy;
@@ -67,7 +67,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
if (set == null) {
set = new LinkedHashSet<>();
}
set.addAll((Collection<? extends E>) other.getActualDetails());
set.addAll((Collection<? extends E>) other.actualDetails());
}
@Override
@@ -155,17 +155,17 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
/**
* Return the actual underlying set.
*/
public Set<E> getActualSet() {
public Set<E> actualSet() {
return set;
}
@Override
public Collection<E> getActualDetails() {
public Collection<E> actualDetails() {
return set;
}
@Override
public Collection<?> getActualEntries() {
public Collection<?> actualEntries() {
return set;
}
@@ -382,7 +382,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
}
@Override
public BeanCollection<E> getShallowCopy() {
public BeanCollection<E> shallowCopy() {
BeanSet<E> copy = new BeanSet<>(new LinkedHashSet<>(set));
copy.setFromOriginal(this);
return copy;
@@ -123,10 +123,10 @@ public class DatabaseConfig {
private boolean loadModuleInfo = true;
/**
* List of interesting classes such as entities, embedded, ScalarTypes,
* Listeners, Finders, Controllers etc.
* Interesting classes such as entities, embedded, ScalarTypes,
* Listeners, Finders, Controllers, AttributeConverters etc.
*/
private List<Class<?>> classes = new ArrayList<>();
private Set<Class<?>> classes = new HashSet<>();
/**
* The packages that are searched for interesting classes. Only used when
@@ -2320,8 +2320,7 @@ public class DatabaseConfig {
}
/**
* Programmatically add classes (typically entities) that this server should
* use.
* Programmatically add classes (typically entities) that this server should use.
* <p>
* The class can be an Entity, Embedded type, ScalarType, BeanPersistListener,
* BeanFinder or BeanPersistController.
@@ -2331,8 +2330,7 @@ public class DatabaseConfig {
* <p>
* Alternatively the classes can be added via {@link #setClasses(List)}.
*
* @param cls the entity type (or other type) that should be registered by this
* database.
* @param cls the entity type (or other type) that should be registered by this database.
*/
public void addClass(Class<?> cls) {
classes.add(cls);
@@ -2341,7 +2339,7 @@ public class DatabaseConfig {
/**
* Register all the classes (typically entity classes).
*/
public void addAll(List<Class<?>> classList) {
public void addAll(Collection<Class<?>> classList) {
if (classList != null && !classList.isEmpty()) {
classes.addAll(classList);
}
@@ -2383,15 +2381,26 @@ public class DatabaseConfig {
* <p>
* Alternatively the classes can contain added via {@link #addClass(Class)}.
*/
public void setClasses(List<Class<?>> classes) {
this.classes = classes;
public void setClasses(Collection<Class<?>> classes) {
this.classes = new HashSet<>(classes);
}
/**
* Return the classes registered for this database. Typically this includes
* Return the classes registered for this database. Typically, this includes
* entities and perhaps listeners.
*/
public List<Class<?>> getClasses() {
public Set<Class<?>> classes() {
return classes;
}
/**
* Deprecated - migrate to classes().
* <p>
* Sorry if returning Set rather than List breaks code but it feels safer to
* do that than a subtle change to return a shallow copy which you will not detect.
*/
@Deprecated
public Set<Class<?>> getClasses() {
return classes;
}
@@ -2760,8 +2769,6 @@ public class DatabaseConfig {
this.classLoadConfig = classLoadConfig;
}
/**
* Load settings from application.properties, application.yaml and other sources.
* <p>
@@ -2906,7 +2913,7 @@ public class DatabaseConfig {
serverCachePlugin = p.createInstance(ServerCachePlugin.class, "serverCachePlugin", serverCachePlugin);
String packagesProp = p.get("search.packages", p.get("packages", null));
packages = getSearchList(packagesProp, packages);
packages = searchList(packagesProp, packages);
skipCacheAfterWrite = p.getBoolean("skipCacheAfterWrite", skipCacheAfterWrite);
updateAllPropertiesInBatch = p.getBoolean("updateAllPropertiesInBatch", updateAllPropertiesInBatch);
@@ -2982,10 +2989,10 @@ public class DatabaseConfig {
tenantCatalogProvider = p.createInstance(TenantCatalogProvider.class, "tenant.catalogProvider", tenantCatalogProvider);
tenantSchemaProvider = p.createInstance(TenantSchemaProvider.class, "tenant.schemaProvider", tenantSchemaProvider);
tenantPartitionColumn = p.get("tenant.partitionColumn", tenantPartitionColumn);
classes = getClasses(p);
classes = readClasses(p);
String mappingsProp = p.get("mappingLocations", null);
mappingLocations = getSearchList(mappingsProp, mappingLocations);
mappingLocations = searchList(mappingsProp, mappingLocations);
}
private NamingConvention createNamingConvention(PropertiesWrapper properties, NamingConvention namingConvention) {
@@ -2999,13 +3006,13 @@ public class DatabaseConfig {
* @param properties the properties
* @return the classes
*/
private List<Class<?>> getClasses(PropertiesWrapper properties) {
private Set<Class<?>> readClasses(PropertiesWrapper properties) {
String classNames = properties.get("classes", null);
if (classNames == null) {
return classes;
}
List<Class<?>> classList = new ArrayList<>();
Set<Class<?>> classList = new HashSet<>();
String[] split = StringHelper.splitNames(classNames);
for (String cn : split) {
if (!"class".equalsIgnoreCase(cn)) {
@@ -3020,7 +3027,7 @@ public class DatabaseConfig {
return classList;
}
private List<String> getSearchList(String searchNames, List<String> defaultValue) {
private List<String> searchList(String searchNames, List<String> defaultValue) {
if (searchNames != null) {
String[] entries = StringHelper.splitNames(searchNames);
List<String> hitList = new ArrayList<>(entries.length);
@@ -3399,8 +3406,16 @@ public class DatabaseConfig {
* When false we either register entity classes via application code or use classpath
* scanning to find and register entity classes.
*/
public boolean isLoadModuleInfo() {
return loadModuleInfo;
}
/**
* Deprecated - migrate to isLoadModuleInfo().
*/
@Deprecated
public boolean isAutoLoadModuleInfo() {
return loadModuleInfo && classes.isEmpty();
return loadModuleInfo;
}
/**
@@ -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;
}
@@ -143,7 +143,7 @@ public final class ShutdownManager {
}
// shutdown any registered servers that have not
// already been shutdown manually
for (Database server : databases) {
for (Database server : new ArrayList<>(databases)) {
try {
server.shutdown();
} catch (Exception ex) {
@@ -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();
}
@@ -22,6 +22,7 @@ public final class StackWalkFilter {
public boolean test(StackWalker.StackFrame stackFrame) {
return !stackFrame.getClassName().startsWith("io.ebean")
&& !stackFrame.getClassName().startsWith("jdk.")
&& !stackFrame.getClassName().startsWith("java.")
&& !stackFrame.getMethodName().startsWith("_ebean_");
}
}
@@ -3,10 +3,6 @@ package io.ebean.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.ebean.annotation.MutationDetection;
import io.ebean.annotation.PersistBatch;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.JsonConfig;
import io.ebean.config.MatchingNamingConvention;
import io.ebean.config.PlatformConfig;
import io.ebean.config.dbplatform.IdType;
import io.ebean.datasource.DataSourceConfig;
import org.junit.jupiter.api.Assertions;
@@ -93,6 +89,7 @@ class DatabaseConfigTest {
assertTrue(config.isDbOffline());
assertTrue(config.isAutoReadOnlyDataSource());
assertTrue(config.isAutoLoadModuleInfo());
assertTrue(config.isLoadModuleInfo());
assertTrue(config.skipDataSourceCheck());
assertTrue(config.isIdGeneratorAutomatic());
@@ -165,6 +162,7 @@ class DatabaseConfigTest {
assertEquals(MutationDetection.HASH, config.getJsonMutationDetection());
assertTrue(config.getPlatformConfig().isCaseSensitiveCollation());
assertTrue(config.isAutoLoadModuleInfo());
assertTrue(config.isLoadModuleInfo());
assertFalse(config.isQueryPlanEnable());
assertEquals(Long.MAX_VALUE, config.getQueryPlanThresholdMicros());
@@ -175,6 +173,7 @@ class DatabaseConfigTest {
config.setLoadModuleInfo(false);
assertFalse(config.isAutoLoadModuleInfo());
assertFalse(config.isLoadModuleInfo());
config.setAutoPersistUpdates(true);
assertTrue(config.isAutoPersistUpdates());
config.setSkipDataSourceCheck(true);
+12 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
@@ -59,6 +59,13 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.avaje</groupId>
<artifactId>junit</artifactId>
@@ -69,7 +76,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
@@ -80,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>
@@ -97,7 +97,7 @@ public class AutoTuneDiffCollection {
OrmQueryDetail profileDetail = entry.getDetail();
// compare with the existing query tuning entry
OrmQueryDetail tuneDetail = queryTuner.get(point.getKey());
OrmQueryDetail tuneDetail = queryTuner.get(point.key());
if (tuneDetail == null) {
addToDocumentNewEntry(entry, point);
@@ -145,10 +145,10 @@ public class AutoTuneDiffCollection {
private Origin createOrigin(AutoTuneCollection.Entry entry, ObjectGraphOrigin point, String query) {
Origin origin = new Origin();
origin.setKey(point.getKey());
origin.setBeanType(point.getBeanType());
origin.setKey(point.key());
origin.setBeanType(point.beanType());
origin.setDetail(entry.getDetail().asString());
origin.setCallStack(point.getCallOrigin().getFullDescription());
origin.setCallStack(point.callOrigin().description());
origin.setOriginal(query);
if (updateTuning) {
@@ -122,7 +122,7 @@ public class BaseQueryTuner {
if (queryTuning) {
// get current "tuned fetch" for this query point
TunedQueryInfo tuneInfo = tunedQueryInfoMap.get(origin.getOriginQueryPoint().getKey());
TunedQueryInfo tuneInfo = tunedQueryInfoMap.get(origin.origin().key());
return tuneInfo != null && tuneInfo.tuneQuery(query);
}
return false;
@@ -46,9 +46,9 @@ public class ProfileManager implements ProfilingListener {
@Override
public boolean isProfileRequest(ObjectGraphNode origin, SpiQuery<?> query) {
ProfileOrigin profileOrigin = profileMap.get(origin.getOriginQueryPoint().getKey());
ProfileOrigin profileOrigin = profileMap.get(origin.origin().key());
if (profileOrigin == null) {
profileMap.put(origin.getOriginQueryPoint().getKey(), createProfileOrigin(origin, query));
profileMap.put(origin.origin().key(), createProfileOrigin(origin, query));
return true;
} else {
return profileOrigin.isProfile();
@@ -62,7 +62,7 @@ public class ProfileManager implements ProfilingListener {
* query detail that is specified in the code (as the query might already be manually optimised).
*/
private ProfileOrigin createProfileOrigin(ObjectGraphNode origin, SpiQuery<?> query) {
ProfileOrigin profileOrigin = new ProfileOrigin(origin.getOriginQueryPoint(), queryTuningAddVersion, profilingBase, profilingRate);
ProfileOrigin profileOrigin = new ProfileOrigin(origin.origin(), queryTuningAddVersion, profilingBase, profilingRate);
// set the current query detail (fetch group) so that we can compare against profiling for new entries
profileOrigin.setOriginalQuery(query.getDetail().asString());
return profileOrigin;
@@ -76,7 +76,7 @@ public class ProfileManager implements ProfilingListener {
@Override
public void collectQueryInfo(ObjectGraphNode node, long beans, long micros) {
if (node != null) {
ObjectGraphOrigin origin = node.getOriginQueryPoint();
ObjectGraphOrigin origin = node.origin();
if (origin != null) {
ProfileOrigin stats = getProfileOrigin(origin);
stats.collectQueryInfo(node, beans, micros);
@@ -92,14 +92,14 @@ public class ProfileManager implements ProfilingListener {
*/
@Override
public void collectNodeUsage(NodeUsageCollector.State usageCollector) {
ProfileOrigin profileOrigin = getProfileOrigin(usageCollector.node().getOriginQueryPoint());
ProfileOrigin profileOrigin = getProfileOrigin(usageCollector.node().origin());
profileOrigin.collectUsageInfo(usageCollector);
}
private ProfileOrigin getProfileOrigin(ObjectGraphOrigin originQueryPoint) {
lock.lock();
try {
return profileMap.computeIfAbsent(originQueryPoint.getKey(), k -> new ProfileOrigin(originQueryPoint, queryTuningAddVersion, profilingBase, profilingRate));
return profileMap.computeIfAbsent(originQueryPoint.key(), k -> new ProfileOrigin(originQueryPoint, queryTuningAddVersion, profilingBase, profilingRate));
} finally {
lock.unlock();
}
@@ -111,7 +111,7 @@ public class ProfileManager implements ProfilingListener {
public AutoTuneCollection profilingCollection(boolean reset) {
AutoTuneCollection req = new AutoTuneCollection();
for (ProfileOrigin origin : profileMap.values()) {
BeanDescriptor<?> desc = server.descriptorById(origin.getOrigin().getBeanType());
BeanDescriptor<?> desc = server.descriptorById(origin.getOrigin().beanType());
if (desc != null) {
origin.profilingCollection(desc, req, reset);
}
@@ -134,7 +134,7 @@ public class ProfileOrigin {
*/
public void collectQueryInfo(ObjectGraphNode node, long beansLoaded, long micros) {
String key = node.getPath();
String key = node.path();
if (key == null) {
key = "";
}
@@ -153,7 +153,7 @@ public class ProfileOrigin {
*/
public void collectUsageInfo(NodeUsageCollector.State profile) {
if (!profile.isEmpty()) {
getNodeStats(profile.node().getPath()).collectUsageInfo(profile);
getNodeStats(profile.node().path()).collectUsageInfo(profile);
}
}
@@ -1,28 +1,37 @@
package org.tests.autofetch;
import io.ebean.DB;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Order;
import java.util.List;
public class MainAutoQueryTune1 {
// public static void main(String[] args) {
//
// ResetBasicData.reset();
//
// MainAutoQueryTune1 me = new MainAutoQueryTune1();
// me.tuneJoin();
// }
//
// private void tuneJoin() {
// List<Order> list = Ebean.find(Order.class)
// .setAutoTune(true)
// .fetch("customer")
// .where()
// .eq("status", Order.Status.NEW)
// .eq("customer.name", "Rob")
// .order().asc("id")
// .findList();
//
// for (Order order : list) {
// order.getId();
// order.getOrderDate();
// }
// }
public static void main(String[] args) {
MainAutoQueryTune1 me = new MainAutoQueryTune1();
me.tuneJoin();
}
@Test
void tuneJoin() {
TestData.load();
List<Order> list = DB.find(Order.class)
.setAutoTune(true)
//.fetch("customer")
.where()
.eq("status", Order.Status.NEW)
.eq("customer.name", "Rob")
.order().asc("id")
.findList();
for (Order order : list) {
order.getId();
order.getOrderDate();
order.getCustomer().getName();
order.getCustomer().getNote();
}
}
}
@@ -0,0 +1,25 @@
package org.tests.autofetch;
import io.ebean.DB;
import org.tests.model.basic.Address;
import org.tests.model.basic.Customer;
import org.tests.model.basic.Order;
import java.time.LocalDate;
public class TestData {
static void load() {
if (DB.find(Order.class).findCount() > 0) {
return;
}
var customer = new Customer("Rob");
customer.setBillingAddress(new Address("l0", "city0"));
DB.save(customer);
var order = new Order(customer);
order.setOrderDate(LocalDate.now());
DB.save(order);
}
}
@@ -1,17 +1,21 @@
package org.tests.model.basic;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "address")
@Table(name = "o_address")
public class Address extends BaseModel {
String line1;
String line2;
String city;
public Address(String line1, String city) {
this.line1 = line1;
this.city = city;
}
public String getLine1() {
return line1;
}
@@ -1,5 +1,8 @@
package org.tests.model.basic;
import io.ebean.annotation.NotNull;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@@ -8,13 +11,17 @@ import javax.persistence.Table;
@Table(name = "o_customer")
public class Customer extends BaseModel {
String name;
@NotNull String name;
String note;
@ManyToOne
@ManyToOne(cascade = CascadeType.PERSIST)
Address billingAddress;
public Customer(String name) {
this.name = name;
}
public String getName() {
return name;
}
@@ -1,21 +1,10 @@
package org.tests.model.basic;
import io.ebean.Model;
import io.ebean.annotation.WhenModified;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Version;
import java.sql.Timestamp;
import javax.persistence.*;
import java.time.LocalDate;
@Entity
@Table(name = "orders")
@Table(name = "o_order")
public class Order extends BaseModel {
public enum Status {
@@ -32,7 +21,11 @@ public class Order extends BaseModel {
LocalDate orderDate;
@ManyToOne(cascade = CascadeType.PERSIST)
Customer customer;
final Customer customer;
public Order(Customer customer) {
this.customer = customer;
}
public Status getStatus() {
return status;
@@ -54,7 +47,4 @@ public class Order extends BaseModel {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
@@ -9,3 +9,9 @@ datasource.h2.url=jdbc:h2:mem:h2AutoTune
datasource.pg.username=sa
datasource.pg.password=
datasource.pg.url=jdbc:h2:mem:h2AutoTune
ebean.autoTune.profiling=true
ebean.maxCallStack=10
ebean.autoTune.queryTuning=true
ebean.autoTune.queryTuningFile=autotune/my-autotune.xml
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<autotune xmlns="http://ebean-orm.github.io/xml/ns/autotune">
<origin key="BmouL7.Bn_jgL.BNY1QD" beanType="org.tests.model.basic.Order" detail="select (orderDate) fetch customer (name,note)" original="">
<callStack>org.tests.autofetch.MainAutoQueryTune1.tuneJoin(MainAutoQueryTune1.java:27)
org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)</callStack>
</origin>
</autotune>
@@ -12,10 +12,11 @@
<appender-ref ref="STDOUT"/>
</root>
<logger name="io.ebeaninternal" level="DEBUG"/>
<logger name="io.ebean.docker" level="TRACE"/>
<!-- <logger name="io.ebean.DDL" level="DEBUG"/>-->
<!-- <logger name="io.ebean.SQL" level="TRACE"/>-->
<logger name="io.ebean.SQL" level="TRACE"/>
<!-- <logger name="io.ebean.TXN" level="TRACE"/>-->
<!-- <logger name="io.ebean.SUM" level="TRACE"/>-->
<logger name="io.ebean.SUM" level="TRACE"/>
</configuration>
+30 -30
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-joda-time</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-jsonnode</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-xml</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-autotune</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>kotlin-querybean-generator</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-redis</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-spring-txn</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<!-- platforms -->
@@ -202,67 +202,67 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-clickhouse</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-db2</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-h2</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-hana</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mariadb</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mysql</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-nuodb</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-oracle</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgres</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlite</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlserver</artifactId>
<version>13.14.1</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.14.1</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.14.1</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.14.1</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.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -46,13 +46,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
</dependency>
<dependency>
@@ -143,21 +143,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.14.1</version>
<version>13.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.14.1</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.getLazyLoadProperty(), ebi.isLoaded(), loadCache || ebi.isLoadedFromCache());
this(loadBuffer, null, true, ebi.lazyLoadProperty(), ebi.isLoaded(), loadCache || ebi.isLoadedFromCache());
this.triggerEbi = String.valueOf(ebi);
}
/**
@@ -53,20 +63,23 @@ 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> getIdList() {
List<Object> idList = new ArrayList<>();
BeanDescriptor<?> desc = loadBuffer.descriptor();
private List<Object> ids() {
final List<Object> idList = new ArrayList<>(batch.size());
final BeanDescriptor<?> desc = loadBuffer.descriptor();
for (EntityBeanIntercept ebi : batch) {
idList.add(desc.getId(ebi.getOwner()));
idList.add(desc.getId(ebi.owner()));
}
return idList;
}
@@ -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
@@ -111,44 +129,33 @@ public final class LoadBeanRequest extends LoadRequest {
desc.cacheBeanPutAll(list);
}
if (lazyLoadProperty != null) {
List<EntityBeanIntercept> missed = new ArrayList<>();
Set<Object> missedIds = new HashSet<>();
for (EntityBeanIntercept ebi : batch) {
// check if the underlying row in DB was deleted. Mark the bean as 'failed' if
// necessary but allow processing to continue until it is accessed by client code
Object id = desc.getId(ebi.getOwner());
Object id = desc.getId(ebi.owner());
if (!loadedIds.contains(id)) {
// assume this is logically deleted (hence not found)
desc.markAsDeleted(ebi.getOwner());
missedIds.add(id);
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);
}
return EMPTY_RESULT;
}
static final Result EMPTY_RESULT = new Result(Collections.emptySet(),Collections.emptySet());
public static class Result {
private final Set<Object> loadedIds;
private final Set<Object> missedIds;
Result(Set<Object> loadedIds, Set<Object> missedIds) {
this.loadedIds = loadedIds;
this.missedIds = missedIds;
}
public boolean markedDeleted() {
return !missedIds.isEmpty();
}
public Set<Object> missedIds() {
return missedIds;
}
public Set<Object> loadedIds() {
return loadedIds;
}
}
}
@@ -16,7 +16,7 @@ public interface LoadContext {
/**
* Return the minimum batch size when using QueryIterator with query joins.
*/
int getSecondaryQueriesMinBatchSize();
int secondaryQueriesMinBatchSize();
/**
* Execute any secondary (+query) queries if there are any defined.
@@ -29,12 +29,12 @@ public interface LoadContext {
/**
* Return the node for a given path which is used by AutoTune profiling.
*/
ObjectGraphNode getObjectGraphNode(String path);
ObjectGraphNode objectGraphNode(String path);
/**
* Return the persistence context used by this query and future lazy loading.
*/
PersistenceContext getPersistenceContext();
PersistenceContext persistenceContext();
/**
* Register a Bean for lazy loading.
@@ -31,15 +31,15 @@ public interface LoadManyBuffer {
*/
boolean removeFromBuffer(BeanCollection<?> collection);
BeanPropertyAssocMany<?> getBeanProperty();
BeanPropertyAssocMany<?> beanProperty();
ObjectGraphNode getObjectGraphNode();
ObjectGraphNode objectGraphNode();
BeanDescriptor<?> getBeanDescriptor();
BeanDescriptor<?> descriptor();
PersistenceContext getPersistenceContext();
PersistenceContext persistenceContext();
String getFullPath();
String fullPath();
void configureQuery(SpiQuery<?> query);
@@ -50,11 +50,11 @@ public final class LoadManyRequest extends LoadRequest {
@Override
public Class<?> beanType() {
return loadContext.getBeanDescriptor().type();
return loadContext.descriptor().type();
}
public String description() {
return loadContext.getFullPath();
return loadContext.fullPath();
}
private List<Object> parentIdList(SpiEbeanServer server) {
@@ -66,13 +66,13 @@ public final class LoadManyRequest extends LoadRequest {
if (lazy && !originIncluded && bc == originCollection) {
originIncluded = true;
}
idList.add(many.parentId(bc.getOwnerBean()));
idList.add(many.parentId(bc.owner()));
bc.setLoader(server); // don't use the load buffer again
}
}
if (originCollection != null && !originIncluded) {
CoreLog.log.log(INFO, "Batch lazy loading including origin collection - size:{0}", idList.size());
idList.add(many.parentId(originCollection.getOwnerBean()));
idList.add(many.parentId(originCollection.owner()));
originCollection.setLoader(server); // don't use the load buffer again
}
if (many.targetDescriptor().isPadInExpression()) {
@@ -82,7 +82,7 @@ public final class LoadManyRequest extends LoadRequest {
}
private BeanPropertyAssocMany<?> many() {
return loadContext.getBeanProperty();
return loadContext.beanProperty();
}
public SpiQuery<?> createQuery(SpiEbeanServer server) {
@@ -100,7 +100,7 @@ public final class LoadManyRequest extends LoadRequest {
}
query.setLazyLoadForParents(many);
many.addWhereParentIdIn(query, parentIdList(server), loadContext.isUseDocStore());
query.setPersistenceContext(loadContext.getPersistenceContext());
query.setPersistenceContext(loadContext.persistenceContext());
query.setLoadDescription(lazy ? "+lazy" : "+query", description());
if (lazy) {
query.setLazyLoadBatchSize(loadContext.batchSize());
@@ -120,7 +120,7 @@ public final class LoadManyRequest extends LoadRequest {
* After the query execution check for empty collections and load L2 cache if desired.
*/
public void postLoad() {
BeanDescriptor<?> desc = loadContext.getBeanDescriptor();
BeanDescriptor<?> desc = loadContext.descriptor();
BeanPropertyAssocMany<?> many = many();
// check for BeanCollection's that where never processed
// in the +query or +lazy load due to no rows (predicates)
@@ -129,12 +129,12 @@ public final class LoadManyRequest extends LoadRequest {
if (bc != null) {
if (bc.checkEmptyLazyLoad()) {
if (log.isLoggable(DEBUG)) {
EntityBean ownerBean = bc.getOwnerBean();
EntityBean ownerBean = bc.owner();
Object parentId = desc.getId(ownerBean);
log.log(DEBUG, "BeanCollection after lazy load was empty. type:{0} id:{1} owner:{2}", ownerBean.getClass().getName(), parentId, ownerBean);
}
} else if (loadCache && many.isUseCache()) {
desc.cacheManyPropPut(many, bc, desc.cacheKeyForBean(bc.getOwnerBean()));
desc.cacheManyPropPut(many, bc, desc.cacheKeyForBean(bc.owner()));
}
}
}
@@ -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,7 +14,7 @@ public interface SpiExpressionRequest {
/**
* Return the DB specific handler for JSON and ARRAY expressions.
*/
DbExpressionHandler getDbPlatformHandler();
DbExpressionHandler platformHandler();
/**
* Parse the logical property name to the deployment name.
@@ -24,17 +24,30 @@ public interface SpiExpressionRequest {
/**
* Return the bean descriptor for the root type.
*/
BeanDescriptor<?> getBeanDescriptor();
BeanDescriptor<?> descriptor();
/**
* Return the associated QueryRequest.
*/
SpiOrmQueryRequest<?> getQueryRequest();
SpiOrmQueryRequest<?> queryRequest();
/**
* Append to the expression sql.
* Append to the expression sql without any parsing.
*/
SpiExpressionRequest append(String sql);
SpiExpressionRequest append(String expression);
/**
* Append to the expression sql with logical property parsing to db columns with logical path prefix.
* <p>
* This is a fast path case when expression is a bean property path and falls back to using parse()
* when that isn't the case.
*/
SpiExpressionRequest property(String expression);
/**
* Append to the expression sql with logical property parsing to db columns with logical path prefix.
*/
SpiExpressionRequest parse(String expression);
/**
* Add an encryption key to bind to this request.
@@ -49,12 +62,12 @@ public interface SpiExpressionRequest {
/**
* Return the accumulated expression sql for all expressions in this request.
*/
String getSql();
String sql();
/**
* Return the ordered list of bind values for all expressions in this request.
*/
List<Object> getBindValues();
List<Object> bindValues();
/**
* Increments the parameter index and returns that value.
@@ -34,5 +34,5 @@ public interface SpiJsonReader {
Object readValueUsingObjectMapper(Class<?> propertyType) throws IOException;
boolean intercept();
boolean update();
}
@@ -14,11 +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.*;
import static java.lang.System.Logger.Level.DEBUG;
/**
* Helper to handle lazy loading and refreshing of beans.
@@ -41,7 +39,7 @@ final class DefaultBeanLoader {
}
void loadMany(BeanCollection<?> bc, boolean onlyIds) {
loadManyInternal(bc.getOwnerBean(), bc.getPropertyName(), false, onlyIds);
loadManyInternal(bc.owner(), bc.propertyName(), false, onlyIds);
}
void refreshMany(EntityBean parentBean, String propertyName) {
@@ -50,7 +48,7 @@ final class DefaultBeanLoader {
private void loadManyInternal(EntityBean parentBean, String propertyName, boolean refresh, boolean onlyIds) {
EntityBeanIntercept ebi = parentBean._ebean_getIntercept();
PersistenceContext pc = ebi.getPersistenceContext();
PersistenceContext pc = ebi.persistenceContext();
BeanDescriptor<?> parentDesc = server.descriptor(parentBean.getClass());
BeanPropertyAssocMany<?> many = (BeanPropertyAssocMany<?>) parentDesc.beanProperty(propertyName);
BeanCollection<?> beanCollection = null;
@@ -59,7 +57,7 @@ final class DefaultBeanLoader {
Object currentValue = many.getValue(parentBean);
if (currentValue instanceof BeanCollection<?>) {
beanCollection = (BeanCollection<?>) currentValue;
filterMany = beanCollection.getFilterMany();
filterMany = beanCollection.filterMany();
}
Object parentId = parentDesc.getId(parentBean);
@@ -112,7 +110,7 @@ final class DefaultBeanLoader {
if (beanCollection != null) {
if (beanCollection.checkEmptyLazyLoad()) {
if (log.isLoggable(DEBUG)) {
log.log(DEBUG, "BeanCollection after load was empty. Owner:{0}", beanCollection.getOwnerBean());
log.log(DEBUG, "BeanCollection after load was empty. Owner:{0}", beanCollection.owner());
}
} else if (useManyIdCache) {
final String parentKey = parentDesc.cacheKey(parentId);
@@ -125,25 +123,12 @@ final class DefaultBeanLoader {
* Load a batch of beans for +query or +lazy loading.
*/
void loadBean(LoadBeanRequest loadRequest) {
Set<EntityBeanIntercept> batch = loadRequest.batch();
if (batch.isEmpty()) {
if (loadRequest.checkEmpty()) {
throw new RuntimeException("Nothing in batch?");
}
List<Object> idList = loadRequest.getIdList();
if (idList.isEmpty()) {
// everything was loaded from cache
return;
}
SpiQuery<?> query = server.createQuery(loadRequest.beanType());
loadRequest.configureQuery(query, idList);
final List<?> list = executeQuery(loadRequest, query);
final LoadBeanRequest.Result result = loadRequest.postLoad(list);
if (result.markedDeleted() && CoreLog.markedAsDeleted.isLoggable(DEBUG)) {
String msg = MessageFormat.format("Loaded bean marked as deleted for {0} missedIds:{1} loadedIds:{2} sql:{3} list:{4}", loadRequest.beanType(), result.missedIds(), result.loadedIds(), query.getGeneratedSql(), list);
CoreLog.markedAsDeleted.log(DEBUG, msg, new RuntimeException("LoadBeanRequest markedAsDeleted"));
}
final SpiQuery<?> query = server.createQuery(loadRequest.beanType());
loadRequest.configureQuery(query);
loadRequest.postLoad(executeQuery(loadRequest, query));
}
/**
@@ -168,12 +153,12 @@ final class DefaultBeanLoader {
}
void loadBean(EntityBeanIntercept ebi) {
refreshBeanInternal(ebi.getOwner(), SpiQuery.Mode.LAZYLOAD_BEAN, -1);
refreshBeanInternal(ebi.owner(), SpiQuery.Mode.LAZYLOAD_BEAN, -1);
}
private void refreshBeanInternal(EntityBean bean, SpiQuery.Mode mode, int embeddedOwnerIndex) {
EntityBeanIntercept ebi = bean._ebean_getIntercept();
PersistenceContext pc = ebi.getPersistenceContext();
PersistenceContext pc = ebi.persistenceContext();
if (Mode.REFRESH_BEAN == mode) {
// need a new PersistenceContext for REFRESH
pc = null;
@@ -181,8 +166,8 @@ final class DefaultBeanLoader {
BeanDescriptor<?> desc = server.descriptor(bean.getClass());
if (EntityType.EMBEDDED == desc.entityType()) {
// lazy loading on an embedded bean property
EntityBean embeddedOwner = (EntityBean) ebi.getEmbeddedOwner();
refreshBeanInternal(embeddedOwner, mode, ebi.getEmbeddedOwnerIndex());
EntityBean embeddedOwner = (EntityBean) ebi.embeddedOwner();
refreshBeanInternal(embeddedOwner, mode, ebi.embeddedOwnerIndex());
}
Object id = desc.getId(bean);
if (pc == null) {
@@ -204,14 +189,14 @@ final class DefaultBeanLoader {
}
}
SpiQuery<?> query = server.createQuery(desc.type());
query.setLazyLoadProperty(ebi.getLazyLoadProperty());
query.setLazyLoadProperty(ebi.lazyLoadProperty());
if (draft) {
query.asDraft();
} else if (mode == SpiQuery.Mode.LAZYLOAD_BEAN && desc.isSoftDelete()) {
query.setIncludeSoftDeletes();
}
if (embeddedOwnerIndex > -1) {
query.select(ebi.getProperty(embeddedOwnerIndex));
query.select(ebi.property(embeddedOwnerIndex));
}
// don't collect AutoTune usage profiling information
// as we just copy the data out of these fetched beans
@@ -46,17 +46,17 @@ public final class DefaultBeanState implements BeanState {
@Override
public Set<String> loadedProps() {
return intercept.getLoadedPropertyNames();
return intercept.loadedPropertyNames();
}
@Override
public Set<String> changedProps() {
return intercept.getDirtyPropertyNames();
return intercept.dirtyPropertyNames();
}
@Override
public Map<String, ValuePair> dirtyValues() {
return intercept.getDirtyValues();
return intercept.dirtyValues();
}
@Override
@@ -91,11 +91,11 @@ public final class DefaultBeanState implements BeanState {
@Override
public Map<String, Exception> loadErrors() {
return intercept.getLoadErrors();
return intercept.loadErrors();
}
@Override
public int sortOrder() {
return intercept.getSortOrder();
return intercept.sortOrder();
}
}
@@ -17,8 +17,8 @@ import javax.persistence.PersistenceException;
import java.net.URL;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
import static java.lang.System.Logger.Level.*;
@@ -121,7 +121,7 @@ public final class DefaultContainer implements SpiContainer {
configProvider.apply(config);
}
}
if (config.isAutoLoadModuleInfo()) {
if (config.isLoadModuleInfo()) {
// auto register entity classes
boolean found = false;
for (EntityClassRegister loader : ServiceLoader.load(EntityClassRegister.class)) {
@@ -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.");
}
}
@@ -177,10 +177,10 @@ public final class DefaultContainer implements SpiContainer {
* Get the class based entities, scalarTypes, Listeners etc.
*/
private BootupClasses bootupClasses1(DatabaseConfig config) {
List<Class<?>> entityClasses = config.getClasses();
if (config.isDisableClasspathSearch() || (entityClasses != null && !entityClasses.isEmpty())) {
Set<Class<?>> classes = config.classes();
if (config.isDisableClasspathSearch() || (classes != null && !classes.isEmpty())) {
// use classes we explicitly added via configuration
return new BootupClasses(entityClasses);
return new BootupClasses(classes);
}
return BootupClassPathSearch.search(config);
}
@@ -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;
@@ -354,50 +355,35 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
public void shutdown() {
lock.lock();
try {
shutdownInternal(true, false);
} finally {
lock.unlock();
}
shutdown(true, false);
}
/**
* Shutting down manually.
*/
@Override
public void shutdown(boolean shutdownDataSource, boolean deregisterDriver) {
lock.lock();
try {
ShutdownManager.unregisterDatabase(this);
shutdownInternal(shutdownDataSource, deregisterDriver);
log.log(TRACE, "shutting down instance {0}", serverName);
if (shutdown) {
// already shutdown
return;
}
shutdownPlugins();
autoTuneService.shutdown();
// shutdown background threads
backgroundExecutor.shutdown();
// shutdown DataSource (if its an Ebean one)
transactionManager.shutdown(shutdownDataSource, deregisterDriver);
dumpMetrics();
shutdown = true;
if (shutdownDataSource) {
config.setDataSource(null);
}
} finally {
lock.unlock();
}
}
/**
* Shutdown the services like threads and DataSource.
*/
private void shutdownInternal(boolean shutdownDataSource, boolean deregisterDriver) {
log.log(TRACE, "shutting down instance {0}", serverName);
if (shutdown) {
// already shutdown
return;
}
shutdownPlugins();
autoTuneService.shutdown();
// shutdown background threads
backgroundExecutor.shutdown();
// shutdown DataSource (if its an Ebean one)
transactionManager.shutdown(shutdownDataSource, deregisterDriver);
dumpMetrics();
shutdown = true;
if (shutdownDataSource) {
config.setDataSource(null);
}
}
private void dumpMetrics() {
if (config.isDumpMetricsOnShutdown()) {
new DumpMetrics(this, config.getDumpMetricsOptions()).dump();
@@ -574,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);
}
}
}
@@ -601,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();
}
/**
@@ -641,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
@@ -888,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());
@@ -904,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);
}
@@ -962,13 +956,15 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
if (transaction == null) {
transaction = currentServerTransaction();
}
query.setDefaultRawSqlIfRequired();
if (query.isAutoTunable() && !autoTuneService.tuneQuery(query)) {
// use deployment FetchType.LAZY/EAGER annotations
// to define the 'default' select clause
query.setDefaultSelectClause();
if (!query.isRawSql()) {
query.setDefaultRawSqlIfRequired();
if (query.isAutoTunable() && !autoTuneService.tuneQuery(query)) {
// use deployment FetchType.LAZY/EAGER annotations
// to define the 'default' select clause
query.setDefaultSelectClause();
}
query.selectAllForLazyLoadProperty();
}
query.selectAllForLazyLoadProperty();
ProfileLocation profileLocation = query.getProfileLocation();
if (profileLocation != null) {
profileLocation.obtain();
@@ -2180,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);
@@ -2208,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;
}
@@ -19,7 +19,7 @@ final class DefaultSlowQueryListener implements SlowQueryListener {
String firstStack = "";
ObjectGraphNode node = event.getOriginNode();
if (node != null) {
firstStack = node.getOriginQueryPoint().getTopElement();
firstStack = node.origin().top();
}
log.log(WARNING, "Slow query warning - millis:{0} rows:{1} caller[{2}] sql[{3}]", event.getTimeMillis(), event.getRowCount(), firstStack, event.getSql());
}
@@ -40,7 +40,7 @@ public final class DiffHelp {
}
}
if (oldBean == null) {
return ((EntityBean) newBean)._ebean_getIntercept().getDirtyValues();
return ((EntityBean) newBean)._ebean_getIntercept().dirtyValues();
}
return desc.diff((EntityBean) newBean, (EntityBean) oldBean);
}
@@ -127,7 +127,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
* iteration is fine.
*/
public int secondaryQueriesMinBatchSize() {
return loadContext.getSecondaryQueriesMinBatchSize();
return loadContext.secondaryQueriesMinBatchSize();
}
/**
@@ -529,7 +529,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
OrderBy<T> orderBy = query.getOrderBy();
if (orderBy != null && !orderBy.isEmpty()) {
// in memory sort after merging the cache hits with the DB hits
beanDescriptor.sort(((BeanList<T>) result).getActualList(), orderBy.toStringFormat());
beanDescriptor.sort(((BeanList<T>) result).actualList(), orderBy.toStringFormat());
}
}
}
@@ -646,7 +646,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
if (cached != null && isAuditReads() && readAuditQueryType()) {
if (cached instanceof BeanCollection) {
// raw sql can't use L2 cache so normal queries only in here
Collection<T> actualDetails = ((BeanCollection<T>) cached).getActualDetails();
Collection<T> actualDetails = ((BeanCollection<T>) cached).actualDetails();
List<Object> ids = new ArrayList<>(actualDetails.size());
for (T bean : actualDetails) {
ids.add(beanDescriptor.idForJson(bean));
@@ -657,7 +657,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
if (Boolean.FALSE.equals(query.isReadOnly())) {
// return shallow copies if readonly is explicitly set to false
if (cached instanceof BeanCollection) {
cached = ((BeanCollection<?>) cached).getShallowCopy();
cached = ((BeanCollection<?>) cached).shallowCopy();
} else if (cached instanceof List) {
cached = new CopyOnFirstWriteList<>((List<?>) cached);
} else if (cached instanceof Set) {
@@ -281,7 +281,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
private void onFailedUpdateUndoGeneratedProperties() {
for (BeanProperty prop : beanDescriptor.propertiesGenUpdate()) {
Object oldVal = intercept.getOrigValue(prop.propertyIndex());
Object oldVal = intercept.origValue(prop.propertyIndex());
prop.setValue(entityBean, oldVal);
}
}
@@ -372,12 +372,12 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
@Override
public Set<String> loadedProperties() {
return intercept.getLoadedPropertyNames();
return intercept.loadedPropertyNames();
}
@Override
public Set<String> updatedProperties() {
return intercept.getDirtyPropertyNames();
return intercept.dirtyPropertyNames();
}
/**
@@ -410,7 +410,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
@Override
public Map<String, ValuePair> updatedValues() {
return intercept.getDirtyValues();
return intercept.dirtyValues();
}
/**
@@ -713,7 +713,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
* Return the original / old value for the given property.
*/
public Object getOrigValue(BeanProperty prop) {
return intercept.getOrigValue(prop.propertyIndex());
return intercept.origValue(prop.propertyIndex());
}
@Override
@@ -867,7 +867,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
boolean isChangeLog = beanDescriptor.isChangeLog();
if (type == Type.UPDATE && (isChangeLog || notifyCache || docStoreMode == DocStoreMode.UPDATE)) {
// get the dirty properties for update notification to the doc store
dirtyProperties = intercept.getDirtyProperties();
dirtyProperties = intercept.dirtyProperties();
}
if (isChangeLog) {
changeLog();
@@ -1142,9 +1142,9 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
public String updatePlanHash() {
StringBuilder key;
if (determineUpdateAllLoadedProperties()) {
key = intercept.getLoadedPropertyKey();
key = intercept.loadedPropertyKey();
} else {
key = intercept.getDirtyPropertyKey();
key = intercept.dirtyPropertyKey();
}
BeanProperty versionProperty = beanDescriptor.versionProperty();
if (versionProperty != null) {
@@ -1237,7 +1237,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
public void docStorePersist() {
idValue = beanDescriptor.getId(entityBean);
if (type == Type.UPDATE) {
dirtyProperties = intercept.getDirtyProperties();
dirtyProperties = intercept.dirtyProperties();
}
// processing now so set IGNORE (unlike DB + DocStore processing with post-commit)
docStoreMode = DocStoreMode.IGNORE;
@@ -22,6 +22,7 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import static java.lang.System.Logger.Level.DEBUG;
@@ -79,9 +80,9 @@ public class BootupClasses implements Predicate<Class<?>> {
public BootupClasses() {
}
public BootupClasses(List<Class<?>> list) {
if (list != null) {
for (Class<?> cls : list) {
public BootupClasses(Set<Class<?>> classes) {
if (classes != null) {
for (Class<?> cls : classes) {
test(cls);
}
}
@@ -45,7 +45,7 @@ abstract class BaseCollectionHelp<T> implements BeanCollectionHelp<T> {
@Override
public final Collection underlying(Object value) {
if (value instanceof BeanCollection) {
return ((BeanCollection)value).getActualDetails();
return ((BeanCollection)value).actualDetails();
} else {
return (Collection)value;
}
@@ -36,7 +36,7 @@ public final class BeanCollectionUtil {
}
// For maps this is a collection of Map.Entry, otherwise it
// returns a collection of beans
return bc.getActualEntries();
return bc.actualEntries();
}
if (o instanceof Collection<?>) {
return ((Collection<?>) o);
@@ -61,7 +61,7 @@ public final class BeanCollectionUtil {
}
// For maps this is a collection of Map.Entry, otherwise it
// returns a collection of beans
return bc.getActualDetails();
return bc.actualDetails();
}
if (o instanceof Map<?, ?>) {
// yes, we want the entrySet (to set the keys)
@@ -29,6 +29,7 @@ import io.ebeaninternal.api.*;
import io.ebeaninternal.api.TransactionEventTable.TableIUD;
import io.ebeaninternal.api.json.SpiJsonReader;
import io.ebeaninternal.api.json.SpiJsonWriter;
import io.ebeaninternal.server.bind.DataBind;
import io.ebeaninternal.server.cache.CacheChangeSet;
import io.ebeaninternal.server.cache.CachedBeanData;
import io.ebeaninternal.server.cache.CachedManyIds;
@@ -45,7 +46,6 @@ import io.ebeaninternal.server.querydefn.DefaultOrmQuery;
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
import io.ebeaninternal.server.querydefn.OrmQueryProperties;
import io.ebeaninternal.server.rawsql.SpiRawSql;
import io.ebeaninternal.server.bind.DataBind;
import io.ebeaninternal.util.SortByClause;
import io.ebeaninternal.util.SortByClauseParser;
import io.ebeanservice.docstore.api.DocStoreBeanAdapter;
@@ -350,9 +350,9 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
this.idPropertyIndex = (idProperty == null) ? -1 : ebi.findProperty(idProperty.name());
this.versionPropertyIndex = (versionProperty == null) ? -1 : ebi.findProperty(versionProperty.name());
this.unloadProperties = derivePropertiesToUnload(prototypeEntityBean);
this.propertiesIndex = new BeanProperty[ebi.getPropertyLength()];
this.propertiesIndex = new BeanProperty[ebi.propertyLength()];
for (int i = 0; i < propertiesIndex.length; i++) {
propertiesIndex[i] = propMap.get(ebi.getProperty(i));
propertiesIndex[i] = propMap.get(ebi.property(i));
}
}
idSelect = initIdSelect();
@@ -400,7 +400,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
* These properties need to be unloaded when populating beans for queries.
*/
private int[] derivePropertiesToUnload(EntityBean prototypeEntityBean) {
boolean[] loaded = prototypeEntityBean._ebean_getIntercept().getLoaded();
boolean[] loaded = prototypeEntityBean._ebean_getIntercept().loaded();
int[] props = new int[loaded.length];
int pos = 0;
// collect the positions of the properties initialised in the default constructor.
@@ -711,7 +711,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
public void merge(EntityBean bean, EntityBean existing) {
EntityBeanIntercept fromEbi = bean._ebean_getIntercept();
EntityBeanIntercept toEbi = existing._ebean_getIntercept();
int propertyLength = toEbi.getPropertyLength();
int propertyLength = toEbi.propertyLength();
String[] names = properties();
for (int i = 0; i < propertyLength; i++) {
if (fromEbi.isLoadedProperty(i)) {
@@ -2217,12 +2217,12 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
}
public boolean lazyLoadMany(EntityBeanIntercept ebi, LoadBeanContext parent) {
int lazyLoadProperty = ebi.getLazyLoadPropertyIndex();
int lazyLoadProperty = ebi.lazyLoadPropertyIndex();
if (lazyLoadProperty == -1) {
return false;
}
if (inheritInfo != null) {
return descOf(ebi.getOwner().getClass()).lazyLoadMany(ebi, lazyLoadProperty, parent);
return descOf(ebi.owner().getClass()).lazyLoadMany(ebi, lazyLoadProperty, parent);
}
return lazyLoadMany(ebi, lazyLoadProperty, parent);
}
@@ -2241,7 +2241,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
BeanProperty lazyLoadBeanProp = propertiesIndex[lazyLoadProperty];
if (lazyLoadBeanProp instanceof BeanPropertyAssocMany<?>) {
BeanPropertyAssocMany<?> manyProp = (BeanPropertyAssocMany<?>) lazyLoadBeanProp;
final BeanCollection<?> collection = manyProp.createReference(ebi.getOwner());
final BeanCollection<?> collection = manyProp.createReference(ebi.owner());
ebi.setLoadedLazy();
if (loadBeanContext != null) {
loadBeanContext.register(manyProp, collection);
@@ -3076,7 +3076,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
// not using Id generator so just base on isLoaded()
return !ebi.isLoaded();
}
if (!hasIdValue(ebi.getOwner())) {
if (!hasIdValue(ebi.owner())) {
// No Id property means it must be an insert
return true;
}
@@ -3139,7 +3139,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
for (BeanProperty beanProperty : propertiesMutable) {
int propertyIndex = beanProperty.propertyIndex();
if (ebi.isLoadedProperty(propertyIndex)) {
Object value = beanProperty.getValue(ebi.getOwner());
Object value = beanProperty.getValue(ebi.owner());
if (beanProperty.checkMutable(value, ebi.isDirtyProperty(propertyIndex), ebi)) {
// mutable scalar value which is considered dirty so mark
// it as such so that it is included in an update
@@ -3156,7 +3156,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
for (BeanProperty beanProperty : propertiesMutable) {
int propertyIndex = beanProperty.propertyIndex();
if (ebi.isLoadedProperty(propertyIndex)) {
Object value = beanProperty.getValue(ebi.getOwner());
Object value = beanProperty.getValue(ebi.owner());
if (beanProperty.checkMutable(value, ebi.isDirtyProperty(propertyIndex), ebi)) {
ebi.markPropertyAsChanged(propertyIndex);
return;
@@ -271,9 +271,9 @@ final class BeanDescriptorCacheHelp<T> {
// not in cache so return unsuccessful
return false;
}
EntityBean ownerBean = bc.getOwnerBean();
EntityBean ownerBean = bc.owner();
EntityBeanIntercept ebi = ownerBean._ebean_getIntercept();
PersistenceContext persistenceContext = ebi.getPersistenceContext();
PersistenceContext persistenceContext = ebi.persistenceContext();
BeanDescriptor<?> targetDescriptor = many.targetDescriptor();
List<Object> idList = entry.getIdList();
@@ -696,7 +696,7 @@ final class BeanDescriptorCacheHelp<T> {
Set<EntityBeanIntercept> beanCacheLoadAll(Set<EntityBeanIntercept> batch, PersistenceContext context, int lazyLoadProperty, String propertyName) {
Map<Object, EntityBeanIntercept> ebis = new HashMap<>();
for (EntityBeanIntercept ebi : batch) {
ebis.put(desc.cacheKeyForBean(ebi.getOwner()), ebi);
ebis.put(desc.cacheKeyForBean(ebi.owner()), ebi);
}
Map<Object, Object> hits = getBeanCache().getAll(ebis.keySet());
@@ -715,7 +715,7 @@ final class BeanDescriptorCacheHelp<T> {
beanLog.log(TRACE, " load {0}({1}) - cache miss on property({2})", cacheName, key, propertyName);
}
} else {
CachedBeanDataToBean.load(desc, ebi.getOwner(), cacheData, context);
CachedBeanDataToBean.load(desc, ebi.owner(), cacheData, context);
loaded.add(ebi);
if (beanLog.isLoggable(DEBUG)) {
beanLog.log(DEBUG, " load {0}({1}) - hit", cacheName, key);
@@ -739,10 +739,10 @@ final class BeanDescriptorCacheHelp<T> {
}
return false;
}
int lazyLoadProperty = ebi.getLazyLoadPropertyIndex();
if (lazyLoadProperty > -1 && !cacheData.isLoaded(ebi.getLazyLoadProperty())) {
int lazyLoadProperty = ebi.lazyLoadPropertyIndex();
if (lazyLoadProperty > -1 && !cacheData.isLoaded(ebi.lazyLoadProperty())) {
if (beanLog.isLoggable(TRACE)) {
beanLog.log(TRACE, " LOAD {0}({1}) - cache miss on property({2})", cacheName, key, ebi.getLazyLoadProperty());
beanLog.log(TRACE, " LOAD {0}({1}) - cache miss on property({2})", cacheName, key, ebi.lazyLoadProperty());
}
return false;
}
@@ -133,7 +133,12 @@ final class BeanDescriptorJsonHelp<T> {
String key = parser.getCurrentName();
BeanProperty p = desc.beanProperty(key);
if (p != null) {
p.jsonRead(readJson, bean);
if (p.isVersion() && readJson.update() ) {
// skip version prop during update
p.jsonRead(readJson);
} else {
p.jsonRead(readJson, bean);
}
} else {
// read an unmapped property
if (unmappedProperties == 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);
@@ -932,7 +932,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
// define the TableJoin
DeployTableJoin oneToManyJoin = oneToMany.getTableJoin();
if (!oneToManyJoin.hasJoinColumns()) {
throw new RuntimeException("No join columns");
throw new RuntimeException("No join columns found to satisfy the relationship " + oneToMany);
}
createUnidirectional(targetDesc, owningType, beanTable, oneToManyJoin);
}
@@ -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;
}
@@ -31,7 +31,7 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
public final BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) {
if (bc instanceof BeanList<?>) {
BeanList<?> bl = (BeanList<?>) bc;
if (bl.getActualList() == null) {
if (bl.actualList() == null) {
bl.setActualList(new ArrayList<>());
}
return bl;
@@ -85,7 +85,7 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
} else if (currentList instanceof BeanList<?>) {
// normally this case, replace just the underlying list
BeanList<?> currentBeanList = (BeanList<?>) currentList;
currentBeanList.setActualList(newBeanList.getActualList());
currentBeanList.setActualList(newBeanList.actualList());
currentBeanList.setModifyListening(many.modifyListenMode());
} else {
@@ -108,7 +108,7 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
return;
}
}
list = beanList.getActualList();
list = beanList.actualList();
} else {
list = (List<?>) collection;
}
@@ -44,7 +44,7 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
BeanProperty beanProp = targetDescriptor.beanProperty(mapKey);
if (bc instanceof BeanMap<?, ?>) {
BeanMap<Object, Object> bm = (BeanMap<Object, Object>) bc;
Map<Object, Object> actualMap = bm.getActualMap();
Map<Object, Object> actualMap = bm.actualMap();
if (actualMap == null) {
actualMap = new LinkedHashMap<>();
bm.setActualMap(actualMap);
@@ -132,7 +132,7 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
} else if (current instanceof BeanMap<?, ?>) {
// normally this case, replace just the underlying list
BeanMap<?, ?> currentBeanMap = (BeanMap<?, ?>) current;
currentBeanMap.setActualMap(newBeanMap.getActualMap());
currentBeanMap.setActualMap(newBeanMap.actualMap());
currentBeanMap.setModifyListening(many.modifyListenMode());
} else {
@@ -155,7 +155,7 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
return;
}
}
map = bc.getActualMap();
map = bc.actualMap();
} else {
map = (Map<?, ?>) collection;
}
@@ -20,9 +20,9 @@ import io.ebeaninternal.api.SpiExpressionRequest;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.api.json.SpiJsonReader;
import io.ebeaninternal.api.json.SpiJsonWriter;
import io.ebeaninternal.server.bind.DataBind;
import io.ebeaninternal.server.core.EncryptAlias;
import io.ebeaninternal.server.core.InternString;
import io.ebeaninternal.server.bind.DataBind;
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty;
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedWhenCreated;
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedWhenModified;
@@ -700,7 +700,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
* Return the bean cache value for this property using original values.
*/
public Object getCacheDataValueOrig(EntityBeanIntercept ebi) {
return cacheDataConvert(ebi.getOrigValue(propertyIndex));
return cacheDataConvert(ebi.origValue(propertyIndex));
}
private Object cacheDataConvert(Object value) {
@@ -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);
}
/**
@@ -1408,15 +1408,20 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
}
public void jsonRead(SpiJsonReader ctx, EntityBean bean) throws IOException {
Object objValue = jsonRead(ctx);
if (jsonDeserialize) {
if (ctx.update()) {
setValueIntercept(bean, objValue);
} else {
setValue(bean, objValue);
}
}
}
public Object jsonRead(SpiJsonReader ctx) throws IOException {
JsonToken event = ctx.nextToken();
if (JsonToken.VALUE_NULL == event) {
if (jsonDeserialize) {
if (ctx.intercept()) {
setValueIntercept(bean, null);
} else {
setValue(bean, null);
}
}
return null;
} else {
// expect to read non-null json value
Object objValue;
@@ -1433,13 +1438,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty {
CoreLog.log.log(ERROR, msg, e);
}
}
if (jsonDeserialize) {
if (ctx.intercept()) {
setValueIntercept(bean, objValue);
} else {
setValue(bean, objValue);
}
}
return objValue;
}
}
@@ -2,6 +2,8 @@ package io.ebeaninternal.server.deploy;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.ebean.SqlUpdate;
import io.ebean.Transaction;
import io.ebean.bean.BeanCollection;
@@ -27,6 +29,7 @@ import java.io.StringWriter;
import java.util.*;
import static java.lang.System.Logger.Level.ERROR;
import static java.lang.System.Logger.Level.WARNING;
/**
* Property mapped to a List Set or Map.
@@ -200,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));
}
/**
@@ -208,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()) {
@@ -413,8 +416,8 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
public String assocIsEmpty(SpiExpressionRequest request, String path) {
boolean softDelete = targetDescriptor.isSoftDelete();
boolean needsX2Table = softDelete || extraWhere() != null;
StringBuilder sb = new StringBuilder(50);
SpiQuery<?> query = request.getQueryRequest().query();
StringBuilder sb = new StringBuilder(50).append("from "); // use from to stop parsing on table name
SpiQuery<?> query = request.queryRequest().query();
if (hasJoinTable()) {
sb.append(query.isAsDraft() ? intersectionDraftTable : intersectionPublishTable);
} else {
@@ -872,7 +875,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
// publish from each draft to live bean creating new live beans as required
draftVal.size();
Collection<T> actualDetails = draftVal.getActualDetails();
Collection<T> actualDetails = draftVal.actualDetails();
for (T bean : actualDetails) {
Object id = targetDescriptor.id(bean);
T liveBean = liveBeansAsMap.remove(id);
@@ -901,7 +904,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
@SuppressWarnings("unchecked")
private Map<Object, T> liveBeansAsMap(BeanCollection<?> liveVal) {
liveVal.size();
Collection<?> liveBeans = liveVal.getActualDetails();
Collection<?> liveBeans = liveVal.actualDetails();
Map<Object, T> liveMap = new LinkedHashMap<>();
for (Object liveBean : liveBeans) {
Object id = targetDescriptor.id(liveBean);
@@ -937,7 +940,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
if (elementDescriptor != null) {
elementDescriptor.jsonWriteMapEntry(ctx, entry);
} else {
targetDescriptor.jsonWrite(ctx, (EntityBean)entry.getValue());
targetDescriptor.jsonWrite(ctx, (EntityBean) entry.getValue());
}
}
@@ -1003,7 +1006,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
if (JsonToken.VALUE_NULL == event) {
return null;
}
return jsonReadCollection(ctx, null);
return jsonReadCollection(ctx, null, null);
}
/**
@@ -1016,15 +1019,16 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
/**
* Read the collection (JSON Array) containing entity beans.
*/
public Object jsonReadCollection(SpiJsonReader readJson, EntityBean parentBean) throws IOException {
public Object jsonReadCollection(SpiJsonReader readJson, EntityBean parentBean, Object targets) throws IOException {
if (elementDescriptor != null && elementDescriptor.isJsonReadCollection()) {
return elementDescriptor.jsonReadCollection(readJson, parentBean);
}
BeanCollection<?> collection = createEmpty(parentBean);
BeanCollectionAdd add = beanCollectionAdd(collection);
Map<Object, T> existingBeans = extractBeans(targets);
do {
// CHECKME: Update existing list entry here?
EntityBean detailBean = (EntityBean) targetDescriptor.jsonRead(readJson, name, null);
EntityBean detailBean = getDetailBean(readJson, existingBeans);
if (detailBean == null) {
// read the entire array
break;
@@ -1039,6 +1043,63 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
return collection;
}
/**
* Find bean in the target collection and reuse it for JSON update.
*/
private EntityBean getDetailBean(SpiJsonReader readJson, Map<Object, T> targets) throws IOException {
BeanProperty idProperty = targetDescriptor.idProperty();
if (targets == null || idProperty == null) {
return (EntityBean) targetDescriptor.jsonRead(readJson, name, null);
} else {
JsonToken token = readJson.parser().nextToken();
if (JsonToken.VALUE_NULL == token || JsonToken.END_ARRAY == token) {
return null;
}
// extract the id. We have to buffer the JSON;
ObjectNode node = readJson.mapper().readTree(readJson.parser());
SpiJsonReader jsonReader = readJson.forJson(node.traverse());
JsonNode idNode = node.get(idProperty.name());
Object id = idNode == null ? null : idProperty.jsonRead(readJson.forJson(idNode.traverse()));
return (EntityBean) targetDescriptor.jsonRead(jsonReader, name, targets.get(id));
}
}
/**
* Extract beans, that are currently in the target collection. (targets can be a List/Set/Map)
*/
private Map<Object, T> extractBeans(Object targets) {
Collection<T> beans;
if (targets == null) {
return null;
} else if (targets instanceof Map) {
if (((Map<?, T>) targets).isEmpty()) {
return null;
}
beans = ((Map<?, T>) targets).values();
} else if (targets instanceof Collection) {
if (((Collection<?>) targets).isEmpty()) {
return null;
}
beans = (Collection<T>) targets;
} else {
CoreLog.log.log(WARNING, "Found non collection value " + targets.getClass().getSimpleName());
return null;
}
BeanProperty idProp = targetDescriptor.idProperty();
Map<Object, T> ret = new HashMap<>();
for (T bean : beans) {
if (bean instanceof EntityBean) {
Object id = idProp.getValue((EntityBean) bean);
if (id != null) {
ret.put(id, bean);
}
}
}
return ret.isEmpty() ? null : ret;
}
/**
* Bind all the property values to the SqlUpdate.
*/
@@ -50,10 +50,10 @@ class BeanPropertyAssocManyJsonHelp {
if (JsonToken.START_ARRAY != event && JsonToken.START_OBJECT != event) {
throw new JsonParseException(parser, "Unexpected token " + event + " - expecting start array or object");
}
if (readJson.intercept()) {
many.setValueIntercept(parentBean, many.jsonReadCollection(readJson, parentBean));
if (readJson.update()) {
many.setValueIntercept(parentBean, many.jsonReadCollection(readJson, parentBean, many.getValue(parentBean)));
} else {
many.setValue(parentBean, many.jsonReadCollection(readJson, parentBean));
many.setValue(parentBean, many.jsonReadCollection(readJson, parentBean, null));
}
}

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