Compare commits

...
Author SHA1 Message Date
Rob Bygrave bac7eb11bd [maven-release-plugin] prepare release ebean-parent-13.6.0 2022-05-03 15:13:13 +12:00
Rob Bygrave a8c2e4db3f Our release profile is now called "central" 2022-05-03 15:09:34 +12:00
Rob Bygrave 67a4e66b00 [maven-release-plugin] rollback the release of ebean-parent-13.6.0 2022-05-03 15:07:55 +12:00
Rob Bygrave 0d1d212f9f [maven-release-plugin] prepare for next development iteration 2022-05-03 14:59:36 +12:00
Rob Bygrave f44c77f5f5 [maven-release-plugin] prepare release ebean-parent-13.6.0 2022-05-03 14:59:29 +12:00
Rob Bygrave 65d07f4af9 Merge branch 'master' of github.com:ebean-orm/ebean 2022-05-03 14:48:52 +12:00
Rob Bygrave c74de4c221 Bump ebean-agent to 13.6.0 2022-05-03 14:48:38 +12:00
Rob BygraveandGitHub ebbef86def Merge pull request #2626 from ebean-orm/wip/EntityBeanIntercept-interface
Support EntityBeanIntercept as an interface with InterceptReadWrite and InterceptReadOnly options
2022-05-03 14:15:49 +12:00
Rob Bygrave 3fab465a13 #2649 - Bump avaje-config to 2.0 (uses System.Logger and not slf4j-api) 2022-05-03 13:50:22 +12:00
Rob BygraveandGitHub ff662bff58 Merge pull request #2683 from ebean-orm/feature/bump-datasource
Bump ebean-datasource to 8.0 with use of System.Logger (from slf4j-api)
2022-05-03 13:46:18 +12:00
Rob Bygrave cc7acd4761 Bump ebean-datasource to 8.0 with use of System.Logger (from slf4j-api) 2022-05-03 13:45:35 +12:00
Rob BygraveandGitHub 1365e39e94 Merge pull request #2681 from ebean-orm/feature/2647
#2647 - When Postgres + isAllQuotedIdentifiers true + using DataSourceConfig THEN `datasourceConfig.addProperty("quoteReturningIdentifiers", false);`
2022-05-03 13:38:10 +12:00
Rob BygraveandGitHub a73eb1c42f Merge pull request #2648 from ebean-orm/feature/bump-classpathscanner
Bump avaje classpath scanner to 7.1, ignores module-info, uses System.Logger (not slf4j-api)
2022-05-03 13:36:39 +12:00
Rob BygraveandGitHub 3f5a610df1 Merge pull request #2650 from ebean-orm/feature/bump-ddlrunner
Bump ebean-ddl-runner (sync version with ebean-migration)
2022-05-03 13:36:29 +12:00
Rob BygraveandGitHub d96e28991c Merge pull request #2682 from ebean-orm/feature/ebean-migration-system-logger
Bump ebean-migration to 13.6.0 (bumps classpath scanner and ebean-ddl-runner)
2022-05-03 13:36:16 +12:00
Rob Bygrave e84d12dad8 Bump ebean-migration to 13.6.0 (bumps classpath scanner and ebean-ddl-runner) 2022-05-03 13:30:09 +12:00
Rob Bygrave 1d4f2ad856 #2626 - Add final modifier to methods - For readOnly disableLazyLoad using Collections.EMPTY_LIST etc 2022-05-03 12:23:22 +12:00
Rob Bygrave 84042397b6 #2626 - For readOnly disableLazyLoad using Collections.EMPTY_LIST etc for reference collections 2022-05-03 12:12:47 +12:00
Rob Bygrave a70461d779 Update InterceptReadWrite with file content diff detection 2022-05-03 10:46:22 +12:00
Rob Bygrave d1b5400f2c Merge branch 'master' into wip/EntityBeanIntercept-interface 2022-05-03 10:45:45 +12:00
Rob Bygrave 244f336f54 #2647 - When Postgres + isAllQuotedIdentifiers true + using DataSourceConfig THEN datasourceConfig.addProperty("quoteReturningIdentifiers", false);
I think there is not a case where we do NOT want to do this. allQuotedIdentifiers + Postgres is almost not usable without this.
2022-05-03 10:15:07 +12:00
Rob Bygrave f92887b2f0 #2680 - Bump parent to java11-oss 3.8 which moves nexus-staging-maven-plugin and distributionManagement under "central" profile
This means that the nexus-staging-maven-plugin should not be used for forks looking to deploy into their own local nexus/archiva maven repo.
2022-05-03 09:06:27 +12:00
Rob Bygrave f49b93a845 Bump to 13.6.0-SNAPSHOT 2022-05-03 08:55:50 +12:00
Rob Bygrave a6f3a4f922 Bump to 13.6.0-SNAPSHOT 2022-05-03 08:37:29 +12:00
Rob Bygrave d6a65e4e66 Bump to 13.6.0-SNAPSHOT 2022-05-02 22:31:32 +12:00
Rob BygraveandGitHub ea5b4e9271 Merge pull request #2662 from ebean-orm/feature/deprecated-remove-Ebean
Remove deprecated Ebean, EbeanServer, EbeanServerFactory, ServerConfig migrate to DB, Database, DatabaseFactory, DatabaseConfig
2022-05-02 22:27:57 +12:00
Rob BygraveandGitHub ffa50b3176 Merge pull request #2679 from ebean-orm/feature/2677
#2677 - Fix for trim failing on mutation of lastAccessTime
2022-05-02 22:25:13 +12:00
Rob Bygrave 2cf83278ea #2677 - Change trimOnPut to be 10% of max or 1_000.
Can look to provide an explicit option via `@CacheBeanTuning` later.
2022-05-02 22:19:37 +12:00
Rob Bygrave 5c332286b6 #2677 - Add ReentrantLock for DefaultServerCache.runEviction() and trigger runEviction() via mutationCounter
If we get a lot of cache mutation (puts) between background trims then also trigger runEviction() in foreground using mutationCounter.
2022-05-02 21:48:58 +12:00
Rob Bygrave 1cd319c495 #2677 - Add try catch around DefaultServerCache.runEviction()
If there is an unexpected error we expect it to be temporary and want runEviction() to keep executing.
2022-05-02 20:51:33 +12:00
Rob BygraveandGitHub cec8a2e482 Merge pull request #2678 from focbenz/patch-1
Fixed typo Junit -> JUnit in README
2022-05-02 20:33:01 +12:00
Rob Bygrave d036edf7fd #2677 - Fix for trim failing on mutation of lastAccessTime
Currently, lastAccessTime can mutate during cache trim processing. This fixes this issue by taking a copy of the lastAccessTime storing as lastAccessSort and using that for sorting for cache trim.
2022-05-02 20:31:10 +12:00
Michael BenzandGitHub 2fefb5c7ef Merge branch 'ebean-orm:master' into patch-1 2022-05-02 10:10:34 +02:00
Michael BenzandGitHub 4278aa46f5 Junit -> JUnit
Just one more change ... verified in Intellij:
Junit -> JUnit
2022-05-02 10:08:46 +02:00
Rob BygraveandGitHub 7873a2b327 Merge pull request #2676 from focbenz/patch-1
Fix grammar in README.md
2022-05-02 20:08:04 +12:00
Rob BygraveandGitHub 9d3a3ddfeb Merge pull request #2675 from ebean-orm/feature/DefaultOrmQuery-final
Modify DefaultOrmQuery to have non-final copy() methods to allow ebean-mocker to be updated
2022-05-02 20:07:40 +12:00
Michael BenzandGitHub ac0b9aa025 Fix grammar in README.md
Just some grammatical fixes and uppercasings in README. No code changes here!
2022-05-02 08:40:34 +02:00
Rob Bygrave 4d4f8e2c4b Modify DefaultOrmQuery to have non-final copy() methods to allow ebean-mocker to be updated 2022-05-02 18:01:25 +12:00
Rob Bygrave 2b581fb148 Update README with details on building ebean from source 2022-05-02 16:36:59 +12:00
Rob BygraveandGitHub 35bd98c14f Merge pull request #2674 from ebean-orm/feature/ebean-test-container-5
Bump to ebean-test-docker 5.0-RC1
2022-05-02 16:36:02 +12:00
Rob Bygrave 8db9991ea3 Bump to ebean-test-docker 5.0 2022-05-02 16:04:42 +12:00
Rob Bygrave fac69f75d0 Bump to ebean-test-docker 5.0-RC2 2022-05-02 15:40:01 +12:00
Rob Bygrave b18226711b Bump to ebean-test-docker 5.0-RC1 2022-04-29 16:43:48 +12:00
Rob Bygrave 4bdb48d340 Bump to 13.5.1-SNAPSHOT after release 2022-04-28 17:58:58 +12:00
Rob Bygrave d2a742fefb [maven-release-plugin] prepare for next development iteration 2022-04-28 17:42:12 +12:00
Rob Bygrave 22de23ddf4 [maven-release-plugin] prepare release ebean-parent-13.5.0 2022-04-28 17:42:05 +12:00
Rob Bygrave 496d9674d2 #2672 - Bump ebean-agent to 13.5.0 for - ToStringBuilder enhancement does not use toString() of the abstract class 2022-04-28 10:50:34 +12:00
Rob Bygrave 4ece9fe6cc Bump to 13.5.0-SNAPSHOT 2022-04-28 10:46:14 +12:00
Rob Bygrave 62f162e4fb Bump to 13.5.0-SNAPSHOT 2022-04-28 10:44:56 +12:00
Rob Bygrave 38803aa7f8 Bump to 13.5.0-SNAPSHOT 2022-04-28 10:33:41 +12:00
Rob Bygrave f9943f14b7 Adjust test ebean.properties 2022-04-28 10:32:27 +12:00
Rob Bygrave 1b24c888ee Put back test jdbc driver for MariaDB ... need to look at changes in newer driver wrt forwardOnlyHintOnFindIterate
That is, forwardOnlyHintOnFindIterate is a hack to support poor MySql jdbc driver behavior but maybe we can remove this
hack in later versions of MariaDB at least
2022-04-27 23:13:28 +12:00
Rob Bygrave 45233e96ab #2673 - Bug introduced in 13.3.1 via #2652 - incorrect binding of history query with SQL2011 standards based queries 2022-04-27 22:48:02 +12:00
Rob Bygrave 517556bfe3 For sql server tests add jdbc parameters ;integratedSecurity=false;trustServerCertificate=true 2022-04-27 20:02:02 +12:00
Rob Bygrave 07101d1528 #2671 - Bump ebean-test-docker to 4.7 2022-04-27 19:53:52 +12:00
Rob Bygrave 9fa1def22b Bump test jdbc drivers 2022-04-27 18:43:27 +12:00
Rob Bygrave dd9d49cfa2 #2671 - Bump ebean-test-docker to 4.7 2022-04-27 18:39:49 +12:00
Rob Bygrave 7680a75ca9 Bump test modules to 13.4.2-SNAPSHOT after release 2022-04-27 09:48:13 +12:00
Rob Bygrave 786286421d [maven-release-plugin] prepare for next development iteration 2022-04-27 09:13:48 +12:00
Rob Bygrave b517551352 [maven-release-plugin] prepare release ebean-parent-13.4.1 2022-04-27 09:13:41 +12:00
Rob Bygrave 507ba7da1c Bump ebean-agent to 13.4.1 2022-04-27 09:09:48 +12:00
Rob Bygrave 835796f614 #2670 - Missing implementation of loadIgnore in ScalarTypePgisBase 2022-04-27 08:43:06 +12:00
Rob Bygrave ab9a6fb69a git push origin masterMerge branch 'FOCONIS-toString-with-map' 2022-04-27 08:35:38 +12:00
Jonas PöhlerandNoemi Szemenyei 4d7a3d135c FIX: StackOverflowError when using recursive relation within Map
(cherry picked from commit d06bc13b4e1e421546f4997900d5fdc6aa980257)
2022-04-26 13:53:51 +02:00
Rob Bygrave 937b15c07a Modify EA builds to use EA,GA rather than specific versions 2022-04-26 09:30:20 +12:00
Rob Bygrave 47cf81fef9 Bump test modules to 13.4.0-SNAPSHOT after release 2022-04-21 13:47:29 +12:00
Rob Bygrave b21123343f [maven-release-plugin] prepare for next development iteration 2022-04-21 13:30:00 +12:00
Rob Bygrave 303f63fe5e [maven-release-plugin] prepare release ebean-parent-13.4.0 2022-04-21 13:29:54 +12:00
Rob Bygrave 59d12c908c Bump ebean-agent to 13.4.0 (no effective change) 2022-04-21 10:38:39 +12:00
Rob Bygrave e736263148 Bump to 13.4.0-SNAPSHOT 2022-04-21 10:36:08 +12:00
Rob Bygrave 72712c0e46 Bump to 13.4.0-SNAPSHOT 2022-04-21 10:29:58 +12:00
Rob Bygrave 5245ef597d Bump to 13.4.0-SNAPSHOT 2022-04-21 10:28:01 +12:00
Rob Bygrave 9d2621d353 #2667 - Bump jedis dependency to 4.2.2 from 4.2.1 2022-04-21 10:20:51 +12:00
Rob BygraveandGitHub 015ef0289f Merge pull request #2666 from ebean-orm/feature/discriminatorString-compareTo
Fix: CompareTo when discriminatorString is null
2022-04-21 09:56:22 +12:00
Rob Bygrave 5b9ca2933f Fix: CompareTo when discriminatorString is null
- Fix for regression introduced by #2646 in version  13.3.1
- Replaces PR #2664
2022-04-21 09:53:06 +12:00
Rob BygraveandGitHub 4ba23ebc22 Merge pull request #2665 from ebean-orm/feature/NodeUsageCollector-Cleaner
NodeUsageCollector migrate from using finalize() to Cleaner
2022-04-21 09:05:30 +12:00
Rob Bygrave cacbee5fd5 Refactor tidy NodeUsageCollector, remove unused loadProperty and unnecessary WeakReference for State.listener 2022-04-21 08:59:53 +12:00
Rob Bygrave e1b9bf62a3 NodeUsageCollector migrate from using finalize() to Cleaner 2022-04-21 08:40:00 +12:00
Rob Bygrave 4d21fbfcf8 #2663 - No effective change - Tidy Query interface with default methods 2022-04-20 21:49:06 +12:00
Rob Bygrave 76b02ff56a Tidy internals, use cls.getDeclaredConstructor().newInstance(); 2022-04-20 21:42:09 +12:00
Rob Bygrave 356af08f68 Tidy internal MTable only for test only constructor (remove @Deprecated) 2022-04-20 21:22:23 +12:00
Rob Bygrave 846afba724 Remove incorrect @Deprecated from internal DefaultOrmQuery 2022-04-20 21:14:44 +12:00
Rob Bygrave d34da06840 Remove deprecated Ebean, EbeanServer, EbeanServerFactory, ServerConfig migrate to DB, Database, DatabaseFactory, DatabaseConfig 2022-04-20 20:46:53 +12:00
Rob Bygrave 50e13c4c99 Tidy imports only on DeleteIdRequest 2022-04-20 18:50:47 +12:00
Rob BygraveandGitHub 30ec3145ed Merge pull request #2661 from ebean-orm/feature/deprecated-BackgroundExecutor
Remove deprecated methods from BackgroundExecutor, migrate executePeriodically() -> scheduleWithFixedDelay()
2022-04-20 18:35:37 +12:00
Rob Bygrave e20a2269ae Remove deprecated methods from BackgroundExecutor, migrate executePeriodically() -> scheduleWithFixedDelay()
All removed methods are renamed. Migrate to use the renamed method.
2022-04-20 18:34:33 +12:00
Rob Bygrave d6ee67cf4e Remove deprecated methods from BeanPersistRequest, BeanQueryRequest, BeanDeleteIdRequest
All removed methods are renamed. Migrate to use the renamed method.
2022-04-20 18:29:55 +12:00
Rob BygraveandGitHub 3bcb891133 Merge pull request #2660 from ebean-orm/feature/deprecated-event-requests
Remove deprecated methods from BeanPersistRequest, BeanQueryRequest, BeanDeleteIdRequest
2022-04-20 18:27:17 +12:00
Rob Bygrave a270caf605 Remove deprecated methods from BeanPersistRequest, BeanQueryRequest, BeanDeleteIdRequest
All removed methods are renamed. Migrate to use the renamed method.
2022-04-20 18:26:34 +12:00
Rob BygraveandGitHub aaade167e1 Merge pull request #2659 from ebean-orm/feature/deprecated-Transaction
Remove deprecated methods from Transaction, migrate setBatchGetGeneratedKeys() -> setGetGeneratedKeys() etc
2022-04-20 18:16:56 +12:00
Rob Bygrave ffb292dcd5 Remove deprecated methods from Transaction, migrate setBatchGetGeneratedKeys() -> setGetGeneratedKeys() etc
All removed methods are renamed. Migrate to use the renamed method.
2022-04-20 18:15:40 +12:00
Rob BygraveandGitHub 2e799be9e3 Merge pull request #2658 from ebean-orm/feature/deprecated-SpiServer
Remove deprecated methods from SpiServer, migrate getServerConfig() -> config() etc
2022-04-20 18:09:00 +12:00
Rob BygraveandGitHub 3863fa5fc6 Merge pull request #2657 from ebean-orm/feature/deprecated-FetchConfig
Remove deprecated methods from FetchConfig, migrate new FetchConfig().query(50) -> FetchConfig.ofQuery(50)
2022-04-20 18:08:38 +12:00
Rob Bygrave 2490562918 Remove deprecated methods from SpiServer, migrate getServerConfig() -> config() etc
All removed methods are renamed. Migrate to use the renamed method.
2022-04-20 18:07:16 +12:00
Rob BygraveandGitHub d6fe60bb33 Merge pull request #2656 from ebean-orm/feature/deprecated-pairs
Remove deprecated methods from Pairs, migrate setConcatSeparator() -> concatSeparator()
2022-04-20 18:03:22 +12:00
Rob Bygrave a4fc61549f Remove deprecated methods from FetchConfig, migrate new FetchConfig().query(50) -> FetchConfig.ofQuery(50) 2022-04-20 18:02:10 +12:00
Rob Bygrave 354b76e698 Remove deprecated methods from Pairs, migrate setConcatSeparator() -> concatSeparator() 2022-04-20 17:49:02 +12:00
Rob Bygrave f01e60094f #2655 - Remove JndiDataSourceLookup - app perform JNDI lookup if needed 2022-04-20 17:45:25 +12:00
Rob Bygrave 956ebf173e Bump test modules to 13.3.2-SNAPSHOT after release 2022-04-20 12:34:23 +12:00
Rob Bygrave c4eece36d3 [maven-release-plugin] prepare for next development iteration 2022-04-20 12:09:16 +12:00
Rob Bygrave 385867b9f5 [maven-release-plugin] prepare release ebean-parent-13.3.1 2022-04-20 12:09:09 +12:00
Rob Bygrave 4b30c51ff4 Bump ebean-agent 2022-04-20 12:05:14 +12:00
Rob Bygrave 0969e1427b ebean-api module-info, requires static jackson databind (as optional) 2022-04-20 11:01:10 +12:00
Rob Bygrave b2349bb044 Fix test InitDataSourceTest to use public API 2022-04-20 10:50:39 +12:00
Rob Bygrave c766756efe Improve test TestHistoryOneToOne 2022-04-20 10:02:11 +12:00
Rob BygraveandGitHub 0e6c6965f0 Merge pull request #2654 from FOCONIS/file-dirty-detection
Fix: Setting file with same content should not make bean dirty
2022-04-19 22:30:15 +12:00
Rob Bygrave 7a17cd0797 Tidy DefaultDbSqlContext, remove excess space from sql left join, tidy whitespace 2022-04-19 15:44:08 +12:00
Rob Bygrave 56acac9f08 git push origin masterMerge branch 'tobias--failing_parameter' 2022-04-19 15:03:11 +12:00
Rob Bygrave 756e3e4a1c #2651 - @OneToOne with @History, add fix and update tests
Effectively Ebean internally needs to keep a count on the number of times AS OF predicates are added (to joins + top level table). This change moves keeping that count for all joins to DbSqlContext.
2022-04-19 15:02:50 +12:00
Roland Praml 669d004d1b Fix: Setting file with same content should not make bean dirty
(cherry picked from commit 62c4acd36a)
2022-04-14 15:12:45 +02:00
Tobias 67fc7cdb48 Test case for lazy @OneToOne beans with @History
Ebean produces an invalid query when trying to lazy load @OneToOne
from a historical bean. This test asserts working behaviour.
2022-04-14 10:17:45 +02:00
Rob Bygrave 8432fa1320 Bump ebean-ddl-runner (sync version with ebean-migration) 2022-04-14 14:48:37 +12:00
Rob Bygrave 6b81dbbaa2 Bump avaje classpath scanner to 7.1, ignores module-info, uses System.Logger (not slf4j-api) 2022-04-14 12:40:49 +12:00
Rob BygraveandGitHub 9862526352 Merge branch 'master' into wip/EntityBeanIntercept-interface 2022-04-13 10:43:13 +12:00
Rob Bygrave 0e548ec1c5 Tidy test module poms 2022-04-13 10:40:55 +12:00
Rob BygraveandGitHub 493e2d7463 Merge pull request #2646 from FOCONIS/sort-inherit
Produce deterministic DDL if @Inheritance is used
2022-04-13 10:29:57 +12:00
Rob BygraveandGitHub ea30c1d43b Merge pull request #2645 from FOCONIS/sort-beancache
NPE executing query with beanCache and order by & clear
2022-04-13 10:23:28 +12:00
Roland Praml 8c800e992d Fix beanCache order by & clear did not work
(cherry picked from commit 4dee827fda)
2022-04-12 13:51:49 +02:00
Rob Bygrave d348794d92 Bump test modules to 13.3.1-SNAPSHOT after release 2022-04-12 21:47:00 +12:00
Rob Bygrave 526e476ba1 [maven-release-plugin] prepare for next development iteration 2022-04-12 21:23:12 +12:00
Rob Bygrave bdc936b63b [maven-release-plugin] prepare release ebean-parent-13.3.0 2022-04-12 21:23:05 +12:00
Rob BygraveandGitHub 45003b3d5f Merge branch 'master' into wip/EntityBeanIntercept-interface 2022-04-12 21:09:58 +12:00
Roland Praml 3179aa23ea Sort DeployInheritInfo, so that DDL is deterministic
(cherry picked from commit 6412e060e6)
2022-04-12 09:43:16 +02:00
Rob BygraveandGitHub 2aba1835f1 ebean-test - Fix AutoConfigureForTesting to skip configuration for non-default DatabaseConfig (#2644)
#2644 - ebean-test - Fix AutoConfigureForTesting to skip configuration for non-default DatabaseConfig
2022-04-12 17:36:25 +12:00
Rob Bygrave 4b8eadad1c Bump to 13.3.0-SNAPSHOT 2022-04-11 14:00:45 +12:00
Rob Bygrave 0a43b64f71 #2641 - Add a simple integration test for toString() implementation 2022-04-11 13:52:30 +12:00
Rob Bygrave 21c2232d96 #2641 - Bump ebean-agent for toString() implementation 2022-04-11 13:42:56 +12:00
Rob Bygrave 119b2d4638 #2643 - Bump dependencies h2database -> 2.1.212 ebean-test-docker -> 4.6 2022-04-11 12:50:46 +12:00
Rob BygraveandGitHub 5cc2685732 Merge pull request #2642 from ebean-orm/feature/2641-ToStringBuilder
#2641 -  Provide a decent default toString() implementation for entity beans
2022-04-11 12:49:02 +12:00
Rob Bygrave 6d6e417c94 #2641 - toString() - add tests for max beans and max content 2022-04-11 12:27:09 +12:00
Rob Bygrave be2466003d #2641 - toString() - addCollection() firstElement change 2022-04-08 22:30:00 +12:00
Rob Bygrave 183b601be8 #2641 - toString() - Change BeanCollection toString() implementations, suppress unloaded BeanCollections 2022-04-08 18:53:57 +12:00
Rob Bygrave 5a7e8456e1 #2641 - Provide a decent default toString() implementation for entity beans 2022-04-08 17:35:27 +12:00
Rob Bygrave 6e3db70d20 #2640 - ebean-redis - bump jedis dependency to 4.2.1 from 4.2.0 2022-04-08 09:10:12 +12:00
Rob Bygrave 2be34a8eb8 Bump test modules to 13.2.1-SNAPSHOT after release 2022-04-07 18:46:44 +12:00
Rob Bygrave 1c749e55c6 Fix javadoc in DB 2022-04-07 18:45:19 +12:00
Rob Bygrave 73dd4a5648 [maven-release-plugin] prepare for next development iteration 2022-04-07 18:13:48 +12:00
Rob Bygrave 6802fe9e02 [maven-release-plugin] prepare release ebean-parent-13.2.0 2022-04-07 18:13:41 +12:00
Rob Bygrave 6e5e89f155 Bump ebean-agent to 13.2.0 2022-04-07 18:04:45 +12:00
Rob Bygrave aa351e919d Bump to 13.2.0-SNAPSHOT 2022-04-07 18:03:58 +12:00
Rob BygraveandGitHub 857bde645a Merge pull request #2639 from ebean-orm/feature/deprecated_ServerCache
Remove deprecated methods on ServerCache getHitRatio() -> hitRatio(), getStatistics() -> statistics()
2022-04-07 17:04:31 +12:00
Rob Bygrave ff257a272b Remove deprecated methods on ServerCache getHitRatio() -> hitRatio(), getStatistics() -> statistics() 2022-04-07 17:03:04 +12:00
Rob Bygrave e22e5885e2 Bump parent pom to 3.7 (surefire bump) 2022-04-07 16:48:23 +12:00
Rob Bygrave 71892fd2b5 Organise imports only 2022-04-07 16:44:02 +12:00
Rob BygraveandGitHub e41f9a0669 Merge pull request #2638 from ebean-orm/feature/TenantAwareCache
Refactor L2 cache tenant awareness - add TenantAwareCache
2022-04-07 16:43:05 +12:00
Rob Bygrave f5a779e18b Refactor L2 cache tenant awareness - add TenantAwareCache
The design change is to use TenantAwareCache to deal with wrap/unwrap of tenant aware keys, removing any tenant awareness from the underlying cache implementations (DefaultServerCache, redis, hazelcast etc).
2022-04-07 15:26:21 +12:00
Rob Bygrave daf5220766 #2635 Remove deprecated methods from Database - createSqlQuery() -> sqlQuery(), createSqlUpdate() -> sqlUpdate() 2022-04-06 22:36:31 +12:00
Rob BygraveandGitHub 4b5379c80c Merge pull request #2635 from ebean-orm/feature/deprecated_Database
Remove deprecated methods in ebean-api - Database
2022-04-06 22:30:05 +12:00
Rob BygraveandGitHub 51b4f58744 Merge pull request #2634 from ebean-orm/feature/deprecated_DB
Remove deprecated methods in ebean-api - DB
2022-04-06 22:29:27 +12:00
Rob BygraveandGitHub 539dd7c90c Merge pull request #2637 from ebean-orm/feature/2636_remove_CreatedTimestamp
#2636 - Remove deprecated @CreatedTimestamp and @UpdateTimestamp, migrate to @WhenCreated / @WhenModified
2022-04-06 22:25:21 +12:00
Rob Bygrave c7ad5c5981 #2636 - Remove deprecated @CreatedTimestamp and @UpdateTimestamp, migrate to @WhenCreated / @WhenModified 2022-04-06 22:17:33 +12:00
Rob Bygrave 34ce77c17e Bump to 13.1.1-SNAPSHOT after release 2022-04-06 22:10:01 +12:00
Rob Bygrave bee476ecf6 [maven-release-plugin] prepare for next development iteration 2022-04-06 21:55:18 +12:00
Rob Bygrave 370f50aebe Remove deprecated methods in ebean-api - Database 2022-04-06 21:05:57 +12:00
Rob Bygrave 22db5abdbe Remove deprecated methods in ebean-api - DB 2022-04-06 21:00:35 +12:00
Rob Bygrave bed4721823 Bump ebean-agent to 13.0.1-RC2 with ASM 9.3 - support for Java 19 2022-04-06 16:28:44 +12:00
Rob Bygrave 307832edae Fix test modules in terms of enhancement plugins 2022-04-04 14:04:15 +12:00
Rob Bygrave 1f684107b6 Fix test modules in terms of enhancement plugins 2022-04-04 13:52:37 +12:00
Rob Bygrave 5ab02715ef Support EntityBeanIntercept as an interface with InterceptReadWrite and InterceptReadOnly options
With the view that we can optimise the readOnly + disableLazyLoad case by using InterceptReadOnly which doesn't need to support any of the flags used as part of mutation.
2022-04-04 13:30:26 +12:00
207 changed files with 4099 additions and 4431 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
matrix:
## valhalla - failing on javadoc with:
## javadoc: error - The code being documented uses packages in the unnamed module, but the packages defined in https://ebean.io/platforms/ebean-platform-h2/apidocs/ are in named modules.
java_version: [17,18,19,loom,metropolis,panama]
java_version: [GA,EA,loom,metropolis,panama]
os: [ubuntu-latest]
steps:
+30 -1
View File
@@ -55,9 +55,38 @@ Post questions or issues to the Ebean google group - https://groups.google.com/f
## Documentation
Goto [https://ebean.io/docs/](https://ebean.io/docs/)
## Maven central
[Maven central - io.ebean](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22io.ebean%22%20)
## Building Ebean from source
- JDK 11 or higher installed
- Maven installed
- `git clone git@github.com:ebean-orm/ebean.git`
- `mvn clean install`
Ebean 13 uses Java modules with module-info. This means that there are stricter compilation
rules in place now than when building with classpath pre version 13.
For Maven Surefire testing we use `<surefire.useModulePath>false</surefire.useModulePath>` such
that tests run using classpath and not module-path. We are doing this until all the tooling
(Maven, IDE) improves in the area of testing with module-info.
#### Eclipse IDE
Right now we can't use Eclipse IDE to build Ebean and run its tests due to its poor support
for java modules. See [ebean/issues/2653](https://github.com/ebean-orm/ebean/issues/2653)
The current recommendation is to use IntelliJ IDEA as the IDE to build and hack Ebean.
#### IntelliJ IDEA
We want to get IntelliJ to run tests using classpath similar to Maven Surefire. To do this set:
`JUnit -> modify options -> Do not use module-path option`
To set this option as the global default for IntelliJ use:
`Run - Edit Configurations -> Edit configuration templates -> JUnit -> modify options - Do not use module-path option`
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean-clickhouse</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean-cockroach</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean-db2</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean-h2</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean-hana</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean-mariadb</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean-mysql</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean-nuodb</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean-oracle</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean-postgres</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean-sqlite</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean-sqlserver</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean-yugabyte</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
</project>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>composites</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean (all platforms)</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -35,18 +35,18 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
<scm>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
</project>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<artifactId>composites</artifactId>
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean api</name>
@@ -20,14 +20,14 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
<version>1.7.36</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-config</artifactId>
<version>1.7</version>
<version>2.0</version>
</dependency>
<!--
@@ -49,7 +49,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-annotation</artifactId>
<version>7.8</version>
<version>8.0</version>
</dependency>
<dependency>
@@ -39,26 +39,6 @@ public interface BackgroundExecutor {
*/
void execute(Runnable task);
/**
* Deprecated - migrate to scheduleWithFixedDelay().
* Execute a task periodically with a fixed delay between each execution.
* <p>
* For example, execute a runnable every minute.
* <p>
* The delay is the time between executions no matter how long the task took.
* That is, this method has the same behaviour characteristics as
* {@link ScheduledExecutorService#scheduleWithFixedDelay(Runnable, long, long, TimeUnit)}
*/
@Deprecated
void executePeriodically(Runnable task, long delay, TimeUnit unit);
/**
* Deprecated - migrate to scheduleWithFixedDelay().
* Execute a task periodically additionally with an initial delay different from delay.
*/
@Deprecated
void executePeriodically(Runnable task, long initialDelay, long delay, TimeUnit unit);
/**
* Execute a task periodically with a given delay.
*
+19 -133
View File
@@ -22,10 +22,9 @@ import java.util.concurrent.Callable;
* DB additionally provides a convenient way to use the 'default' Database.
* <p>
* <h3>Default database</h3>
* <p>
* One of the Database instances can be registered as the "default database"
* and can be obtained using <code>DB.getDefault()</code>
* </p>
*
* <pre>{@code
*
* Database database = DB.getDefault();
@@ -36,7 +35,7 @@ import java.util.concurrent.Callable;
* <p>
* Multiple database instances can be registered with DB and we can obtain them
* using <code>DB.byName()</code>
* </p>
*
* <pre>{@code
*
* Database hrDatabase = DB.byName("hr");
@@ -47,7 +46,6 @@ import java.util.concurrent.Callable;
* <p>
* DB has methods like {@link #find(Class)} and {@link #save(Object)} which are
* just convenience for using the default database.
* </p>
*
* <pre>{@code
*
@@ -117,39 +115,26 @@ public final class DB {
* build the WHERE and HAVING clauses. Alternatively you can use the
* ExpressionFactory directly to create expressions to add to the query where
* clause.
* </p>
* <p>
* Alternatively you can use the {@link Expr} as a shortcut to the
* ExpressionFactory of the 'Default' database.
* </p>
* <p>
* You generally need to the an ExpressionFactory (or {@link Expr}) to build
* an expression that uses OR like Expression e = Expr.or(..., ...);
* </p>
*/
public static ExpressionFactory expressionFactory() {
return getDefault().expressionFactory();
}
/**
* Deprecated migrate to expressionFactory().
*/
@Deprecated
public static ExpressionFactory getExpressionFactory() {
return expressionFactory();
}
/**
* Return the next identity value for a given bean type.
* <p>
* This will only work when a IdGenerator is on this bean type such as a DB
* sequence or UUID.
* </p>
* <p>
* For DB's supporting getGeneratedKeys and sequences such as Oracle10 you do
* not need to use this method generally. It is made available for more
* complex cases where it is useful to get an ID prior to some processing.
* </p>
*/
public static Object nextId(Class<?> beanType) {
return getDefault().nextId(beanType);
@@ -159,17 +144,14 @@ public final class DB {
* Start a transaction with 'REQUIRED' semantics.
* <p>
* With REQUIRED semantics if an active transaction already exists that transaction will be used.
* </p>
* <p>
* The transaction is stored in a ThreadLocal variable and typically you only
* need to use the returned Transaction <em>IF</em> you wish to do things like
* use batch mode, change the transaction isolation level, use savepoints or
* log comments to the transaction log.
* </p>
* <p>
* Example of using a transaction to span multiple calls to find(), save()
* etc.
* </p>
* Example of using a transaction to span multiple calls to find(), save() etc.
*
* <pre>{@code
*
* try (Transaction transaction = DB.beginTransaction()) {
@@ -187,7 +169,6 @@ public final class DB {
* With Database we can pass the transaction to the various find(), save() and execute()
* methods. This gives us the ability to create the transactions externally from Ebean
* and use the transaction explicitly via the various methods available on Database.
* </p>
*/
public static Transaction beginTransaction() {
return getDefault().beginTransaction();
@@ -199,7 +180,6 @@ public final class DB {
* You will want to do this if you want multiple Transactions in a single
* thread or generally use transactions outside of the TransactionThreadLocal
* management.
* </p>
*/
public static Transaction createTransaction() {
return getDefault().createTransaction();
@@ -219,7 +199,6 @@ public final class DB {
* <p>
* Note that this provides an try finally alternative to using {@link #executeCall(TxScope, Callable)} or
* {@link #execute(TxScope, Runnable)}.
* </p>
* <p>
* <h3>REQUIRES_NEW example:</h3>
* <pre>{@code
@@ -278,7 +257,7 @@ public final class DB {
/**
* Register a TransactionCallback on the currently active transaction.
* <p/>
* <p>
* If there is no currently active transaction then a PersistenceException is thrown.
*
* @param transactionCallback the transaction callback to be registered with the current transaction
@@ -307,14 +286,12 @@ public final class DB {
* rollback the transaction.
* <p>
* It is preferable to use <em>try with resources</em> rather than this.
* </p>
* <p>
* Useful to put in a finally block to ensure the transaction is ended, rather
* than a rollbackTransaction() in each catch block.
* </p>
* <p>
* Code example:
* </p>
*
* <pre>{@code
* DB.beginTransaction();
* try {
@@ -345,7 +322,6 @@ public final class DB {
* <p>
* When null is passed in for b, then the 'OldValues' of a is used for the
* difference comparison.
* </p>
*/
public static Map<String, ValuePair> diff(Object a, Object b) {
return getDefault().diff(a, b);
@@ -356,18 +332,15 @@ public final class DB {
* <p>
* If there is no current transaction one will be created and committed for
* you automatically.
* </p>
* <p>
* Save can cascade along relationships. For this to happen you need to
* specify a cascade of CascadeType.ALL or CascadeType.PERSIST on the
* OneToMany, OneToOne or ManyToMany annotation.
* </p>
* <p>
* When a save cascades via a OneToMany or ManyToMany Ebean will automatically
* set the 'parent' object to the 'detail' object. In the example below in
* saving the order and cascade saving the order details the 'parent' order
* will be set against each order detail when it is saved.
* </p>
*/
public static void save(Object bean) throws OptimisticLockException {
getDefault().save(bean);
@@ -418,11 +391,9 @@ public final class DB {
* <b>Stateless updates:</b> Note that the bean does not have to be previously fetched to call
* update().You can create a new instance and set some of its properties programmatically for via
* JSON/XML marshalling etc. This is described as a 'stateless update'.
* </p>
* <p>
* <b>Optimistic Locking: </b> Note that if the version property is not set when update() is
* called then no optimistic locking is performed (internally ConcurrencyMode.NONE is used).
* </p>
* <p>
* <pre>{@code
*
@@ -539,20 +510,16 @@ public final class DB {
* Delete the bean.
* <p>
* This will return true if the bean was deleted successfully or JDBC batch is being used.
* </p>
* <p>
* If there is no current transaction one will be created and committed for
* you automatically.
* </p>
* <p>
* If the bean is configured with <code>@SoftDelete</code> then this will perform a soft
* delete rather than a hard/permanent delete.
* </p>
* <p>
* If the Bean does not have a version property (or loaded version property) and
* the bean does not exist then this returns false indicating that nothing was
* deleted. Note that, if JDBC batch mode is used then this always returns true.
* </p>
*/
public static boolean delete(Object bean) throws OptimisticLockException {
return getDefault().delete(bean);
@@ -612,7 +579,6 @@ public final class DB {
* <p>
* Note that this resets OneToMany and ManyToMany properties so that if they
* are accessed a lazy load will refresh the many property.
* </p>
*/
public static void refresh(Object bean) {
getDefault().refresh(bean);
@@ -620,6 +586,7 @@ public final class DB {
/**
* Refresh a 'many' property of a bean.
*
* <pre>{@code
*
* Order order = ...;
@@ -640,7 +607,7 @@ public final class DB {
* Get a reference object.
* <p>
* This is sometimes described as a proxy (with lazy loading).
* </p>
*
* <pre>{@code
*
* Product product = DB.getReference(Product.class, 1);
@@ -661,14 +628,6 @@ public final class DB {
return getDefault().reference(beanType, id);
}
/**
* Deprecated migrate to beanId().
*/
@Deprecated
public static <T> T getReference(Class<T> beanType, Object id) {
return reference(beanType, id);
}
/**
* Sort the list using the sortByClause which can contain a comma delimited
* list of property names and keywords asc, desc, nullsHigh and nullsLow.
@@ -684,7 +643,7 @@ public final class DB {
* <p>
* Note that the sorting uses a Comparator and Collections.sort(); and does
* not invoke a DB query.
* </p>
*
* <pre>{@code
*
* // find orders and their customers
@@ -719,9 +678,8 @@ public final class DB {
*
* }</pre>
* <p>
* If you want more control over the query then you can use createQuery() and
* Query.findOne();
* </p>
* If you want more control over the query then you can use createQuery() and Query.findOne();
*
* <pre>{@code
*
* // ... additionally fetching customer, customer shipping address,
@@ -761,40 +719,25 @@ public final class DB {
}
/**
* Look to execute a native sql query that does not returns beans but instead
* returns SqlRow or direct access to ResultSet (see {@link SqlQuery#findList(RowMapper)}.
*
* Look to execute a native sql query that does not return beans but instead
* returns SqlRow or uses {@link RowMapper}.
* <p>
* Refer to {@link DtoQuery} for native sql queries returning DTO beans.
* </p>
* <p>
* Refer to {@link #findNative(Class, String)} for native sql queries returning entity beans.
* </p>
*/
public static SqlQuery sqlQuery(String sql) {
return getDefault().sqlQuery(sql);
}
/**
* Deprecated - migrate to sqlQuery().
* <p>
* This is an alias for {@link #sqlQuery(String)}.
*/
@Deprecated
public static SqlQuery createSqlQuery(String sql) {
return sqlQuery(sql);
}
/**
* Look to execute a native sql insert update or delete statement.
* <p>
* Use this to execute a Insert Update or Delete statement. The statement will
* be native to the database and contain database table and column names.
* </p>
*
* <p>
* See {@link SqlUpdate} for example usage.
* </p>
*
* @return The SqlUpdate instance to set parameters and execute
*/
@@ -802,16 +745,6 @@ public final class DB {
return getDefault().sqlUpdate(sql);
}
/**
* Deprecated - migrate to sqlUpdate().
* <p>
* This is an alias for {@link #sqlUpdate(String)}.
*/
@Deprecated
public static SqlUpdate createSqlUpdate(String sql) {
return sqlUpdate(sql);
}
/**
* Create a CallableSql to execute a given stored procedure.
*
@@ -828,10 +761,9 @@ public final class DB {
* <p>
* The orm update differs from the sql update in that it you can use the bean
* name and bean property names rather than table and column names.
* </p>
* <p>
* An example:
* </p>
*
* <pre>{@code
*
* // The bean name and properties - "topic","postCount" and "id"
@@ -864,7 +796,6 @@ public final class DB {
* Create a named query.
* <p>
* For RawSql the named query is expected to be in ebean.xml.
* </p>
*
* @param beanType The type of entity bean
* @param namedQuery The name of the query
@@ -880,15 +811,12 @@ public final class DB {
* <p>
* You can use the methods on the Query object to specify fetch paths,
* predicates, order by, limits etc.
* </p>
* <p>
* You then use findList(), findSet(), findMap() and findOne() to execute
* the query and return the collection or bean.
* </p>
* <p>
* Note that a query executed by {@link Query#findList()} etc will execute against
* the same database from which is was created.
* </p>
*
* @param beanType the class of entity to be fetched
* @return A ORM Query for this beanType
@@ -940,7 +868,6 @@ public final class DB {
* This is actually the same as {@link #createQuery(Class)}. The reason it
* exists is that people used to JPA will probably be looking for a
* createQuery method (the same as entityManager).
* </p>
*
* @param beanType the type of entity bean to find
* @return A ORM Query object for this beanType
@@ -953,7 +880,7 @@ public final class DB {
* Create a query using native SQL.
* <p>
* The native SQL can contain named parameters or positioned parameters.
* </p>
*
* <pre>{@code
*
* String sql = "select c.id, c.name from customer c where c.name like ? order by c.name";
@@ -978,7 +905,6 @@ public final class DB {
* <p>
* DTO beans are just normal bean like classes with public constructor(s) and setters.
* They do not need to be registered with Ebean before use.
* </p>
*
* @param dtoType The type of the DTO bean the rows will be mapped into.
* @param sql The SQL query to execute.
@@ -1015,10 +941,8 @@ public final class DB {
* going back to the database.
* <p>
* This produces and returns a new list with the sort and filters applied.
* </p>
* <p>
* Refer to {@link Filter} for an example of its use.
* </p>
*/
public static <T> Filter<T> filter(Class<T> beanType) {
return getDefault().filter(beanType);
@@ -1029,7 +953,7 @@ public final class DB {
* <p>
* The scope can control the transaction type, isolation and rollback
* semantics.
* </p>
*
* <pre>{@code
*
* // set specific transactional scope settings
@@ -1053,7 +977,7 @@ public final class DB {
* <p>
* The default scope runs with REQUIRED and by default will rollback on any
* exception (checked or runtime).
* </p>
*
* <pre>{@code
*
* DB.execute(() -> {
@@ -1078,7 +1002,7 @@ public final class DB {
* <p>
* The scope can control the transaction type, isolation and rollback
* semantics.
* </p>
*
* <pre>{@code
*
* // set specific transactional scope settings
@@ -1102,11 +1026,10 @@ public final class DB {
* <p>
* The default scope runs with REQUIRED and by default will rollback on any
* exception (checked or runtime).
* </p>
* <p>
* This is basically the same as TxRunnable except that it returns an Object
* (and you specify the return type via generics).
* </p>
*
* <pre>{@code
*
* DB.executeCall(() -> {
@@ -1135,23 +1058,19 @@ public final class DB {
* <p>
* If you use DB.execute(UpdateSql) then the table modification information
* is automatically deduced and you do not need to call this method yourself.
* </p>
* <p>
* This information is used to invalidate objects out of the cache and
* potentially text indexes. This information is also automatically broadcast
* across the cluster.
* </p>
* <p>
* If there is a transaction then this information is placed into the current
* transactions event information. When the transaction is committed this
* information is registered (with the transaction manager). If this
* transaction is rolled back then none of the transaction event information
* registers including the information you put in via this method.
* </p>
* <p>
* If there is NO current transaction when you call this method then this
* information is registered immediately (with the transaction manager).
* </p>
*
* @param tableName the name of the table that was modified
* @param inserts true if rows where inserted into the table
@@ -1166,20 +1085,11 @@ public final class DB {
* Return the BeanState for a given entity bean.
* <p>
* This will return null if the bean is not an enhanced entity bean.
* </p>
*/
public static BeanState beanState(Object bean) {
return getDefault().beanState(bean);
}
/**
* Deprecated migrate to beanState().
*/
@Deprecated
public static BeanState getBeanState(Object bean) {
return beanState(bean);
}
/**
* Return the value of the Id property for a given bean.
*/
@@ -1187,14 +1097,6 @@ public final class DB {
return getDefault().beanId(bean);
}
/**
* Deprecated migrate to beanId().
*/
@Deprecated
public static Object getBeanId(Object bean) {
return beanId(bean);
}
/**
* Load and lock the bean using {@code select for update}.
* <p>
@@ -1210,14 +1112,6 @@ public final class DB {
getDefault().lock(bean);
}
/**
* Deprecated migrate to cacheManager().
*/
@Deprecated
public static ServerCacheManager getServerCacheManager() {
return getDefault().cacheManager();
}
/**
* Return the manager of the level 2 cache ("L2" cache).
*/
@@ -1233,14 +1127,6 @@ public final class DB {
return getDefault().backgroundExecutor();
}
/**
* Deprecated migrate to backgroundExecutor().
*/
@Deprecated
public static BackgroundExecutor getBackgroundExecutor() {
return backgroundExecutor();
}
/**
* Return the JsonContext for reading/writing JSON.
*/
@@ -123,81 +123,33 @@ public interface Database {
*/
AutoTune autoTune();
/**
* Deprecated migrate to autoTune().
*/
@Deprecated
default AutoTune getAutoTune() {
return autoTune();
}
/**
* Return the associated DataSource for this Database instance.
*/
DataSource dataSource();
/**
* Deprecated migrate to dataSource().
*/
@Deprecated
default DataSource getDataSource() {
return dataSource();
}
/**
* Return the associated read only DataSource for this Database instance (can be null).
*/
DataSource readOnlyDataSource();
/**
* Deprecated migrate to readOnlyDataSource().
*/
@Deprecated
default DataSource getReadOnlyDataSource() {
return readOnlyDataSource();
}
/**
* Return the name. This is used with {@link DB#byName(String)} to get a
* Database that was registered with the DB singleton.
*/
String name();
/**
* Deprecated migrate to name().
*/
@Deprecated
default String getName() {
return name();
}
/**
* Return the ExpressionFactory for this database.
*/
ExpressionFactory expressionFactory();
/**
* Deprecated migrate to expressionFactory().
*/
@Deprecated
default ExpressionFactory getExpressionFactory() {
return expressionFactory();
}
/**
* Return the MetaInfoManager which is used to get meta data from the Database
* such as query execution statistics.
*/
MetaInfoManager metaInfo();
/**
* Deprecated migrate to metaInfo().
*/
@Deprecated
default MetaInfoManager getMetaInfoManager() {
return metaInfo();
}
/**
* Return the platform used for this database instance.
* <p>
@@ -217,27 +169,11 @@ public interface Database {
*/
Platform platform();
/**
* Deprecated migrate to platform().
*/
@Deprecated
default Platform getPlatform() {
return platform();
}
/**
* Return the extended API intended for use by plugins.
*/
SpiServer pluginApi();
/**
* Deprecated migrate to pluginApi().
*/
@Deprecated
default SpiServer getPluginApi() {
return pluginApi();
}
/**
* Return the BeanState for a given entity bean.
* <p>
@@ -246,27 +182,11 @@ public interface Database {
*/
BeanState beanState(Object bean);
/**
* Deprecated migrate to beanState().
*/
@Deprecated
default BeanState getBeanState(Object bean) {
return beanState(bean);
}
/**
* Return the value of the Id property for a given bean.
*/
Object beanId(Object bean);
/**
* Deprecated migrate to beanId().
*/
@Deprecated
default Object getBeanId(Object bean) {
return beanId(bean);
}
/**
* Set the Id value onto the bean converting the type of the id value if necessary.
* <p>
@@ -279,14 +199,6 @@ public interface Database {
*/
Object beanId(Object bean, Object id);
/**
* Deprecated migrate to beanId().
*/
@Deprecated
default Object setBeanId(Object bean, Object id) {
return beanId(bean, id);
}
/**
* Return a map of the differences between two objects of the same type.
* <p>
@@ -588,14 +500,6 @@ public interface Database {
*/
SqlQuery sqlQuery(String sql);
/**
* Deprecated - migrate to sqlQuery().
* <p>
* This is an alias for {@link #sqlQuery(String)}.
*/
@Deprecated
SqlQuery createSqlQuery(String sql);
/**
* Look to execute a native sql insert update or delete statement.
* <p>
@@ -611,14 +515,6 @@ public interface Database {
*/
SqlUpdate sqlUpdate(String sql);
/**
* Deprecated - migrate to sqlUpdate().
* <p>
* This is an alias for {@link #sqlUpdate(String)}.
*/
@Deprecated
SqlUpdate createSqlUpdate(String sql);
/**
* Create a CallableSql to execute a given stored procedure.
*/
@@ -952,14 +848,6 @@ public interface Database {
*/
<T> T reference(Class<T> beanType, Object id);
/**
* Deprecated migrate to reference().
*/
@Deprecated
default <T> T getReference(Class<T> beanType, Object id) {
return reference(beanType, id);
}
/**
* Return the extended API for Database.
* <p>
@@ -1528,28 +1416,12 @@ public interface Database {
*/
ServerCacheManager cacheManager();
/**
* Deprecated migrate to cacheManager().
*/
@Deprecated
default ServerCacheManager getServerCacheManager() {
return cacheManager();
}
/**
* Return the BackgroundExecutor service for asynchronous processing of
* queries.
*/
BackgroundExecutor backgroundExecutor();
/**
* Deprecated migrate to backgroundExecutor().
*/
@Deprecated
default BackgroundExecutor getBackgroundExecutor() {
return backgroundExecutor();
}
/**
* Return the JsonContext for reading/writing JSON.
* <p>
File diff suppressed because it is too large Load Diff
@@ -1,15 +0,0 @@
package io.ebean;
/**
* Deprecated - please migrate to <code>io.ebean.Database</code>.
* Provides the API for fetching and saving beans to a particular Database.
* <p>
* Effectively this is an alias for {@link Database} which is now the new
* and improved name for EbeanServer.
* <p>
* The preference is to use DB and Database rather than Ebean and EbeanServer.
*/
@Deprecated
public interface EbeanServer extends Database {
}
@@ -1,70 +0,0 @@
package io.ebean;
import io.ebean.config.ContainerConfig;
import io.ebean.config.ServerConfig;
/**
* Deprecated - please migrate to DatabaseFactory.
* <p>
* Creates EbeanServer instances.
* <p>
* This uses either a ServerConfig or properties in the ebean.properties file to
* configure and create a EbeanServer instance.
* </p>
* <p>
* The EbeanServer instance can either be registered with the Ebean singleton or
* not. The Ebean singleton effectively holds a map of EbeanServers by a name.
* If the EbeanServer is registered with the Ebean singleton you can retrieve it
* later via {@link Ebean#getServer(String)}.
* </p>
* <p>
* One EbeanServer can be nominated as the 'default/primary' EbeanServer. Many
* methods on the Ebean singleton such as {@link Ebean#find(Class)} are just a
* convenient way of using the 'default/primary' EbeanServer.
* </p>
*/
@Deprecated
public class EbeanServerFactory {
/**
* Initialise the container with clustering configuration.
* <p>
* Call this prior to creating any EbeanServer instances or alternatively set the
* ContainerConfig on the ServerConfig when creating the first EbeanServer instance.
*/
public static void initialiseContainer(ContainerConfig containerConfig) {
DatabaseFactory.initialiseContainer(containerConfig);
}
/**
* Create using ebean.properties to configure the database.
*/
public static EbeanServer create(String name) {
return (EbeanServer)DatabaseFactory.create(name);
}
/**
* Create using the ServerConfig object to configure the database.
*/
public static EbeanServer create(ServerConfig config) {
return (EbeanServer)DatabaseFactory.create(config);
}
/**
* Create using the ServerConfig additionally specifying a classLoader to use as the context class loader.
*/
public static EbeanServer createWithContextClassLoader(ServerConfig config, ClassLoader classLoader) {
return (EbeanServer)DatabaseFactory.createWithContextClassLoader(config, classLoader);
}
/**
* Shutdown gracefully all EbeanServers cleaning up any resources as required.
* <p>
* This is typically invoked via JVM shutdown hook and not explicitly called.
* </p>
*/
public static void shutdown() {
DatabaseFactory.shutdown();
}
}
@@ -13,8 +13,7 @@ import java.io.Serializable;
* }</pre>
* <p>
* Example: Using a "query join" instead of a "fetch join" we instead use 2 SQL queries
* </p>
* <p>
*
* <pre>{@code
*
* // This will use 2 SQL queries to build this object graph
@@ -27,9 +26,6 @@ import java.io.Serializable;
* // query 2) find orderDetails where order.id in (?,?...) // first 100 order id's
*
* }</pre>
*
* @author mario
* @author rbygrave
*/
public final class FetchConfig implements Serializable {
@@ -40,21 +36,9 @@ public final class FetchConfig implements Serializable {
private static final int LAZY_MODE = 2;
private static final int CACHE_MODE = 3;
private int mode;
private int batchSize;
private int hashCode;
/**
* Deprecated - migrate to one of the static factory methods like {@link FetchConfig#ofQuery()}
* <p>
* Construct using default JOIN mode.
*/
@Deprecated
public FetchConfig() {
//this.mode = JOIN_MODE;
this.batchSize = 100;
this.hashCode = 1000;
}
private final int mode;
private final int batchSize;
private final int hashCode;
private FetchConfig(int mode, int batchSize) {
this.mode = mode;
@@ -106,94 +90,6 @@ public final class FetchConfig implements Serializable {
return new FetchConfig(JOIN_MODE, 100);
}
/**
* We want to migrate away from mutating FetchConfig to a fully immutable FetchConfig.
*/
private FetchConfig mutate(int mode, int batchSize) {
if (batchSize < 0) {
throw new IllegalArgumentException("batch size " + batchSize + " must be > 0");
}
this.mode = mode;
this.batchSize = batchSize;
this.hashCode = mode + 10 * batchSize;
return this;
}
/**
* Deprecated - migrate to FetchConfig.ofLazy().
*/
@Deprecated
public FetchConfig lazy() {
return mutate(LAZY_MODE, 0);
}
/**
* Deprecated - migrate to FetchConfig.ofLazy(batchSize).
*/
@Deprecated
public FetchConfig lazy(int batchSize) {
return mutate(LAZY_MODE, batchSize);
}
/**
* Deprecated - migrate to FetchConfig.ofQuery().
* <p>
* Eagerly fetch the beans in this path as a separate query (rather than as
* part of the main query).
* <p>
* This will use the default batch size for separate query which is 100.
*/
@Deprecated
public FetchConfig query() {
return mutate(QUERY_MODE, 100);
}
/**
* Deprecated - migrate to FetchConfig.ofQuery(batchSize).
* <p>
* Eagerly fetch the beans in this path as a separate query (rather than as
* part of the main query).
* <p>
* The queryBatchSize is the number of parent id's that this separate query
* will load per batch.
* <p>
* This will load all beans on this path eagerly unless a {@link #lazy(int)}
* is also used.
*
* @param batchSize the batch size used to load beans on this path
*/
@Deprecated
public FetchConfig query(int batchSize) {
return mutate(QUERY_MODE, batchSize);
}
/**
* Deprecated - migrate to FetchConfig.ofQuery(batchSize).
* <p>
* Eagerly fetch the first batch of beans on this path.
* This is similar to {@link #query(int)} but only fetches the first batch.
* <p>
* If there are more parent beans than the batch size then they will not be
* loaded eagerly but instead use lazy loading.
*
* @param batchSize the number of parent beans this path is populated for
*/
@Deprecated
public FetchConfig queryFirst(int batchSize) {
return query(batchSize);
}
/**
* Deprecated - migrate to FetchConfig.ofCache().
* <p>
* Eagerly fetch the beans fetching the beans from the L2 bean cache
* and using the DB for beans not in the cache.
*/
@Deprecated
public FetchConfig cache() {
return mutate(CACHE_MODE, 100);
}
/**
* Return the batch size for fetching.
*/
+3 -21
View File
@@ -10,11 +10,10 @@ import java.util.Objects;
* <p>
* This feature is to enable use of L2 cache with complex natural keys with findList() queries in cases where the
* IN clause is not a single property but instead a pair of properties.
* </p>
* <p>
* These queries can have predicates that can be translated into a list of complex natural keys such that the L2
* cache can be hit with these keys to obtain some or all of the beans from L2 cache rather than the DB.
* </p>
*
* <pre>{@code
*
* // where a bean is annotated with a complex
@@ -45,11 +44,10 @@ import java.util.Objects;
* pairs are a unique key/index or part of a unique key/index and highly selective). Currently we know we can do this
* on any DB that supports expression/formula based indexes.
* using a DB string concatenation formula
* </p>
* <p>
* This means, the implementation converts the list of pairs into a list of strings via concatenation and we use a
* DB concatenation formula to match. We see SQL like:
* </p>
*
* <pre>{@code sql
*
* ...
@@ -60,7 +58,7 @@ import java.util.Objects;
* }</pre>
* <p>
* We often create a DB expression index to match the DB concat formula like:
* </p>
*
* <pre>{@code sql
*
* create index ix_name on table_name (sku || '-' || code);
@@ -144,14 +142,6 @@ public final class Pairs {
return this;
}
/**
* Deprecated migrate to concatSeparator()
*/
@Deprecated
public Pairs setConcatSeparator(String concatSeparator) {
return concatSeparator(concatSeparator);
}
/**
* Return a suffix used with DB varchar concatenation to combine the 2 values.
*/
@@ -167,14 +157,6 @@ public final class Pairs {
return this;
}
/**
* Deprecated migrate to concatSuffix()
*/
@Deprecated
public Pairs setConcatSuffix(String concatSuffix) {
return concatSuffix(concatSuffix);
}
@Override
public String toString() {
return "p0:" + property0 + " p1:" + property1 + " entries:" + entries;
+21 -14
View File
@@ -2,6 +2,7 @@ package io.ebean;
import io.avaje.lang.NonNullApi;
import io.avaje.lang.Nullable;
import javax.persistence.NonUniqueResultException;
import java.sql.Connection;
import java.sql.Timestamp;
@@ -1372,18 +1373,9 @@ public interface Query<T> extends CancelableQuery {
* optional asc and desc keywords representing ascending and descending order
* respectively.
*/
Query<T> order(String orderByClause);
/**
* Return the OrderBy so that you can append an ascending or descending
* property to the order by clause.
* <p>
* This will never return a null. If no order by clause exists then an 'empty'
* OrderBy object is returned.
* <p>
* This is the same as <code>orderBy()</code>
*/
OrderBy<T> order();
default Query<T> order(String orderByClause) {
return orderBy(orderByClause);
}
/**
* Return the OrderBy so that you can append an ascending or descending
@@ -1397,15 +1389,30 @@ public interface Query<T> extends CancelableQuery {
OrderBy<T> orderBy();
/**
* Set an OrderBy object to replace any existing OrderBy clause.
* Return the OrderBy so that you can append an ascending or descending
* property to the order by clause.
* <p>
* This will never return a null. If no order by clause exists then an 'empty'
* OrderBy object is returned.
* <p>
* This is the same as <code>orderBy()</code>
*/
Query<T> setOrder(OrderBy<T> orderBy);
default OrderBy<T> order() {
return orderBy();
}
/**
* Set an OrderBy object to replace any existing OrderBy clause.
*/
Query<T> setOrderBy(OrderBy<T> orderBy);
/**
* Set an OrderBy object to replace any existing OrderBy clause.
*/
default Query<T> setOrder(OrderBy<T> orderBy) {
return setOrderBy(orderBy);
}
/**
* Set whether this query uses DISTINCT.
* <p>
@@ -440,14 +440,6 @@ public interface Transaction extends AutoCloseable {
*/
void setGetGeneratedKeys(boolean getGeneratedKeys);
/**
* Deprecated renamed to setGetGeneratedKeys().
*/
@Deprecated
default void setBatchGetGeneratedKeys(boolean getGeneratedKeys) {
setGetGeneratedKeys(getGeneratedKeys);
}
/**
* By default when mixing UpdateSql (or CallableSql) with Beans the batch is
* automatically flushed when you change (between persisting beans and
@@ -463,14 +455,6 @@ public interface Transaction extends AutoCloseable {
*/
void setFlushOnMixed(boolean batchFlushOnMixed);
/**
* Deprecated renamed to setFlushOnMixed().
*/
@Deprecated
default void setBatchFlushOnMixed(boolean batchFlushOnMixed) {
setFlushOnMixed(batchFlushOnMixed);
}
/**
* By default executing a query will automatically flush any batched
* statements (persisted beans, executed UpdateSql etc).
@@ -480,14 +464,6 @@ public interface Transaction extends AutoCloseable {
*/
void setFlushOnQuery(boolean batchFlushOnQuery);
/**
* Deprecated renamed to setFlushOnQuery().
*/
@Deprecated
default void setBatchFlushOnQuery(boolean batchFlushOnQuery) {
setFlushOnQuery(batchFlushOnQuery);
}
/**
* Return true if the batch (of persisted beans or executed UpdateSql etc)
* should be flushed prior to executing a query.
@@ -496,14 +472,6 @@ public interface Transaction extends AutoCloseable {
*/
boolean isFlushOnQuery();
/**
* Deprecated renamed to isFlushOnQuery().
*/
@Deprecated
default boolean isBatchFlushOnQuery() {
return isFlushOnQuery();
}
/**
* The batch will be flushing automatically but you can use this to explicitly
* flush the batch if you like.
@@ -519,14 +487,6 @@ public interface Transaction extends AutoCloseable {
*/
void flush() throws PersistenceException;
/**
* Deprecated - migrate to flush().
* <p>
* flush() is preferred as it matches the JPA flush() method.
*/
@Deprecated
void flushBatch() throws PersistenceException;
/**
* Return the underlying Connection object.
* <p>
@@ -540,14 +500,6 @@ public interface Transaction extends AutoCloseable {
*/
Connection connection();
/**
* Deprecated migrate to connection().
*/
@Deprecated
default Connection getConnection() {
return connection();
}
/**
* Add table modification information to the TransactionEvent.
* <p>
@@ -18,7 +18,7 @@ import java.util.Set;
* <em>java.util.Collection</em>. The reason being that java.util.Map is not a
* Collection. I realise this makes this name confusing so I apologise for that.
*/
public interface BeanCollection<E> extends Serializable {
public interface BeanCollection<E> extends Serializable, ToStringAware {
enum ModifyListenMode {
/**
@@ -11,7 +11,7 @@ import java.io.Serializable;
* general application consumption.
* </p>
*/
public interface EntityBean extends Serializable {
public interface EntityBean extends Serializable, ToStringAware {
/**
* Return all the property names in defined order.
@@ -34,6 +34,13 @@ public interface EntityBean extends Serializable {
throw new NotEnhancedException();
}
/**
* Create and return a new entity bean instance optimised for read only no interception use.
*/
default Object _ebean_newInstanceReadOnly() {
throw new NotEnhancedException();
}
/**
* Generated method that sets the loaded state on all the embedded beans on
* this entity bean by using EntityBeanIntercept.setEmbeddedLoaded(Object o);
@@ -109,4 +116,8 @@ public interface EntityBean extends Serializable {
throw new NotEnhancedException();
}
@Override
default void toString(ToStringBuilder builder) {
throw new NotEnhancedException();
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,536 @@
package io.ebean.bean;
import io.ebean.ValuePair;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
public class InterceptReadOnly implements EntityBeanIntercept {
private final EntityBean owner;
public InterceptReadOnly(Object ownerBean) {
this.owner = (EntityBean) ownerBean;
}
@Override
public EntityBean getOwner() {
return owner;
}
@Override
public PersistenceContext getPersistenceContext() {
return null;
}
@Override
public void setPersistenceContext(PersistenceContext persistenceContext) {
}
@Override
public void setNodeUsageCollector(NodeUsageCollector usageCollector) {
}
@Override
public Object getOwnerId() {
return null;
}
@Override
public void setOwnerId(Object ownerId) {
}
@Override
public Object getEmbeddedOwner() {
return null;
}
@Override
public int getEmbeddedOwnerIndex() {
return 0;
}
@Override
public void clearGetterCallback() {
}
@Override
public void registerGetterCallback(PreGetterCallback getterCallback) {
}
@Override
public void setEmbeddedOwner(EntityBean parentBean, int embeddedOwnerIndex) {
}
@Override
public void setBeanLoader(BeanLoader beanLoader, PersistenceContext ctx) {
}
@Override
public void setBeanLoader(BeanLoader beanLoader) {
}
@Override
public boolean isFullyLoadedBean() {
return false;
}
@Override
public void setFullyLoadedBean(boolean fullyLoadedBean) {
}
@Override
public boolean isPartial() {
return false;
}
@Override
public boolean isDirty() {
return false;
}
@Override
public void setEmbeddedDirty(int embeddedProperty) {
}
@Override
public void setDirty(boolean dirty) {
}
@Override
public boolean isNew() {
return false;
}
@Override
public boolean isNewOrDirty() {
return false;
}
@Override
public boolean hasIdOnly(int idIndex) {
return false;
}
@Override
public boolean isReference() {
return false;
}
@Override
public void setReference(int idPos) {
}
@Override
public void setLoadedFromCache(boolean loadedFromCache) {
}
@Override
public boolean isLoadedFromCache() {
return false;
}
@Override
public boolean isReadOnly() {
return true;
}
@Override
public void setReadOnly(boolean readOnly) {
}
@Override
public void setForceUpdate(boolean forceUpdate) {
}
@Override
public boolean isUpdate() {
return false;
}
@Override
public boolean isLoaded() {
return true;
}
@Override
public void setNew() {
}
@Override
public void setLoaded() {
}
@Override
public void setLoadedLazy() {
}
@Override
public void setLazyLoadFailure(Object ownerId) {
}
@Override
public boolean isLazyLoadFailure() {
return false;
}
@Override
public boolean isDisableLazyLoad() {
return false;
}
@Override
public void setDisableLazyLoad(boolean disableLazyLoad) {
}
@Override
public void setEmbeddedLoaded(Object embeddedBean) {
}
@Override
public boolean isEmbeddedNewOrDirty(Object embeddedBean) {
return false;
}
@Override
public Object getOrigValue(int propertyIndex) {
return null;
}
@Override
public int findProperty(String propertyName) {
return 0;
}
@Override
public String getProperty(int propertyIndex) {
return null;
}
@Override
public int getPropertyLength() {
return 0;
}
@Override
public void setPropertyLoaded(String propertyName, boolean loaded) {
}
@Override
public void setPropertyUnloaded(int propertyIndex) {
}
@Override
public void setLoadedProperty(int propertyIndex) {
}
@Override
public void setLoadedPropertyAll() {
}
@Override
public boolean isLoadedProperty(int propertyIndex) {
return false;
}
@Override
public boolean isChangedProperty(int propertyIndex) {
return false;
}
@Override
public boolean isDirtyProperty(int propertyIndex) {
return false;
}
@Override
public void markPropertyAsChanged(int propertyIndex) {
}
@Override
public void setChangedProperty(int propertyIndex) {
}
@Override
public void setChangeLoaded(int propertyIndex) {
}
@Override
public void setEmbeddedPropertyDirty(int propertyIndex) {
}
@Override
public void setOriginalValue(int propertyIndex, Object value) {
}
@Override
public void setOriginalValueForce(int propertyIndex, Object value) {
}
@Override
public void setNewBeanForUpdate() {
}
@Override
public Set<String> getLoadedPropertyNames() {
return Collections.emptySet();
}
@Override
public boolean[] getDirtyProperties() {
return new boolean[0];
}
@Override
public Set<String> getDirtyPropertyNames() {
return Collections.emptySet();
}
@Override
public void addDirtyPropertyNames(Set<String> props, String prefix) {
}
@Override
public boolean hasDirtyProperty(Set<String> propertyNames) {
return false;
}
@Override
public Map<String, ValuePair> getDirtyValues() {
return Collections.emptyMap();
}
@Override
public void addDirtyPropertyValues(Map<String, ValuePair> dirtyValues, String prefix) {
}
@Override
public void addDirtyPropertyValues(BeanDiffVisitor visitor) {
}
@Override
public StringBuilder getDirtyPropertyKey() {
return null;
}
@Override
public void addDirtyPropertyKey(StringBuilder sb) {
}
@Override
public StringBuilder getLoadedPropertyKey() {
return null;
}
@Override
public boolean[] getLoaded() {
return new boolean[0];
}
@Override
public int getLazyLoadPropertyIndex() {
return 0;
}
@Override
public String getLazyLoadProperty() {
return null;
}
@Override
public void loadBean(int loadProperty) {
}
@Override
public void loadBeanInternal(int loadProperty, BeanLoader loader) {
}
@Override
public void initialisedMany(int propertyIndex) {
}
@Override
public void preGetterCallback(int propertyIndex) {
}
@Override
public void preGetId() {
}
@Override
public void preGetter(int propertyIndex) {
}
@Override
public void preSetterMany(boolean interceptField, int propertyIndex, Object oldValue, Object newValue) {
}
@Override
public void setChangedPropertyValue(int propertyIndex, boolean setDirtyState, Object origValue) {
}
@Override
public void setDirtyStatus() {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, Object oldValue, Object newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, boolean oldValue, boolean newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, int oldValue, int newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, long oldValue, long newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, double oldValue, double newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, float oldValue, float newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, short oldValue, short newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, char oldValue, char newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, byte oldValue, byte newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, char[] oldValue, char[] newValue) {
}
@Override
public void preSetter(boolean intercept, int propertyIndex, byte[] oldValue, byte[] newValue) {
}
@Override
public void setOldValue(int propertyIndex, Object oldValue) {
}
@Override
public int getSortOrder() {
return 0;
}
@Override
public void setSortOrder(int sortOrder) {
}
@Override
public void setDeletedFromCollection(boolean deletedFromCollection) {
}
@Override
public boolean isOrphanDelete() {
return false;
}
@Override
public void setLoadError(int propertyIndex, Exception t) {
}
@Override
public Map<String, Exception> getLoadErrors() {
return null;
}
@Override
public boolean isChangedProp(int i) {
return false;
}
@Override
public MutableValueInfo mutableInfo(int propertyIndex) {
return null;
}
@Override
public void mutableInfo(int propertyIndex, MutableValueInfo info) {
}
@Override
public void mutableNext(int propertyIndex, MutableValueNext next) {
}
@Override
public String mutableNext(int propertyIndex) {
return null;
}
}
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
package io.ebean.bean;
import java.lang.ref.WeakReference;
import java.lang.ref.Cleaner;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -8,120 +8,102 @@ import java.util.Set;
* Collects profile information for a bean (or reference/proxy bean) at a given node.
* <p>
* The node identifies the location of the bean in the object graph.
* </p>
* <p>
* It has to use a weak reference so as to ensure that it does not stop the
* associated bean from being garbage collected.
* </p>
*/
public final class NodeUsageCollector {
/**
* The point in the object graph for a specific query and call stack point.
*/
private final ObjectGraphNode node;
private final static Cleaner cleaner = Cleaner.create();
public static final class State implements Runnable {
private final NodeUsageListener listener;
/**
* The properties used at this profile point.
*/
private final Set<String> used = new LinkedHashSet<>();
/**
* The point in the object graph for a specific query and call stack point.
*/
private final ObjectGraphNode node;
/**
* set to true if the bean is modified (setter called)
*/
private boolean modified;
private State(ObjectGraphNode node, NodeUsageListener listener) {
this.node = node;
this.listener = listener;
}
@Override
public String toString() {
return node + " read:" + used + " modified:" + modified;
}
@Override
public void run() {
listener.collectNodeUsage(this);
}
/**
* Return true if no properties where used.
*/
public boolean isEmpty() {
return used.isEmpty();
}
/**
* Return the associated node which identifies the location in the object
* graph of the bean/reference.
*/
public ObjectGraphNode node() {
return node;
}
/**
* Return the set of used properties.
*/
public Set<String> used() {
return used;
}
/**
* Return true if the bean was modified by a setter.
*/
public boolean isModified() {
return modified;
}
}
private final State state;
public NodeUsageCollector(ObjectGraphNode node, NodeUsageListener listener) {
this.state = new State(node, listener);
cleaner.register(this, state);
}
/**
* Weak to allow garbage collection.
* Return the underlying state.
*/
private final WeakReference<NodeUsageListener> managerRef;
/**
* The properties used at this profile point.
*/
private final Set<String> used = new LinkedHashSet<>();
/**
* set to true if the bean is modified (setter called)
*/
private boolean modified;
/**
* The property that cause a reference to lazy load.
*/
private String loadProperty;
public NodeUsageCollector(ObjectGraphNode node, WeakReference<NodeUsageListener> managerRef) {
this.node = node;
// weak to allow garbage collection.
this.managerRef = managerRef;
public State state() {
return state;
}
/**
* The bean has been modified by a setter method.
*/
public void setModified() {
modified = true;
state.modified = true;
}
/**
* Add the name of a property that has been used.
*/
public void addUsed(String property) {
used.add(property);
}
/**
* The property that invoked a lazy load.
*/
public void setLoadProperty(String loadProperty) {
this.loadProperty = loadProperty;
}
/**
* Publish the usage info to the manager.
*/
private void publishUsageInfo() {
NodeUsageListener manager = managerRef.get();
if (manager != null) {
manager.collectNodeUsage(this);
}
}
/**
* publish the collected usage information when garbage collection occurs.
*/
@Override
protected void finalize() throws Throwable {
publishUsageInfo();
super.finalize();
}
/**
* Return the associated node which identifies the location in the object
* graph of the bean/reference.
*/
public ObjectGraphNode getNode() {
return node;
}
/**
* Return true if no properties where used.
*/
public boolean isEmpty() {
return used.isEmpty();
}
/**
* Return the set of used properties.
*/
public Set<String> getUsed() {
return used;
}
/**
* Return true if the bean was modified by a setter.
*/
public boolean isModified() {
return modified;
}
public String getLoadProperty() {
return loadProperty;
state.used.add(property);
}
@Override
public String toString() {
return node + " read:" + used + " modified:" + modified;
return state.toString();
}
}
@@ -10,7 +10,6 @@ public interface NodeUsageListener {
* <p>
* This is the properties that are used for a given bean in the object graph.
* This information is used by autoTune to tune queries.
* </p>
*/
void collectNodeUsage(NodeUsageCollector collector);
void collectNodeUsage(NodeUsageCollector.State state);
}
@@ -0,0 +1,12 @@
package io.ebean.bean;
/**
* A type that can participate in building toString content with ToStringBuilder.
*/
public interface ToStringAware {
/**
* Append to the ToStringBuilder.
*/
void toString(ToStringBuilder builder);
}
@@ -0,0 +1,190 @@
package io.ebean.bean;
import io.ebean.common.BeanMap;
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.Map;
/**
* Helps build toString content taking into account recursion.
* <p>
* That is, it detects and handles the case where there are relationships that recurse
* and would otherwise become an infinite loop (e.g. bidirectional parent child).
*/
public final class ToStringBuilder {
/**
* The max number of objects that we allow before stopping content being appended.
*/
private static final int MAX = 100;
/**
* Max length of content in string form added for any given value.
*/
private static final int TRIM_LENGTH = 500;
/**
* The max total content after which we stop content being appended.
*/
private static final int MAX_TOTAL_CONTENT = 2000;
private final IdentityHashMap<Object, Integer> id = new IdentityHashMap<>();
private final StringBuilder sb = new StringBuilder(50);
private boolean first = true;
private int counter;
@Override
public String toString() {
return sb.toString();
}
/**
* Set of an object being added.
*/
public void start(Object bean) {
if (counter == 0) {
id.putIfAbsent(bean, 0);
}
if (counter <= MAX) {
sb.append(bean.getClass().getSimpleName()).append("@").append(counter).append("(");
}
}
/**
* Add a property as name value pair.
*/
public void add(String name, Object value) {
if (value != null && counter <= MAX) {
if (value instanceof BeanCollection) {
if (((BeanCollection<?>)value).isReference()) {
// suppress unloaded bean collections
return;
}
}
key(name);
value(value);
}
}
/**
* Add raw content.
*/
public void addRaw(String content) {
sb.append(content);
}
/**
* End of an object.
*/
public void end() {
if (counter <= MAX) {
sb.append(")");
}
}
private void key(String name) {
if (counter > MAX) {
return;
}
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(name).append(":");
}
private void value(Object value) {
if (counter > MAX) {
return;
}
if (value instanceof ToStringAware) {
if (value instanceof BeanCollection) {
((ToStringAware) value).toString(this);
} else if (push(value)) {
((ToStringAware) value).toString(this);
}
} else if (value instanceof Collection) {
addCollection((Collection<?>) value);
} else if (value instanceof Map) {
addMap(((Map<?, ?>) value));
} else {
String content = String.valueOf(value);
if (content.length() > TRIM_LENGTH) {
content = content.substring(0, TRIM_LENGTH) + " <trimmed>";
}
sb.append(content);
if (sb.length() >= MAX_TOTAL_CONTENT) {
sb.append(" ...");
counter += MAX;
}
}
}
public void addMap(Map<?,?> map) {
if (map == null || map.isEmpty()) {
sb.append("{}");
} else {
boolean firstElement = true;
sb.append("{");
for (Map.Entry<?, ?> entry : map.entrySet()) {
if (firstElement) {
firstElement = false;
} else {
sb.append(", ");
}
sb.append(entry.getKey()).append(":");
value(entry.getValue());
if (counter > MAX) {
return;
}
}
sb.append("}");
}
}
/**
* Add a collection of values.
*/
public void addCollection(Collection<?> c) {
if (c == null || c.isEmpty()) {
sb.append("[]");
return;
}
boolean firstElement = true;
sb.append("[");
for (Object o : c) {
if (firstElement) {
firstElement = false;
} else {
sb.append(", ");
}
value(o);
if (counter > MAX) {
return;
}
}
sb.append("]");
}
private boolean push(Object bean) {
if (counter > MAX) {
return false;
}
if (counter == MAX) {
sb.append(" ...");
counter++;
return false;
}
Integer idx = id.putIfAbsent(bean, counter++);
if (idx != null) {
--counter;
sb.append(bean.getClass().getSimpleName()).append("@").append(idx);
return false;
}
first = true;
return true;
}
}
+15 -15
View File
@@ -1,5 +1,6 @@
package io.ebean.cache;
import io.avaje.lang.Nullable;
import io.ebean.meta.MetricVisitor;
import java.util.LinkedHashMap;
@@ -68,40 +69,39 @@ public interface ServerCache {
/**
* Return the number of entries in the cache.
*/
int size();
default int size() {
return 0;
}
/**
* Return the hit ratio the cache is currently getting.
*/
default int hitRatio() {
return getHitRatio();
return 0;
}
/**
* Deprecated migrate to hitRatio().
*/
@Deprecated
int getHitRatio();
/**
* Return statistics for the cache.
*
* @param reset if true the statistics are reset.
*/
@Nullable
default ServerCacheStatistics statistics(boolean reset) {
return getStatistics(reset);
return null;
}
/**
* Deprecated migrate to statistics().
*/
@Deprecated
ServerCacheStatistics getStatistics(boolean reset);
/**
* Visit the metrics for the cache.
*/
default void visit(MetricVisitor visitor) {
// do nothing by default
}
/**
* Unwrap the underlying ServerCache.
*/
@SuppressWarnings("unchecked")
default <T> T unwrap(Class<T> cls) {
return (T) this;
}
}
@@ -13,6 +13,7 @@ public class ServerCacheConfig {
private final ServerCacheOptions cacheOptions;
private final CurrentTenantProvider tenantProvider;
private final QueryCacheEntryValidate queryCacheEntryValidate;
private final TenantAwareKey tenantAwareKey;
public ServerCacheConfig(ServerCacheType type, String cacheKey, String shortName, ServerCacheOptions cacheOptions, CurrentTenantProvider tenantProvider, QueryCacheEntryValidate queryCacheEntryValidate) {
this.type = type;
@@ -21,6 +22,14 @@ public class ServerCacheConfig {
this.cacheOptions = cacheOptions;
this.tenantProvider = tenantProvider;
this.queryCacheEntryValidate = queryCacheEntryValidate;
this.tenantAwareKey = (tenantProvider == null) ? null : new TenantAwareKey(tenantProvider);
}
/**
* Return the ServerCache taking into account if multi-tenant is used.
*/
public ServerCache tenantAware(ServerCache cache) {
return tenantAwareKey == null ? cache : new TenantAwareCache(cache, tenantAwareKey);
}
/**
@@ -0,0 +1,105 @@
package io.ebean.cache;
import io.ebean.meta.MetricVisitor;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* A ServerCache proxy that is tenant aware.
*/
public final class TenantAwareCache implements ServerCache {
private final ServerCache delegate;
private final TenantAwareKey tenantAwareKey;
/**
* Create given the TenantAwareKey and delegate cache to proxy to.
*
* @param delegate The cache to proxy to
* @param tenantAwareKey Provides tenant aware keys to use in the cache
*/
public TenantAwareCache(ServerCache delegate, TenantAwareKey tenantAwareKey) {
this.delegate = delegate;
this.tenantAwareKey = tenantAwareKey;
}
/**
* Return the underlying ServerCache that is being delegated to.
*/
@SuppressWarnings("unchecked")
@Override
public <T> T unwrap(Class<T> cls) {
return (T) delegate;
}
@Override
public void visit(MetricVisitor visitor) {
delegate.visit(visitor);
}
private Object key(Object key) {
return tenantAwareKey.key(key);
}
@Override
public Object get(Object id) {
return delegate.get(key(id));
}
@Override
public void put(Object id, Object value) {
delegate.put(key(id), value);
}
@Override
public void remove(Object id) {
delegate.remove(key(id));
}
@Override
public void clear() {
delegate.clear();
}
@Override
public int size() {
return delegate.size();
}
@Override
public int hitRatio() {
return delegate.hitRatio();
}
@Override
public ServerCacheStatistics statistics(boolean reset) {
return delegate.statistics(reset);
}
@Override
public Map<Object, Object> getAll(Set<Object> keys) {
Map<Object, Object> keyMapping = new HashMap<>(keys.size());
keys.forEach(k -> keyMapping.put(key(k), k));
Map<Object, Object> tmp = delegate.getAll(keyMapping.keySet());
Map<Object, Object> ret = new HashMap<>(keys.size());
// unwrap tenant info here
tmp.forEach((k,v)-> ret.put(((TenantAwareKey.CacheKey) k).key, v));
return ret;
}
@Override
public void putAll(Map<Object, Object> keyValues) {
Map<Object, Object> tmp = new HashMap<>();
keyValues.forEach((k, v) -> tmp.put(key(k), v));
delegate.putAll(tmp);
}
@Override
public void removeAll(Set<Object> keys) {
delegate.removeAll(keys.stream().map(this::key).collect(Collectors.toSet()));
}
}
@@ -1,9 +1,6 @@
package io.ebean.common;
import io.ebean.bean.BeanCollection;
import io.ebean.bean.BeanCollectionAdd;
import io.ebean.bean.BeanCollectionLoader;
import io.ebean.bean.EntityBean;
import io.ebean.bean.*;
import java.io.Serializable;
import java.util.ArrayList;
@@ -47,6 +44,11 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
super(loader, ownerBean, propertyName);
}
@Override
public void toString(ToStringBuilder builder) {
builder.addCollection(list);
}
@Override
public void reset(EntityBean ownerBean, String propertyName) {
this.ownerBean = ownerBean;
@@ -191,18 +193,11 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
@Override
public String toString() {
StringBuilder sb = new StringBuilder(50);
sb.append("BeanList ");
if (isReadOnly()) {
sb.append("readOnly ");
}
if (list == null) {
sb.append("deferred ");
return "BeanList<deferred>";
} else {
sb.append("size[").append(list.size()).append("] ");
sb.append("list").append(list);
return list.toString();
}
return sb.toString();
}
/**
@@ -3,6 +3,7 @@ package io.ebean.common;
import io.ebean.bean.BeanCollection;
import io.ebean.bean.BeanCollectionLoader;
import io.ebean.bean.EntityBean;
import io.ebean.bean.ToStringBuilder;
import java.util.Collection;
import java.util.Collections;
@@ -40,6 +41,19 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
super(ebeanServer, ownerBean, propertyName);
}
@Override
public void toString(ToStringBuilder builder) {
if (map == null || map.isEmpty()) {
builder.addRaw("{}");
} else {
builder.addRaw("{");
for (Entry<K, E> entry : map.entrySet()) {
builder.add(String.valueOf(entry.getKey()), entry.getValue());
}
builder.addRaw("}");
}
}
@Override
public void reset(EntityBean ownerBean, String propertyName) {
this.ownerBean = ownerBean;
@@ -183,27 +197,20 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
@Override
public String toString() {
StringBuilder sb = new StringBuilder(50);
sb.append("BeanMap ");
if (isReadOnly()) {
sb.append("readOnly ");
}
if (map == null) {
sb.append("deferred ");
return "BeanMap<deferred>";
} else {
sb.append("size[").append(map.size()).append("]");
sb.append(" map").append(map);
return map.toString();
}
return sb.toString();
}
/**
* Equal if obj is a Map and equal in a Map sense.
* Equal if object is a Map and equal in a Map sense.
*/
@Override
public boolean equals(Object obj) {
public boolean equals(Object object) {
init();
return map.equals(obj);
return map.equals(object);
}
@Override
@@ -1,9 +1,6 @@
package io.ebean.common;
import io.ebean.bean.BeanCollection;
import io.ebean.bean.BeanCollectionAdd;
import io.ebean.bean.BeanCollectionLoader;
import io.ebean.bean.EntityBean;
import io.ebean.bean.*;
import java.io.Serializable;
import java.util.Collection;
@@ -41,6 +38,11 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
super(loader, ownerBean, propertyName);
}
@Override
public void toString(ToStringBuilder builder) {
builder.addCollection(set);
}
@Override
public void reset(EntityBean ownerBean, String propertyName) {
this.ownerBean = ownerBean;
@@ -169,18 +171,11 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
@Override
public String toString() {
StringBuilder sb = new StringBuilder(50);
sb.append("BeanSet ");
if (isReadOnly()) {
sb.append("readOnly ");
}
if (set == null) {
sb.append("deferred ");
return "BeanSet<deferred>";
} else {
sb.append("size[").append(set.size()).append("]");
sb.append(" set").append(set);
return set.toString();
}
return sb.toString();
}
/**
@@ -340,11 +340,6 @@ public class DatabaseConfig {
*/
private ClassLoadConfig classLoadConfig = new ClassLoadConfig();
/**
* The data source JNDI name if using a JNDI DataSource.
*/
private String dataSourceJndiName;
/**
* The naming convention.
*/
@@ -392,12 +387,12 @@ public class DatabaseConfig {
* Note: It is possible that multiple servers are sharing the same state file as
* long as they are in the <b>same</b> JVM/ClassLoader scope. In this case it is
* recommended to use the same uuidNodeId configuration.
*
*
* If you have multiple servers in different JVMs, do <b>not</b> share the state
* files!
*/
private String uuidNodeId;
/**
* The clock used for setting the timestamps (e.g. @UpdatedTimestamp) on objects.
*/
@@ -1761,24 +1756,6 @@ public class DatabaseConfig {
this.readOnlyDataSourceConfig = readOnlyDataSourceConfig;
}
/**
* Return the JNDI name of the DataSource to use.
*/
public String getDataSourceJndiName() {
return dataSourceJndiName;
}
/**
* Set the JNDI name of the DataSource to use.
* <p>
* By default a prefix of "java:comp/env/jdbc/" is used to lookup the
* DataSource. This prefix is not used if dataSourceJndiName starts with
* "java:".
*/
public void setDataSourceJndiName(String dataSourceJndiName) {
this.dataSourceJndiName = dataSourceJndiName;
}
/**
* Return a value used to represent TRUE in the database.
* <p>
@@ -2061,14 +2038,14 @@ public class DatabaseConfig {
public void setUuidStateFile(String uuidStateFile) {
this.uuidStateFile = uuidStateFile;
}
/**
* Returns the V1-UUID-NodeId
* Returns the V1-UUID-NodeId
*/
public String getUuidNodeId() {
return uuidNodeId;
}
/**
* Sets the V1-UUID-NodeId.
*/
@@ -2937,7 +2914,6 @@ public class DatabaseConfig {
asOfViewSuffix = p.get("asOfViewSuffix", asOfViewSuffix);
asOfSysPeriod = p.get("asOfSysPeriod", asOfSysPeriod);
historyTableSuffix = p.get("historyTableSuffix", historyTableSuffix);
dataSourceJndiName = p.get("dataSourceJndiName", dataSourceJndiName);
jdbcFetchSizeFindEach = p.getInt("jdbcFetchSizeFindEach", jdbcFetchSizeFindEach);
jdbcFetchSizeFindList = p.getInt("jdbcFetchSizeFindList", jdbcFetchSizeFindList);
databasePlatformName = p.get("databasePlatformName", databasePlatformName);
@@ -1,47 +0,0 @@
package io.ebean.config;
import io.ebean.DatabaseFactory;
/**
* Deprecated - please migrate to <code>io.ebean.DatabaseConfig</code>.
*
* The configuration used for creating a Database.
* <p>
* Used to programmatically construct a Database and optionally register it
* with the DB singleton.
* </p>
* <p>
* If you just use DB without this programmatic configuration DB will read
* the application.properties file and take the configuration from there. This usually
* includes searching the class path and automatically registering any entity
* classes and listeners etc.
* </p>
* <pre>{@code
*
* ServerConfig config = new ServerConfig();
*
* // read the ebean.properties and load
* // those settings into this serverConfig object
* config.loadFromProperties();
*
* // explicitly register the entity beans to avoid classpath scanning
* config.addClass(Customer.class);
* config.addClass(User.class);
*
* Database database = DatabaseFactory.create(config);
*
* }</pre>
*
* <p>
* Note that ServerConfigProvider provides a standard Java ServiceLoader mechanism that can
* be used to apply configuration to the ServerConfig.
* </p>
*
* @author emcgreal
* @author rbygrave
* @see DatabaseFactory
*/
@Deprecated
public class ServerConfig extends DatabaseConfig {
}
@@ -1,41 +0,0 @@
package io.ebean.config;
/**
* Deprecated - migrate to DatabaseConfigProvider.
* <p>
* Provides a ServiceLoader based mechanism to configure a ServerConfig.
* <p>
* Provide an implementation and register it via the standard Java ServiceLoader mechanism
* via a file at <code>META-INF/services/io.ebean.config.ServerConfigProvider</code>.
* <p>
* If you are using a DI container like Spring or Guice you are unlikely to use this but instead use a
* spring specific configuration. When we are not using a DI container we may use this mechanism to
* explicitly register the entity beans and avoid classpath scanning.
* </p>
* <pre>{@code
*
* public class EbeanConfigProvider implements ServerConfigProvider {
*
* @Override
* public void apply(ServerConfig config) {
*
* // register the entity bean classes explicitly
* config.addClass(Customer.class);
* config.addClass(User.class);
* ...
* }
* }
*
* }</pre>
*/
@Deprecated
public interface ServerConfigProvider {
/**
* Apply the configuration to the ServerConfig.
* <p>
* Typically we explicitly register entity bean classes and thus avoid classpath scanning.
* </p>
*/
void apply(ServerConfig config);
}
@@ -1,7 +1,6 @@
package io.ebean.event;
import io.ebean.Database;
import io.ebean.EbeanServer;
import io.ebean.Transaction;
/**
@@ -9,63 +8,24 @@ import io.ebean.Transaction;
*/
public interface BeanDeleteIdRequest {
/**
* Deprecated migrate to database().
*/
@Deprecated
EbeanServer getEbeanServer();
/**
* Deprecated migrate to database().
*/
@Deprecated
default Database getDatabase() {
return getEbeanServer();
}
/**
* Return the DB processing the request.
*/
default Database database() {
return getEbeanServer();
}
Database database();
/**
* Return the Transaction associated with this request.
*/
Transaction transaction();
/**
* Deprecated migrate to transaction().
*/
@Deprecated
default Transaction getTransaction() {
return transaction();
}
/**
* Returns the bean type of the bean being deleted.
*/
Class<?> beanType();
/**
* Deprecated migrate to beanType().
*/
@Deprecated
default Class<?> getBeanType() {
return beanType();
}
/**
* Returns the Id value of the bean being deleted.
*/
Object id();
/**
* Deprecated migrate to id().
*/
@Deprecated
default Object getId() {
return id();
}
}
@@ -1,7 +1,6 @@
package io.ebean.event;
import io.ebean.Database;
import io.ebean.EbeanServer;
import io.ebean.Transaction;
import io.ebean.ValuePair;
@@ -20,29 +19,13 @@ public interface BeanPersistRequest<T> {
/**
* Return the DB processing the request.
*/
default Database database() {
return getEbeanServer();
}
/**
* Deprecated migrate to database().
*/
@Deprecated
EbeanServer getEbeanServer();
Database database();
/**
* Return the Transaction associated with this request.
*/
Transaction transaction();
/**
* Deprecated migrate to transaction().
*/
@Deprecated
default Transaction getTransaction() {
return transaction();
}
/**
* Return true if this request is due to cascading persist.
* False implies this is a "top level" request.
@@ -55,14 +38,6 @@ public interface BeanPersistRequest<T> {
*/
Set<String> loadedProperties();
/**
* Deprecated migrate to loadedProperties().
*/
@Deprecated
default Set<String> getLoadedProperties() {
return loadedProperties();
}
/**
* For an update this is the set of properties that where updated.
* <p>
@@ -72,27 +47,11 @@ public interface BeanPersistRequest<T> {
*/
Set<String> updatedProperties();
/**
* Deprecated migrate to updatedProperties().
*/
@Deprecated
default Set<String> getUpdatedProperties() {
return updatedProperties();
}
/**
* Flags set for dirty properties (used by ElasticSearch integration).
*/
boolean[] dirtyProperties();
/**
* Deprecated migrate to updatedProperties().
*/
@Deprecated
default boolean[] getDirtyProperties() {
return dirtyProperties();
}
/**
* Return true for an update request if at least one of dirty properties is contained
* in the given set of property names.
@@ -115,25 +74,9 @@ public interface BeanPersistRequest<T> {
*/
T bean();
/**
* Deprecated migrate to bean().
*/
@Deprecated
default T getBean() {
return bean();
}
/**
* Returns a map of the properties that have changed and their new and old values.
*/
Map<String, ValuePair> updatedValues();
/**
* Deprecated migrate to updatedValues().
*/
@Deprecated
default Map<String, ValuePair> getUpdatedValues() {
return updatedValues();
}
}
@@ -1,7 +1,6 @@
package io.ebean.event;
import io.ebean.Database;
import io.ebean.EbeanServer;
import io.ebean.Query;
import io.ebean.Transaction;
@@ -13,42 +12,18 @@ public interface BeanQueryRequest<T> {
/**
* Return the DB processing the request.
*/
default Database database() {
return getEbeanServer();
}
/**
* Deprecated migrate to database().
*/
@Deprecated
EbeanServer getEbeanServer();
Database database();
/**
* Return the Transaction associated with this request.
*/
Transaction transaction();
/**
* Deprecated migrate to transaction().
*/
@Deprecated
default Transaction getTransaction() {
return transaction();
}
/**
* Returns the query.
*/
Query<T> query();
/**
* Deprecated migrate to query().
*/
@Deprecated
default Query<T> getQuery() {
return query();
}
/**
* Return true if an Id IN expression should have the bind parameters padded.
*/
@@ -10,14 +10,6 @@ public interface BulkTableEvent {
*/
String tableName();
/**
* Deprecated migrate to tableName().
*/
@Deprecated
default String getTableName() {
return tableName();
}
/**
* Return true if rows were inserted.
*/
@@ -10,10 +10,9 @@ class ClassUtil {
* Return a new instance of the class using the default constructor.
*/
static Object newInstance(String className) {
try {
Class<?> cls = forName(className);
return cls.newInstance();
return cls.getDeclaredConstructor().newInstance();
} catch (Exception e) {
String msg = "Error constructing " + className;
throw new IllegalArgumentException(msg, e);
@@ -27,7 +26,6 @@ class ClassUtil {
return new ClassLoadContext().forName(name);
}
/**
* Helper to wrap the context and caller classLoaders (to use/try both).
*/
@@ -48,7 +46,6 @@ class ClassUtil {
}
public Class<?> forName(String name) throws ClassNotFoundException {
try {
return Class.forName(name, true, contextLoader);
} catch (ClassNotFoundException e) {
@@ -59,7 +56,6 @@ class ClassUtil {
}
}
}
}
}
@@ -18,79 +18,31 @@ public interface SpiServer extends Database {
*/
DatabaseConfig config();
/**
* Migrate to config().
*/
@Deprecated
default DatabaseConfig getServerConfig() {
return config();
}
/**
* Return the DatabasePlatform for this database.
*/
DatabasePlatform databasePlatform();
/**
* Migrate to config().
*/
@Deprecated
default DatabasePlatform getDatabasePlatform() {
return databasePlatform();
}
/**
* Return all the bean types registered on this server instance.
*/
List<? extends BeanType<?>> beanTypes();
/**
* Migrate to beanTypes().
*/
@Deprecated
default List<? extends BeanType<?>> getBeanTypes() {
return beanTypes();
}
/**
* Return the bean type for a given entity bean class.
*/
<T> BeanType<T> beanType(Class<T> beanClass);
/**
* Migrate to beanType().
*/
@Deprecated
default <T> BeanType<T> getBeanType(Class<T> beanClass) {
return beanType(beanClass);
}
/**
* Return the bean types mapped to the given base table.
*/
List<? extends BeanType<?>> beanTypes(String baseTableName);
/**
* Migrate to beanTypes().
*/
@Deprecated
default List<? extends BeanType<?>> getBeanTypes(String baseTableName) {
return beanTypes(baseTableName);
}
/**
* Return the bean type for a given doc store queueId.
*/
BeanType<?> beanTypeForQueueId(String queueId);
/**
* Migrate to beanTypes().
*/
@Deprecated
default BeanType<?> getBeanTypeForQueueId(String queueId) {
return beanTypeForQueueId(queueId);
}
/**
* Return a BeanLoader.
*/
+1
View File
@@ -19,6 +19,7 @@ module io.ebean.api {
requires static io.ebean.types;
requires static com.fasterxml.jackson.core;
requires static com.fasterxml.jackson.databind;
requires static javax.servlet.api;
exports io.ebean;
@@ -0,0 +1,42 @@
package io.ebean.bean;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class NodeUsageCollectorTest {
private final Listener listener = new Listener();
private final ObjectGraphNode node = new ObjectGraphNode((ObjectGraphOrigin) null, "foo");
/**
* Run this manually as we make use of explicit GC call here which is dubious.
*/
@Disabled
@Test
void test() throws InterruptedException {
NodeUsageCollector c = new NodeUsageCollector(node, listener);
c.addUsed("a");
c.addUsed("b");
c = null;
System.gc();
Thread.sleep(100);
assertThat(listener.collectCount).isEqualTo(1);
assertThat(node).isNotNull();
}
static class Listener implements NodeUsageListener {
int collectCount;
@Override
public void collectNodeUsage(NodeUsageCollector.State collector) {
collectCount++;
System.out.println("collectNodeUsage " + collector);
}
}
}
@@ -0,0 +1,287 @@
package io.ebean.bean;
import io.ebean.common.BeanList;
import io.ebean.common.BeanMap;
import io.ebean.common.BeanSet;
import org.junit.jupiter.api.Test;
import java.util.*;
import static org.assertj.core.api.Assertions.assertThat;
class ToStringBuilderTest {
@Test
void basic() {
ToStringBuilder builder = new ToStringBuilder();
builder.start(new Object());
builder.end();
assertThat(builder.toString()).isEqualTo("Object@0()");
}
@Test
void fields() {
ToStringBuilder builder = new ToStringBuilder();
builder.start(new Object());
builder.add("a", 1);
builder.add("b", "B");
builder.end();
assertThat(builder.toString()).isEqualTo("Object@0(a:1, b:B)");
}
@Test
void max100Beans_expect_noMoreContentAfterMax100() {
String loop100 = addLoopForMaxBeans(100);
String loop101 = addLoopForMaxBeans(101);
String loop900 = addLoopForMaxBeans(900);
assertThat(loop100).isEqualTo(loop101);
assertThat(loop101).isEqualTo(loop900);
}
private String addLoopForMaxBeans(int loopMax) {
ToStringBuilder builder = new ToStringBuilder();
builder.start(new Object());
for (int i = 0; i <= loopMax; i++) {
addForMax(builder, i);
}
builder.end();
return builder.toString();
}
private void addForMax(ToStringBuilder builder, int i) {
builder.add("c", new B(i));
}
@Test
void maxContent_expect_noMoreContentAfterMax2000() {
String loop23 = addContentLoop(23);
String loop24 = addContentLoop(24);
String loop25 = addContentLoop(25);
assertThat(loop23).isEqualTo(loop24);
assertThat(loop23).isEqualTo(loop25);
}
private String addContentLoop(int loopMax) {
ToStringBuilder builder = new ToStringBuilder();
builder.start(new Object());
for (int i = 0; i <= loopMax; i++) {
addForMaxContent(builder, i);
}
builder.end();
return builder.toString();
}
private void addForMaxContent(ToStringBuilder builder, int i) {
builder.add("someContentThatAddsUp", new Recurse(i, "SomeContentThatAddsUp_SomeContentThatAddsUp!!"));
}
@Test
void add_referenceBeanCollection_expect_nothingAdded() {
ToStringBuilder builder = new ToStringBuilder();
builder.add("ref", new BeanList<>(null));
assertThat(builder.toString()).isEqualTo("");
}
@Test
void addCollection_some() {
ToStringBuilder builder = new ToStringBuilder();
builder.addCollection( new BeanList<>(List.of("A","B")));
assertThat(builder.toString()).isEqualTo("[A, B]");
}
@Test
void addCollection_null() {
ToStringBuilder builder = new ToStringBuilder();
builder.addCollection(null);
assertThat(builder.toString()).isEqualTo("[]");
}
@Test
void addCollection_empty() {
ToStringBuilder builder = new ToStringBuilder();
builder.addCollection(Collections.emptyList());
assertThat(builder.toString()).isEqualTo("[]");
}
@Test
void flatBean() {
Recurse instance0 = new Recurse(42, "java");
assertThat(instance0.toString()).isEqualTo("Recurse@0(id:42, nm:java)");
}
@Test
void recursive_expect_reference() {
Recurse instance0 = new Recurse(42, "java");
instance0.other = instance0;
assertThat(instance0.toString()).isEqualTo("Recurse@0(id:42, nm:java, other:Recurse@0)");
}
@Test
void notRecursive() {
Recurse instance0 = new Recurse(42, "java");
instance0.other = new Recurse(43, "jvm");
assertThat(instance0.toString()).isEqualTo("Recurse@0(id:42, nm:java, other:Recurse@1(id:43, nm:jvm))");
}
@Test
void beanList_null_empty() {
assertThat(toStringFor(new BeanList<String>(null))).isEqualTo("[]");
assertThat(toStringFor(new BeanList<String>(Collections.emptyList()))).isEqualTo("[]");
}
@Test
void beanSet_null_empty() {
assertThat(toStringFor(new BeanSet<String>(null))).isEqualTo("[]");
assertThat(toStringFor(new BeanSet<String>(Collections.emptySet()))).isEqualTo("[]");
}
@Test
void beanMap_null_empty() {
assertThat(toStringFor(new BeanMap<String, String>(null))).isEqualTo("{}");
assertThat(toStringFor(new BeanMap<String, String>(Collections.emptyMap()))).isEqualTo("{}");
}
@Test
void beanList_some() {
BeanList<Recurse> list = new BeanList<>(List.of(new Recurse(1, "a"), new Recurse(2, "b")));
assertThat(toStringFor(list)).isEqualTo("[Recurse@1(id:1, nm:a), Recurse@2(id:2, nm:b)]");
}
@Test
void beanSet_some() {
BeanSet<Recurse> list = new BeanSet<>(new LinkedHashSet<>(List.of(new Recurse(1, "a"), new Recurse(2, "b"))));
assertThat(toStringFor(list)).isEqualTo("[Recurse@1(id:1, nm:a), Recurse@2(id:2, nm:b)]");
}
@Test
void beanMap_some() {
Map<String, Recurse> under = new LinkedHashMap<>();
under.put("a", new Recurse(1, "a"));
under.put("b", new Recurse(2, "b"));
BeanMap<String, Recurse> list = new BeanMap<>(under);
assertThat(toStringFor(list)).isEqualTo("{a:Recurse@1(id:1, nm:a), b:Recurse@2(id:2, nm:b)}");
}
@Test
void map_recurse() {
final ParamStore paramStore = new ParamStore(1);
paramStore.map.put("aaa", new ParamValue(1, paramStore));
paramStore.map.put("bbb", new ParamValue(2, paramStore));
assertThat(toStringFor(paramStore))
.isEqualTo("ParamStore@0(id:1, map:{aaa:ParamValue@1(id:1, pm:ParamStore@0), bbb:ParamValue@2(id:2, pm:ParamStore@0)})");
}
private String toStringFor(ToStringAware aware) {
ToStringBuilder builder = new ToStringBuilder();
aware.toString(builder);
return builder.toString();
}
static final class ParamValue implements ToStringAware {
final int id;
final ParamStore parentModel;
ParamValue(final int id, final ParamStore parentModel) {
this.id = id;
this.parentModel = parentModel;
}
public String toString() {
ToStringBuilder builder = new ToStringBuilder();
toString(builder);
return builder.toString();
}
@Override
public void toString(ToStringBuilder builder) {
builder.start(this);
builder.add("id", id);
builder.add("pm", parentModel);
builder.end();
}
}
static final class ParamStore implements ToStringAware {
final int id;
final Map<String, ParamValue> map = new HashMap<>();
ParamStore(final int id) {
this.id = id;
}
public String toString() {
ToStringBuilder builder = new ToStringBuilder();
toString(builder);
return builder.toString();
}
@Override
public void toString(ToStringBuilder builder) {
builder.start(this);
builder.add("id", id);
builder.add("map", map);
builder.end();
}
}
static final class Recurse implements ToStringAware {
final int id;
final String nm;
Recurse other;
Recurse(int id, String nm) {
this.id = id;
this.nm = nm;
}
public String toString() {
ToStringBuilder builder = new ToStringBuilder();
toString(builder);
return builder.toString();
}
@Override
public void toString(ToStringBuilder builder) {
builder.start(this);
builder.add("id", id);
builder.add("nm", nm);
builder.add("other", other);
builder.end();
}
}
static final class B implements ToStringAware {
final int id;
B(int id) {
this.id = id;
}
public String toString() {
ToStringBuilder builder = new ToStringBuilder();
toString(builder);
return builder.toString();
}
@Override
public void toString(ToStringBuilder builder) {
builder.start(this);
builder.add("b", id);
builder.end();
}
}
}
@@ -0,0 +1,113 @@
package io.ebean.cache;
import io.ebean.cache.TenantAwareKey.CacheKey;
import io.ebean.config.CurrentTenantProvider;
import org.junit.jupiter.api.Test;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import static org.assertj.core.api.Assertions.assertThat;
class TenantAwareCacheTest {
ServerCache serverCache;
TenantAwareCache cache;
TenantAwareCacheTest() {
TenantAwareKey key = new TenantAwareKey(new TenantProv());
this.serverCache = new Cache();
this.cache = new TenantAwareCache(serverCache, key);
}
@Test
void put_get_remove() {
cache.put("A", "a");
Object val = cache.get("A");
assertThat(val).isEqualTo("a");
CacheKey cacheKey = new CacheKey("A", 42);
Object val2 = serverCache.get(cacheKey);
assertThat(val2).isEqualTo("a");
cache.put("B", "bb");
assertThat(cache.size()).isEqualTo(2);
cache.remove("A");
assertThat(cache.get("A")).isNull();
assertThat(cache.size()).isEqualTo(1);
cache.clear();
assertThat(cache.size()).isEqualTo(0);
assertThat(cache.get("B")).isNull();
}
@Test
void putAll_getAll_removeAll() {
Map<Object, Object> map = new HashMap<>();
map.put("A", "a");
map.put("B", "b");
map.put("C", "c");
cache.putAll(map);
assertThat(cache.size()).isEqualTo(3);
assertThat(cache.get("A")).isEqualTo("a");
assertThat(serverCache.get(new CacheKey("A", 42))).isEqualTo("a");
Map<Object, Object> result = cache.getAll(Set.of("A", "B", "C", "D"));
assertThat(result).hasSize(3);
assertThat(result).containsOnlyKeys("A", "B", "C");
assertThat(result.values()).containsOnly("a", "b", "c");
cache.removeAll(Set.of("A", "C", "D"));
assertThat(cache.size()).isEqualTo(1);
assertThat(cache.get("B")).isEqualTo("b");
assertThat(serverCache.get(new CacheKey("B", 42))).isEqualTo("b");
cache.remove("B");
assertThat(cache.size()).isEqualTo(0);
}
static class TenantProv implements CurrentTenantProvider {
@Override
public Object currentId() {
return 42;
}
}
static class Cache implements ServerCache {
Map<Object, Object> map = new ConcurrentHashMap<>();
@Override
public Object get(Object id) {
return map.get(id);
}
@Override
public void put(Object id, Object value) {
map.put(id, value);
}
@Override
public void remove(Object id) {
map.remove(id);
}
@Override
public void clear() {
map.clear();
}
@Override
public int size() {
return map.size();
}
}
}
@@ -1,4 +1,4 @@
package io.ebean.xtest.config;
package io.ebean.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.ebean.annotation.MutationDetection;
@@ -17,11 +17,10 @@ import java.util.Properties;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
public class DatabaseConfigTest {
class DatabaseConfigTest {
@Test
public void testLoadFromEbeanProperties() {
void testLoadFromEbeanProperties() {
DatabaseConfig config = new DatabaseConfig();
config.loadFromProperties();
@@ -30,8 +29,7 @@ public class DatabaseConfigTest {
}
@Test
public void evalPropertiesInput() {
void evalPropertiesInput() {
String home = System.getProperty("user.home");
String fileSeparator = System.getProperty("file.separator");
@@ -46,8 +44,7 @@ public class DatabaseConfigTest {
}
@Test
public void testLoadWithProperties() {
void testLoadWithProperties() {
DatabaseConfig config = new DatabaseConfig();
config.setPersistBatch(PersistBatch.NONE);
config.setPersistBatchOnCascade(PersistBatch.NONE);
@@ -154,8 +151,7 @@ public class DatabaseConfigTest {
}
@Test
public void test_defaults() {
void test_defaults() {
DatabaseConfig config = new DatabaseConfig();
assertTrue(config.isIdGeneratorAutomatic());
assertTrue(config.isDefaultServer());
@@ -186,8 +182,7 @@ public class DatabaseConfigTest {
}
@Test
public void test_putServiceObject() {
void test_putServiceObject() {
ObjectMapper objectMapper = new ObjectMapper();
DatabaseConfig config = new DatabaseConfig();
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<!-- <parent>-->
<!-- <groupId>org.avaje</groupId>-->
@@ -14,7 +14,7 @@
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
<name>ebean autotune</name>
@@ -26,7 +26,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
<scope>provided</scope>
</dependency>
@@ -55,7 +55,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
<scope>test</scope>
</dependency>
@@ -70,7 +70,7 @@
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:13.1.0</tile>
<tile>io.ebean.tile:enhancement:13.3.0</tile>
</tiles>
</configuration>
</plugin>
@@ -91,8 +91,8 @@ public class ProfileManager implements ProfilingListener {
* is called on the bean.
*/
@Override
public void collectNodeUsage(NodeUsageCollector usageCollector) {
ProfileOrigin profileOrigin = getProfileOrigin(usageCollector.getNode().getOriginQueryPoint());
public void collectNodeUsage(NodeUsageCollector.State usageCollector) {
ProfileOrigin profileOrigin = getProfileOrigin(usageCollector.node().getOriginQueryPoint());
profileOrigin.collectUsageInfo(usageCollector);
}
@@ -151,9 +151,9 @@ public class ProfileOrigin {
/**
* Collect the usage information for from a instance for this node.
*/
public void collectUsageInfo(NodeUsageCollector profile) {
public void collectUsageInfo(NodeUsageCollector.State profile) {
if (!profile.isEmpty()) {
getNodeStats(profile.getNode().getPath()).collectUsageInfo(profile);
getNodeStats(profile.node().getPath()).collectUsageInfo(profile);
}
}
@@ -103,11 +103,10 @@ public class ProfileOriginNodeUsage {
/**
* Collect usage from a node.
*/
protected void collectUsageInfo(NodeUsageCollector profile) {
protected void collectUsageInfo(NodeUsageCollector.State profile) {
lock.lock();
try {
Set<String> used = profile.getUsed();
Set<String> used = profile.used();
profileCount++;
if (!used.isEmpty()) {
profileUsedCount++;
@@ -1,6 +1,7 @@
package io.ebeaninternal.server.autotune.service;
import io.ebean.bean.NodeUsageCollector;
import io.ebean.bean.NodeUsageListener;
import io.ebean.bean.ObjectGraphNode;
import io.ebean.bean.ObjectGraphOrigin;
import io.ebeaninternal.server.deploy.BeanDescriptor;
@@ -13,6 +14,15 @@ import static org.assertj.core.api.Assertions.assertThat;
public class ProfileOriginTest extends BaseTestCase {
static class Noop implements NodeUsageListener {
@Override
public void collectNodeUsage(NodeUsageCollector.State state) {
// do nothing
}
}
private final NodeUsageListener listener = new Noop();
private final BeanDescriptor<Order> desc = getBeanDescriptor(Order.class);
@Test
@@ -23,7 +33,7 @@ public class ProfileOriginTest extends BaseTestCase {
c.addUsed("name");
ProfileOrigin po = new ProfileOrigin(null, false, 1, 1);
po.collectUsageInfo(c);
po.collectUsageInfo(c.state());
OrmQueryDetail detail = po.buildDetail(desc);
@@ -38,11 +48,11 @@ public class ProfileOriginTest extends BaseTestCase {
c.addUsed("name");
ProfileOrigin po = new ProfileOrigin(null, false, 1, 1);
po.collectUsageInfo(c);
po.collectUsageInfo(c.state());
c = node(null);
c.addUsed("orderDate");
po.collectUsageInfo(c);
po.collectUsageInfo(c.state());
OrmQueryDetail detail = po.buildDetail(desc);
@@ -56,11 +66,11 @@ public class ProfileOriginTest extends BaseTestCase {
c.addUsed("id");
ProfileOrigin po = new ProfileOrigin(null, false, 1, 1);
po.collectUsageInfo(c);
po.collectUsageInfo(c.state());
c = node(null);
c.addUsed("orderDate");
po.collectUsageInfo(c);
po.collectUsageInfo(c.state());
OrmQueryDetail detail = po.buildDetail(desc);
@@ -75,15 +85,15 @@ public class ProfileOriginTest extends BaseTestCase {
NodeUsageCollector c = node(null);
c.addUsed("orderDate");
c.addUsed("customer");
po.collectUsageInfo(c);
po.collectUsageInfo(c.state());
c = node("customer");
c.addUsed("billingAddress");
po.collectUsageInfo(c);
po.collectUsageInfo(c.state());
c = node("customer.billingAddress");
c.addUsed("id");
po.collectUsageInfo(c);
po.collectUsageInfo(c.state());
OrmQueryDetail detail = po.buildDetail(desc);
@@ -100,20 +110,20 @@ public class ProfileOriginTest extends BaseTestCase {
NodeUsageCollector c = node(null);
c.addUsed("customer");
po.collectUsageInfo(c);
po.collectUsageInfo(c.state());
c = node("customer");
c.addUsed("id");
c.addUsed("name");
c.addUsed("note");
c.addUsed("billingAddress");
po.collectUsageInfo(c);
po.collectUsageInfo(c.state());
//fetch details.product (id,name)
c = node("customer.billingAddress");
c.addUsed("id");
c.addUsed("line1");
po.collectUsageInfo(c);
po.collectUsageInfo(c.state());
OrmQueryDetail detail = po.buildDetail(desc);
assertThat(detail.asString()).isEqualTo("fetch customer (name,note) fetch customer.billingAddress (line1)");
@@ -121,7 +131,7 @@ public class ProfileOriginTest extends BaseTestCase {
private NodeUsageCollector node(String path) {
ObjectGraphNode node = new ObjectGraphNode((ObjectGraphOrigin)null, path);
return new NodeUsageCollector(node, null);
return new NodeUsageCollector(node, listener);
}
// @Test
+15 -15
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<name>ebean bom</name>
@@ -71,88 +71,88 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-xml</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-autotune</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>kotlin-querybean-generator</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-redis</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<artifactId>ebean-core-type</artifactId>
@@ -16,7 +16,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
+9 -9
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>13.1.0</version>
<version>13.6.0</version>
</parent>
<artifactId>ebean-core</artifactId>
@@ -15,7 +15,7 @@
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-parent-13.1.0</tag>
<tag>ebean-parent-13.6.0</tag>
</scm>
<dependencies>
@@ -29,7 +29,7 @@
<dependency>
<groupId>io.avaje</groupId>
<artifactId>classpath-scanner</artifactId>
<version>6.2</version>
<version>7.1</version>
</dependency>
<dependency>
@@ -41,19 +41,19 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
</dependency>
<dependency>
@@ -144,21 +144,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>13.1.0</version>
<version>13.6.0</version>
<scope>test</scope>
</dependency>
@@ -23,7 +23,7 @@ import java.util.stream.Stream;
/**
* Service Provider extension to EbeanServer.
*/
public interface SpiEbeanServer extends SpiServer, ExtendedServer, EbeanServer, BeanCollectionLoader {
public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectionLoader {
/**
* Return true if the L2 cache has been disabled.
@@ -55,7 +55,6 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, EbeanServer,
* <p>
* Typically used to identify the origin of queries for AutoTune and object
* graph costing.
* </p>
*/
CallOrigin createCallOrigin();
@@ -391,6 +391,11 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
*/
void incrementAsOfTableCount();
/**
* Increment the counter of tables used in 'As Of' query.
*/
void incrementAsOfTableCount(int asOfTableCount);
/**
* Return the table alias used for the base table.
*/
@@ -312,11 +312,6 @@ public abstract class SpiTransactionProxy implements SpiTransaction {
transaction.flush();
}
@Override
public void flushBatch() throws PersistenceException {
flush();
}
@Override
public Connection connection() {
return transaction.connection();
@@ -2,14 +2,7 @@ package io.ebeaninternal.server.cache;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
/**
* List of changes to be applied to L2 cache.
@@ -3,12 +3,7 @@ package io.ebeaninternal.server.cache;
import io.ebean.annotation.Cache;
import io.ebean.annotation.CacheBeanTuning;
import io.ebean.annotation.CacheQueryTuning;
import io.ebean.cache.QueryCacheEntryValidate;
import io.ebean.cache.ServerCache;
import io.ebean.cache.ServerCacheConfig;
import io.ebean.cache.ServerCacheFactory;
import io.ebean.cache.ServerCacheOptions;
import io.ebean.cache.ServerCacheType;
import io.ebean.cache.*;
import io.ebean.config.CurrentTenantProvider;
import io.ebean.meta.MetricVisitor;
import io.ebean.util.AnnotationUtil;
@@ -3,7 +3,6 @@ package io.ebeaninternal.server.cache;
import io.ebean.BackgroundExecutor;
import io.ebean.cache.ServerCache;
import io.ebean.cache.ServerCacheStatistics;
import io.ebean.cache.TenantAwareKey;
import io.ebean.meta.MetricVisitor;
import io.ebean.metric.CountMetric;
import io.ebean.metric.MetricFactory;
@@ -12,12 +11,10 @@ import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
/**
* The default cache implementation.
@@ -48,21 +45,23 @@ public class DefaultServerCache implements ServerCache {
protected final String name;
protected final String shortName;
private final int maxSize;
private final int trimFrequency;
private final int maxIdleSecs;
private final int maxSecsToLive;
private final TenantAwareKey tenantAwareKey;
protected final int maxSize;
protected final int trimFrequency;
protected final int maxIdleSecs;
protected final int maxSecsToLive;
protected final long trimOnPut;
protected final ReentrantLock lock = new ReentrantLock();
protected final AtomicLong mutationCounter = new AtomicLong();
public DefaultServerCache(DefaultServerCacheConfig config) {
this.name = config.getName();
this.shortName = config.getShortName();
this.map = config.getMap();
this.maxSize = config.getMaxSize();
this.tenantAwareKey = new TenantAwareKey(config.getTenantProvider());
this.maxIdleSecs = config.getMaxIdleSecs();
this.maxSecsToLive = config.getMaxSecsToLive();
this.trimFrequency = config.determineTrimFrequency();
this.trimOnPut = config.determineTrimOnPut();
MetricFactory factory = MetricFactory.get();
String prefix = "l2n.";
@@ -92,7 +91,7 @@ public class DefaultServerCache implements ServerCache {
}
@Override
public ServerCacheStatistics getStatistics(boolean reset) {
public ServerCacheStatistics statistics(boolean reset) {
ServerCacheStatistics cacheStats = new ServerCacheStatistics();
cacheStats.setCacheName(name);
cacheStats.setMaxSize(maxSize);
@@ -121,7 +120,7 @@ public class DefaultServerCache implements ServerCache {
}
@Override
public int getHitRatio() {
public int hitRatio() {
long mc = missCount.get(false);
long hc = hitCount.get(false);
long totalCount = hc + mc;
@@ -152,19 +151,12 @@ public class DefaultServerCache implements ServerCache {
map.clear();
}
/**
* Return the tenant aware key.
*/
protected Object key(Object id) {
return tenantAwareKey.key(id);
}
/**
* Return a value from the cache.
*/
@Override
public Object get(Object id) {
CacheEntry entry = getCacheEntry(id);
public Object get(Object key) {
CacheEntry entry = getCacheEntry(key);
if (entry == null) {
missCount.increment();
return null;
@@ -184,8 +176,8 @@ public class DefaultServerCache implements ServerCache {
/**
* Get the cache entry - override for query cache to validate dependent tables.
*/
protected CacheEntry getCacheEntry(Object id) {
final SoftReference<CacheEntry> ref = map.get(key(id));
protected CacheEntry getCacheEntry(Object key) {
final SoftReference<CacheEntry> ref = map.get(key);
return ref != null ? ref.get() : null;
}
@@ -198,18 +190,20 @@ public class DefaultServerCache implements ServerCache {
* Put a value into the cache.
*/
@Override
public void put(Object id, Object value) {
Object key = key(id);
public void put(Object key, Object value) {
map.put(key, new SoftReference<>(new CacheEntry(key, value)));
putCount.increment();
if (mutationCounter.incrementAndGet() > trimOnPut) {
runEviction();
}
}
/**
* Remove an entry from the cache.
*/
@Override
public void remove(Object id) {
SoftReference<CacheEntry> entry = map.remove(key(id));
public void remove(Object key) {
SoftReference<CacheEntry> entry = map.remove(key);
if (entry != null && entry.get() != null) {
removeCount.increment();
}
@@ -237,62 +231,72 @@ public class DefaultServerCache implements ServerCache {
* Run the eviction based on Idle time, Time to live and LRU last access.
*/
public void runEviction() {
long trimForMaxSize;
if (maxSize == 0) {
trimForMaxSize = 0;
} else {
trimForMaxSize = size() - maxSize;
}
if (maxIdleSecs == 0 && maxSecsToLive == 0 && trimForMaxSize < 0) {
// nothing to trim on this cache
return;
}
long startNanos = System.nanoTime();
long trimmedByIdle = 0;
long trimmedByGC = 0;
long trimmedByTTL = 0;
long trimmedByLRU = 0;
List<CacheEntry> activeList = new ArrayList<>(map.size());
long idleExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxIdleSecs);
long ttlExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxSecsToLive);
Iterator<SoftReference<CacheEntry>> it = map.values().iterator();
while (it.hasNext()) {
SoftReference<CacheEntry> ref = it.next();
final CacheEntry cacheEntry = ref.get();
if (cacheEntry == null) {
it.remove();
trimmedByGC++;
} else if (maxIdleSecs > 0 && idleExpireNano > cacheEntry.getLastAccessTime()) {
it.remove();
trimmedByIdle++;
} else if (maxSecsToLive > 0 && ttlExpireNano > cacheEntry.getCreateTime()) {
it.remove();
trimmedByTTL++;
} else if (trimForMaxSize > 0) {
activeList.add(cacheEntry);
lock.lock();
try {
long trimForMaxSize;
if (maxSize == 0) {
trimForMaxSize = 0;
} else {
trimForMaxSize = size() - maxSize;
}
}
if (trimForMaxSize > 0 && activeList.size() > maxSize) {
// sort into last access time ascending
activeList.sort(BY_LAST_ACCESS);
int trimSize = getTrimSize();
for (int i = trimSize; i < activeList.size(); i++) {
// remove if still in the cache
if (map.remove(activeList.get(i).getKey()) != null) {
trimmedByLRU++;
if (maxIdleSecs == 0 && maxSecsToLive == 0 && trimForMaxSize < 0) {
// nothing to trim on this cache
mutationCounter.set(0);
return;
}
long startNanos = System.nanoTime();
long trimmedByIdle = 0;
long trimmedByGC = 0;
long trimmedByTTL = 0;
long trimmedByLRU = 0;
try {
List<CacheEntry> activeList = new ArrayList<>(map.size());
long idleExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxIdleSecs);
long ttlExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxSecsToLive);
Iterator<SoftReference<CacheEntry>> it = map.values().iterator();
while (it.hasNext()) {
SoftReference<CacheEntry> ref = it.next();
final CacheEntry cacheEntry = ref.get();
if (cacheEntry == null) {
it.remove();
trimmedByGC++;
} else if (maxIdleSecs > 0 && idleExpireNano > cacheEntry.getLastAccessTime()) {
it.remove();
trimmedByIdle++;
} else if (maxSecsToLive > 0 && ttlExpireNano > cacheEntry.getCreateTime()) {
it.remove();
trimmedByTTL++;
} else if (trimForMaxSize > 0) {
activeList.add(cacheEntry.forSort());
}
}
if (trimForMaxSize > 0 && activeList.size() > maxSize) {
// sort into last access time ascending
activeList.sort(BY_LAST_ACCESS);
int trimSize = getTrimSize();
for (int i = trimSize; i < activeList.size(); i++) {
// remove if still in the cache
if (map.remove(activeList.get(i).getKey()) != null) {
trimmedByLRU++;
}
}
}
mutationCounter.set(0);
evictCount.add(trimmedByIdle);
evictCount.add(trimmedByGC);
evictCount.add(trimmedByTTL);
evictCount.add(trimmedByLRU);
if (logger.isTraceEnabled()) {
long exeMicros = TimeUnit.MICROSECONDS.convert(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
logger.trace("Executed trim of cache {} in [{}]millis idle[{}] timeToLive[{}] accessTime[{}] gc[{}]",
name, exeMicros, trimmedByIdle, trimmedByTTL, trimmedByLRU, trimmedByGC);
}
} catch (Throwable e) {
logger.warn("Error during trim of DefaultServerCache [" + name + "]. Cache might be bigger than desired.", e);
}
}
evictCount.add(trimmedByIdle);
evictCount.add(trimmedByGC);
evictCount.add(trimmedByTTL);
evictCount.add(trimmedByLRU);
if (logger.isTraceEnabled()) {
long exeMicros = TimeUnit.MICROSECONDS.convert(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
logger.trace("Executed trim of cache {} in [{}]millis idle[{}] timeToLive[{}] accessTime[{}] gc[{}]",
name, exeMicros, trimmedByIdle, trimmedByTTL, trimmedByLRU, trimmedByGC);
} finally {
lock.unlock();
}
}
@@ -308,7 +312,7 @@ public class DefaultServerCache implements ServerCache {
}
/**
* Comparator for sorting by last access time.
* Comparator for sorting by last access sort, a copy of last access time that should not mutate during trim processing.
*/
public static final class CompareByLastAccess implements Comparator<CacheEntry>, Serializable {
@@ -316,7 +320,7 @@ public class DefaultServerCache implements ServerCache {
@Override
public int compare(CacheEntry e1, CacheEntry e2) {
return Long.compare(e1.getLastAccessTime(), e2.getLastAccessTime());
return Long.compare(e1.lastAccessSort, e2.lastAccessSort);
}
}
@@ -329,6 +333,7 @@ public class DefaultServerCache implements ServerCache {
private final Object value;
private final long createTime;
private long lastAccessTime;
private long lastAccessSort;
public CacheEntry(Object key, Object value) {
this.key = key;
@@ -337,6 +342,14 @@ public class DefaultServerCache implements ServerCache {
this.lastAccessTime = createTime;
}
/**
* Store a copy of lastAccessTime used for sorting. This value should not change during trim processing.
*/
public CacheEntry forSort() {
this.lastAccessSort = lastAccessTime;
return this;
}
/**
* Return the entry key.
*/
@@ -3,7 +3,6 @@ package io.ebeaninternal.server.cache;
import io.ebean.cache.QueryCacheEntryValidate;
import io.ebean.cache.ServerCacheConfig;
import io.ebean.cache.ServerCacheOptions;
import io.ebean.config.CurrentTenantProvider;
import io.ebeaninternal.server.cache.DefaultServerCache.CacheEntry;
import java.lang.ref.SoftReference;
@@ -34,10 +33,6 @@ public final class DefaultServerCacheConfig {
this.maxSize = options.getMaxSize();
}
public CurrentTenantProvider getTenantProvider() {
return config.getTenantProvider();
}
public QueryCacheEntryValidate getQueryCacheEntryValidate() {
return config.getQueryCacheEntryValidate();
}
@@ -81,4 +76,14 @@ public final class DefaultServerCacheConfig {
}
return 0;
}
/**
* Determine the number of mutations/puts required to trigger a runEviction() in the foreground.
*/
public long determineTrimOnPut() {
if (maxSize > 0) {
return maxSize / 10;
}
return 1000;
}
}
@@ -1,11 +1,7 @@
package io.ebeaninternal.server.cache;
import io.ebean.BackgroundExecutor;
import io.ebean.cache.ServerCache;
import io.ebean.cache.ServerCacheConfig;
import io.ebean.cache.ServerCacheFactory;
import io.ebean.cache.ServerCacheNotification;
import io.ebean.cache.ServerCacheNotify;
import io.ebean.cache.*;
/**
@@ -41,7 +37,7 @@ final class DefaultServerCacheFactory implements ServerCacheFactory {
if (executor != null) {
cache.periodicTrim(executor);
}
return cache;
return config.tenantAware(cache);
}
@Override
@@ -10,11 +10,7 @@ import io.ebeaninternal.server.deploy.DCacheRegion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* Manages the bean and query caches.
@@ -27,8 +27,7 @@ public class DefaultServerQueryCache extends DefaultServerCache {
}
@Override
protected CacheEntry getCacheEntry(Object id) {
Object key = key(id);
protected CacheEntry getCacheEntry(Object key) {
final SoftReference<CacheEntry> ref = map.get(key);
CacheEntry entry = ref != null ? ref.get() : null;
if (entry == null) {
@@ -1,6 +1,6 @@
package io.ebeaninternal.server.cluster;
import io.ebean.EbeanServer;
import io.ebean.Database;
import io.ebean.config.ContainerConfig;
import io.ebeaninternal.server.transaction.RemoteTransactionEvent;
import org.slf4j.Logger;
@@ -20,7 +20,7 @@ public class ClusterManager implements ServerLookup {
private final ReentrantLock lock = new ReentrantLock();
private final ConcurrentHashMap<String, EbeanServer> serverMap = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Database> serverMap = new ConcurrentHashMap<>();
private final Object monitor = new Object();
@@ -53,7 +53,7 @@ public class ClusterManager implements ServerLookup {
return factory;
}
public void registerServer(EbeanServer server) {
public void registerServer(Database server) {
lock.lock();
try {
serverMap.put(server.name(), server);
@@ -66,7 +66,7 @@ public class ClusterManager implements ServerLookup {
}
@Override
public EbeanServer getServer(String name) {
public Database getServer(String name) {
lock.lock();
try {
return serverMap.get(name);
@@ -1,14 +1,14 @@
package io.ebeaninternal.server.cluster;
import io.ebean.EbeanServer;
import io.ebean.Database;
/**
* Returns EbeanServer instances for remote message reading.
* Returns Database instances for remote message reading.
*/
public interface ServerLookup {
/**
* Return the EbeanServer instance by name.
*/
EbeanServer getServer(String name);
Database getServer(String name);
}
@@ -1,6 +1,6 @@
package io.ebeaninternal.server.core;
import io.ebean.EbeanServer;
import io.ebean.Database;
import io.ebeaninternal.api.CoreLog;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiTransaction;
@@ -79,7 +79,7 @@ public abstract class BeanRequest {
* Return the server processing the request. Made available for
* BeanController and BeanFinder.
*/
public EbeanServer getEbeanServer() {
public Database database() {
return server;
}
@@ -5,8 +5,6 @@ import io.ebean.config.ContainerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DatabaseConfigProvider;
import io.ebean.config.ModuleInfoLoader;
import io.ebean.config.ServerConfig;
import io.ebean.config.ServerConfigProvider;
import io.ebean.config.TenantMode;
import io.ebean.config.UnderscoreNamingConvention;
import io.ebean.config.dbplatform.DatabasePlatform;
@@ -124,15 +122,8 @@ public final class DefaultContainer implements SpiContainer {
private void applyConfigServices(DatabaseConfig config) {
if (config.isDefaultServer()) {
boolean appliedConfig = false;
for (DatabaseConfigProvider configProvider : ServiceLoader.load(DatabaseConfigProvider.class)) {
configProvider.apply(config);
appliedConfig = true;
}
if (!appliedConfig && config instanceof ServerConfig) {
for (ServerConfigProvider configProvider : ServiceLoader.load(ServerConfigProvider.class)) {
configProvider.apply((ServerConfig)config);
}
}
}
if (config.isAutoLoadModuleInfo()) {
@@ -978,21 +978,11 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return new DefaultRelationalQuery(this, sql.trim());
}
@Override
public SqlQuery createSqlQuery(String sql) {
return sqlQuery(sql);
}
@Override
public SqlUpdate sqlUpdate(String sql) {
return new DefaultSqlUpdate(this, sql.trim());
}
@Override
public SqlUpdate createSqlUpdate(String sql) {
return sqlUpdate(sql);
}
@Override
public CallableSql createCallableSql(String sql) {
return new DefaultCallableSql(this, sql.trim());
@@ -1,5 +1,6 @@
package io.ebeaninternal.server.core;
import io.ebean.annotation.Platform;
import io.ebean.config.DatabaseConfig;
import io.ebean.datasource.DataSourceAlertFactory;
import io.ebean.datasource.DataSourceConfig;
@@ -14,7 +15,6 @@ import javax.sql.DataSource;
*/
final class InitDataSource {
private final JndiDataSourceLookup jndiDataSourceFactory = new JndiDataSourceLookup();
private final DatabaseConfig config;
/**
@@ -41,21 +41,9 @@ final class InitDataSource {
* Initialise the "main" read write DataSource from configuration.
*/
private DataSource initDataSource() {
final String jndiName = config.getDataSourceJndiName();
if (jndiName != null) {
return jndiDataSource(jndiName);
}
return createFromConfig(config.getDataSourceConfig(), false);
}
private DataSource jndiDataSource(String jndiName) {
DataSource ds = jndiDataSourceFactory.lookup(jndiName);
if (ds == null) {
throw new PersistenceException("JNDI lookup for DataSource " + jndiName + " returned null.");
}
return ds;
}
/**
* Initialise the "read only" DataSource from configuration.
*/
@@ -110,10 +98,16 @@ final class InitDataSource {
dsConfig.setReadOnly(true);
dsConfig.setDefaults(config.getDataSourceConfig());
dsConfig.setIsolationLevel(config.getDataSourceConfig().getIsolationLevel());
} else if (isPostgresAllQuotedIdentifiers()) {
dsConfig.addProperty("quoteReturningIdentifiers", false);
}
return create(dsConfig, readOnly);
}
boolean isPostgresAllQuotedIdentifiers() {
return config.isAllQuotedIdentifiers() && Platform.POSTGRES == config.getDatabasePlatform().getPlatform().base();
}
private DataSource create(DataSourceConfig dsConfig, boolean readOnly) {
String poolName = config.getName() + (readOnly ? "-ro" : "");
return DataSourceFactory.create(poolName, dsConfig);
@@ -1,33 +0,0 @@
package io.ebeaninternal.server.core;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.PersistenceException;
import javax.sql.DataSource;
/**
* Helper to lookup a DataSource from JNDI.
*/
class JndiDataSourceLookup {
/**
* Return the DataSource by JNDI lookup.
* <p>
* If name is null the 'default' dataSource is returned.
* </p>
*/
public DataSource lookup(String jndiName) {
try {
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup(jndiName);
if (ds == null) {
throw new PersistenceException("JNDI DataSource [" + jndiName + "] not found?");
}
return ds;
} catch (NamingException ex) {
throw new PersistenceException(ex);
}
}
}
@@ -524,7 +524,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
}
if (result instanceof BeanList) {
OrderBy<T> orderBy = query.getOrderBy();
if (orderBy != null) {
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());
}
@@ -543,7 +543,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
@Override
public List<T> beanCacheHits() {
OrderBy<T> orderBy = query.getOrderBy();
if (orderBy != null) {
if (orderBy != null && !orderBy.isEmpty()) {
beanDescriptor.sort(cacheBeans, orderBy.toStringFormat());
}
return cacheBeans;
@@ -552,7 +552,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
@Override
public <K> Map<K, T> beanCacheHitsAsMap() {
OrderBy<T> orderBy = query.getOrderBy();
if (orderBy != null) {
if (orderBy != null && !orderBy.isEmpty()) {
beanDescriptor.sort(cacheBeans, orderBy.toStringFormat());
}
return cacheBeansToMap();
@@ -91,7 +91,7 @@ public class BootupClasses implements Predicate<Class<?>> {
public void runServerConfigStartup(DatabaseConfig config) {
for (Class<?> cls : serverConfigStartupCandidates) {
try {
ServerConfigStartup newInstance = (ServerConfigStartup) cls.newInstance();
ServerConfigStartup newInstance = (ServerConfigStartup) cls.getDeclaredConstructor().newInstance();
newInstance.onStart(config);
} catch (Exception e) {
// assume that the desired behavior is to fail - add your own try catch if needed
@@ -28,7 +28,7 @@ abstract class BaseCollectionHelp<T> implements BeanCollectionHelp<T> {
}
@Override
public void setLoader(BeanCollectionLoader loader) {
public final void setLoader(BeanCollectionLoader loader) {
this.loader = loader;
}
@@ -43,7 +43,7 @@ abstract class BaseCollectionHelp<T> implements BeanCollectionHelp<T> {
@SuppressWarnings("rawtypes")
@Override
public Collection underlying(Object value) {
public final Collection underlying(Object value) {
if (value instanceof BeanCollection) {
return ((BeanCollection)value).getActualDetails();
} else {
@@ -51,7 +51,7 @@ abstract class BaseCollectionHelp<T> implements BeanCollectionHelp<T> {
}
}
void jsonWriteCollection(SpiJsonWriter ctx, String name, Collection<?> list) throws IOException {
final void jsonWriteCollection(SpiJsonWriter ctx, String name, Collection<?> list) throws IOException {
if (!list.isEmpty() || ctx.isIncludeEmpty()) {
ctx.beginAssocMany(name);
for (Object bean : list) {
@@ -47,6 +47,11 @@ public interface BeanCollectionHelp<T> extends CQueryCollectionAdd<T> {
*/
BeanCollection<T> createEmpty(EntityBean bean);
/**
* Create and return an empty 'vanilla' collection that does not support lazy loading.
*/
Object createEmptyReference();
/**
* Add a bean to the List Set or Map.
*/
@@ -86,7 +86,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
private final ConcurrentHashMap<String, ElPropertyDeploy> elDeployCache = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, ElComparator<T>> comparatorCache = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, STreeProperty> dynamicProperty = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Map<String,String>> pathMaps = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Map<String, String>> pathMaps = new ConcurrentHashMap<>();
private final Map<String, SpiRawSql> namedRawSql;
private final Map<String, String> namedQuery;
@@ -1765,6 +1765,14 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
return createEntityBean(false);
}
@Override
public EntityBean createEntityBean2(boolean readOnlyNoIntercept) {
if (readOnlyNoIntercept) {
return (EntityBean) prototypeEntityBean._ebean_newInstanceReadOnly();
}
return createEntityBean(false);
}
/**
* Create an entity bean for JSON marshalling (which differs for the element collection case).
*/
@@ -2879,7 +2887,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
for (BeanPropertyAssocMany<?> many : propertiesManySave) {
if (ebi.isLoadedProperty(many.propertyIndex())) {
final Object value = many.getValue(bean);
if (value instanceof BeanCollection && ((BeanCollection<?>)value).hasModifications() || value != null) {
if (value instanceof BeanCollection && ((BeanCollection<?>) value).hasModifications() || value != null) {
return true;
}
}
@@ -22,7 +22,7 @@ class BeanDescriptorElementEmbedded<T> extends BeanDescriptorElement<T> {
BeanDescriptorElementEmbedded(BeanDescriptorMap owner, DeployBeanDescriptor<T> deploy, ElementHelp elementHelp) {
super(owner, deploy, elementHelp);
try {
this.prototype = (EntityBean) beanType.newInstance();
this.prototype = (EntityBean) beanType.getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new IllegalStateException("Unable to create entity bean prototype for "+beanType);
}
@@ -11,6 +11,7 @@ import io.ebeaninternal.api.json.SpiJsonWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@@ -27,8 +28,7 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
}
@Override
public BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) {
public final BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) {
if (bc instanceof BeanList<?>) {
BeanList<?> bl = (BeanList<?>) bc;
if (bl.getActualList() == null) {
@@ -42,12 +42,17 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
}
@Override
public BeanCollection<T> createEmptyNoParent() {
public final Object createEmptyReference() {
return Collections.EMPTY_LIST;
}
@Override
public final BeanCollection<T> createEmptyNoParent() {
return new BeanList<>();
}
@Override
public BeanCollection<T> createEmpty(EntityBean parentBean) {
public final BeanCollection<T> createEmpty(EntityBean parentBean) {
BeanList<T> beanList = new BeanList<>(loader, parentBean, propertyName);
if (many != null) {
beanList.setModifyListening(many.modifyListenMode());
@@ -56,29 +61,23 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
}
@Override
public BeanCollection<T> createReference(EntityBean parentBean) {
public final BeanCollection<T> createReference(EntityBean parentBean) {
BeanList<T> beanList = new BeanList<>(loader, parentBean, propertyName);
beanList.setModifyListening(many.modifyListenMode());
return beanList;
}
@Override
public void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
public final void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
BeanList<?> newBeanList = (BeanList<?>) server.findList(query, t);
refresh(newBeanList, parentBean);
}
@Override
public void refresh(BeanCollection<?> bc, EntityBean parentBean) {
public final void refresh(BeanCollection<?> bc, EntityBean parentBean) {
BeanList<?> newBeanList = (BeanList<?>) bc;
List<?> currentList = (List<?>) many.getValue(parentBean);
newBeanList.setModifyListening(many.modifyListenMode());
if (currentList == null) {
// the currentList is null? Not really expecting this...
many.setValue(parentBean, newBeanList);
@@ -96,8 +95,7 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
}
@Override
public void jsonWrite(SpiJsonWriter ctx, String name, Object collection, boolean explicitInclude) throws IOException {
public final void jsonWrite(SpiJsonWriter ctx, String name, Object collection, boolean explicitInclude) throws IOException {
List<?> list;
if (collection instanceof BeanCollection<?>) {
BeanList<?> beanList = (BeanList<?>) collection;
@@ -114,7 +112,6 @@ public class BeanListHelp<T> extends BaseCollectionHelp<T> {
} else {
list = (List<?>) collection;
}
jsonWriteCollection(ctx, name, list);
}
@@ -10,6 +10,7 @@ import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.json.SpiJsonWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
@@ -36,13 +37,11 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
@Override
@SuppressWarnings("unchecked")
public BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) {
public final BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) {
if (mapKey == null) {
mapKey = many.mapKey();
}
BeanProperty beanProp = targetDescriptor.beanProperty(mapKey);
if (bc instanceof BeanMap<?, ?>) {
BeanMap<Object, Object> bm = (BeanMap<Object, Object>) bc;
Map<Object, Object> actualMap = bm.getActualMap();
@@ -57,10 +56,9 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
}
}
static class Adder implements BeanCollectionAdd {
static final class Adder implements BeanCollectionAdd {
private final BeanProperty beanProperty;
private final Map<Object, Object> map;
Adder(BeanProperty beanProperty, Map<Object, Object> map) {
@@ -76,13 +74,17 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
}
@Override
public BeanCollection<T> createEmptyNoParent() {
public final Object createEmptyReference() {
return Collections.EMPTY_MAP;
}
@Override
public final BeanCollection<T> createEmptyNoParent() {
return new BeanMap<>();
}
@Override
public BeanCollection<T> createEmpty(EntityBean ownerBean) {
public final BeanCollection<T> createEmpty(EntityBean ownerBean) {
BeanMap<?, T> beanMap = new BeanMap<>(loader, ownerBean, propertyName);
if (many != null) {
beanMap.setModifyListening(many.modifyListenMode());
@@ -92,7 +94,6 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
@Override
public void add(BeanCollection<?> collection, EntityBean bean, boolean withCheck) {
if (bean == null) {
((BeanMap<?, ?>) collection).internalPutNull();
} else {
@@ -104,8 +105,7 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public BeanCollection<T> createReference(EntityBean parentBean) {
public final BeanCollection<T> createReference(EntityBean parentBean) {
BeanMap beanMap = new BeanMap(loader, parentBean, propertyName);
if (many != null) {
beanMap.setModifyListening(many.modifyListenMode());
@@ -114,14 +114,13 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
}
@Override
public void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
public final void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
BeanMap<?, ?> newBeanMap = (BeanMap<?, ?>) server.findMap(query, t);
refresh(newBeanMap, parentBean);
}
@Override
public void refresh(BeanCollection<?> bc, EntityBean parentBean) {
public final void refresh(BeanCollection<?> bc, EntityBean parentBean) {
BeanMap<?, ?> newBeanMap = (BeanMap<?, ?>) bc;
Map<?, ?> current = (Map<?, ?>) many.getValue(parentBean);
@@ -143,8 +142,7 @@ public class BeanMapHelp<T> extends BaseCollectionHelp<T> {
}
@Override
public void jsonWrite(SpiJsonWriter ctx, String name, Object collection, boolean explicitInclude) throws IOException {
public final void jsonWrite(SpiJsonWriter ctx, String name, Object collection, boolean explicitInclude) throws IOException {
Map<?, ?> map;
if (collection instanceof BeanCollection<?>) {
BeanMap<?, ?> bc = (BeanMap<?, ?>) collection;
@@ -15,7 +15,6 @@ public final class BeanMapHelpElement<T> extends BeanMapHelp<T> {
public void add(BeanCollection<?> collection, EntityBean bean, boolean withCheck) {
Object key = bean._ebean_getField(0);
Object val = bean._ebean_getField(1);
BeanMap<?, ?> map = ((BeanMap<?, ?>) collection);
if (withCheck) {
map.internalPutWithCheck(key, val);
@@ -601,6 +601,11 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
return mapKey;
}
@Override
public void createEmptyReference(EntityBean localBean) {
setValue(localBean, help.createEmptyReference());
}
@Override
public BeanCollection<?> createReference(EntityBean localBean, boolean forceNewReference) {
return forceNewReference ? createReference(localBean) : createReferenceIfNull(localBean);
@@ -10,6 +10,7 @@ import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.json.SpiJsonWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -33,7 +34,7 @@ public class BeanSetHelp<T> extends BaseCollectionHelp<T> {
}
@Override
public BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) {
public final BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) {
if (bc instanceof BeanSet<?>) {
BeanSet<?> beanSet = (BeanSet<?>) bc;
if (beanSet.getActualSet() == null) {
@@ -46,12 +47,17 @@ public class BeanSetHelp<T> extends BaseCollectionHelp<T> {
}
@Override
public BeanCollection<T> createEmptyNoParent() {
public final Object createEmptyReference() {
return Collections.EMPTY_SET;
}
@Override
public final BeanCollection<T> createEmptyNoParent() {
return new BeanSet<>();
}
@Override
public BeanCollection<T> createEmpty(EntityBean ownerBean) {
public final BeanCollection<T> createEmpty(EntityBean ownerBean) {
BeanSet<T> beanSet = new BeanSet<>(loader, ownerBean, propertyName);
if (many != null) {
beanSet.setModifyListening(many.modifyListenMode());
@@ -60,20 +66,20 @@ public class BeanSetHelp<T> extends BaseCollectionHelp<T> {
}
@Override
public BeanCollection<T> createReference(EntityBean parentBean) {
public final BeanCollection<T> createReference(EntityBean parentBean) {
BeanSet<T> beanSet = new BeanSet<>(loader, parentBean, propertyName);
beanSet.setModifyListening(many.modifyListenMode());
return beanSet;
}
@Override
public void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
public final void refresh(SpiEbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
BeanSet<?> newBeanSet = (BeanSet<?>) server.findSet(query, t);
refresh(newBeanSet, parentBean);
}
@Override
public void refresh(BeanCollection<?> bc, EntityBean parentBean) {
public final void refresh(BeanCollection<?> bc, EntityBean parentBean) {
BeanSet<?> newBeanSet = (BeanSet<?>) bc;
Set<?> current = (Set<?>) many.getValue(parentBean);
newBeanSet.setModifyListening(many.modifyListenMode());
@@ -94,7 +100,7 @@ public class BeanSetHelp<T> extends BaseCollectionHelp<T> {
}
@Override
public void jsonWrite(SpiJsonWriter ctx, String name, Object collection, boolean explicitInclude) throws IOException {
public final void jsonWrite(SpiJsonWriter ctx, String name, Object collection, boolean explicitInclude) throws IOException {
Set<?> set;
if (collection instanceof BeanCollection<?>) {
BeanSet<?> bc = (BeanSet<?>) collection;
@@ -119,6 +119,11 @@ public interface DbSqlContext {
*/
boolean isIncludeSoftDelete();
/**
* Return the count of history table AS OF predicates added via joins.
*/
int asOfTableCount();
/**
* Return true if the query is a 'asDraft' query.
*/
@@ -2,6 +2,7 @@ package io.ebeaninternal.server.deploy;
import io.ebean.bean.EntityBean;
import io.ebean.bean.EntityBeanIntercept;
import io.ebean.bean.InterceptReadWrite;
final class ElementEntityBean implements EntityBean {
@@ -13,7 +14,7 @@ final class ElementEntityBean implements EntityBean {
ElementEntityBean(String[] properties) {
this.properties = properties;
this.intercept = new EntityBeanIntercept(this);
this.intercept = new InterceptReadWrite(this);
}
@Override
@@ -219,9 +219,7 @@ public class DeployBeanProperty {
return (AnnotationUtil.has(field, WhenCreated.class)
|| AnnotationUtil.has(field, WhenModified.class)
|| AnnotationUtil.has(field, WhoModified.class)
|| AnnotationUtil.has(field, WhoCreated.class)
|| AnnotationUtil.has(field, UpdatedTimestamp.class)
|| AnnotationUtil.has(field, CreatedTimestamp.class));
|| AnnotationUtil.has(field, WhoCreated.class));
}
public String getFullBeanName() {
@@ -1,38 +1,7 @@
package io.ebeaninternal.server.deploy.parse;
import io.ebean.annotation.Aggregation;
import io.ebean.annotation.CreatedTimestamp;
import io.ebean.annotation.DbArray;
import io.ebean.annotation.DbComment;
import io.ebean.annotation.DbDefault;
import io.ebean.annotation.DbJson;
import io.ebean.annotation.DbJsonB;
import io.ebean.annotation.DbMap;
import io.ebean.annotation.DbMigration;
import io.ebean.annotation.DocCode;
import io.ebean.annotation.DocEmbedded;
import io.ebean.annotation.DocProperty;
import io.ebean.annotation.DocSortable;
import io.ebean.annotation.Draft;
import io.ebean.annotation.DraftDirty;
import io.ebean.annotation.DraftOnly;
import io.ebean.annotation.DraftReset;
import io.ebean.annotation.Encrypted;
import io.ebean.annotation.Expose;
import io.ebean.annotation.Formula;
import io.ebean.annotation.HistoryExclude;
import io.ebean.annotation.Identity;
import io.ebean.annotation.Index;
import io.ebean.annotation.JsonIgnore;
import io.ebean.annotation.Length;
import io.ebean.annotation.SoftDelete;
import io.ebean.annotation.TenantId;
import io.ebean.annotation.UnmappedJson;
import io.ebean.annotation.UpdatedTimestamp;
import io.ebean.annotation.WhenCreated;
import io.ebean.annotation.WhenModified;
import io.ebean.annotation.WhoCreated;
import io.ebean.annotation.WhoModified;
import io.ebean.annotation.*;
import io.ebean.config.EncryptDeploy;
import io.ebean.config.EncryptDeploy.Mode;
import io.ebean.config.dbplatform.DbEncrypt;
@@ -51,24 +20,7 @@ import io.ebeaninternal.server.type.ScalarTypeBytesBase;
import io.ebeaninternal.server.type.ScalarTypeBytesEncrypted;
import io.ebeaninternal.server.type.ScalarTypeEncryptedWrapper;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PersistenceException;
import javax.persistence.SequenceGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.Version;
import javax.persistence.*;
import java.sql.Types;
import java.util.Set;
import java.util.UUID;
@@ -339,10 +291,10 @@ final class AnnotationFields extends AnnotationParser {
}
private void initWhen(DeployBeanProperty prop) {
if (has(prop, WhenCreated.class) || has(prop, CreatedTimestamp.class)) {
if (has(prop, WhenCreated.class)) {
generatedPropFactory.setInsertTimestamp(prop);
}
if (has(prop, WhenModified.class) || has(prop, UpdatedTimestamp.class)) {
if (has(prop, WhenModified.class)) {
generatedPropFactory.setUpdateTimestamp(prop);
}
}
@@ -7,12 +7,14 @@ import javax.persistence.DiscriminatorType;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
/**
* Represents a node in the Inheritance tree.
* Holds information regarding Super Subclass support.
*/
public final class DeployInheritInfo {
public final class DeployInheritInfo implements Comparable<DeployInheritInfo> {
/**
* the default discriminator column according to the JPA 1.0 spec.
@@ -27,7 +29,7 @@ public final class DeployInheritInfo {
private String columnDefn;
private final Class<?> type;
private Class<?> parent;
private final ArrayList<DeployInheritInfo> children = new ArrayList<>();
private final Set<DeployInheritInfo> children = new TreeSet<>();
/**
* Create for a given type.
@@ -74,7 +76,7 @@ public final class DeployInheritInfo {
/**
* Return the child nodes.
*/
public List<DeployInheritInfo> children() {
public Set<DeployInheritInfo> children() {
return children;
}
@@ -251,7 +253,18 @@ public final class DeployInheritInfo {
@Override
public String toString() {
return "InheritInfo[" + type.getName() + "]" + " root[" + parent.getName() + "]" + " disValue[" + discriminatorStringValue + "]";
String root = parent == null ? null : parent.getName();
String name = type == null ? null : type.getName();
return "InheritInfo[" + name + "]" + " root[" + root + "]" + " disValue[" + discriminatorStringValue + "]";
}
@Override
public int compareTo(DeployInheritInfo other) {
if (other == this) {
return 0;
} else {
return type.getName().compareTo(other.type.getName());
}
}
}
@@ -100,22 +100,11 @@ public final class DefaultBackgroundExecutor implements SpiBackgroundExecutor {
return pool.submit(wrap(task));
}
@Override
public void execute(Runnable task) {
submit(logExceptions(task));
}
@Override
public void executePeriodically(Runnable task, long delay, TimeUnit unit) {
schedulePool.scheduleWithFixedDelay(wrap(logExceptions(task)), delay, delay, unit);
}
@Override
public void executePeriodically(Runnable task, long initialDelay, long delay, TimeUnit unit) {
schedulePool.scheduleWithFixedDelay(wrap(logExceptions(task)), initialDelay, delay, unit);
}
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long initialDelay, long delay, TimeUnit unit) {
return schedulePool.scheduleWithFixedDelay(wrap(logExceptions(task)), initialDelay, delay, unit);
@@ -1,15 +1,15 @@
package io.ebeaninternal.server.persist;
import io.ebean.EbeanServer;
import io.ebean.Database;
import io.ebean.Transaction;
import io.ebean.event.BeanDeleteIdRequest;
import io.ebeaninternal.api.SpiEbeanServer;
final class DeleteIdRequest implements BeanDeleteIdRequest {
private final EbeanServer server;
private final SpiEbeanServer server;
private final Transaction transaction;
private Class<?> beanType;
private final Class<?> beanType;
private Object id;
DeleteIdRequest(SpiEbeanServer server, Transaction transaction, Class<?> beanType, Object id) {
@@ -24,7 +24,7 @@ final class DeleteIdRequest implements BeanDeleteIdRequest {
}
@Override
public EbeanServer getEbeanServer() {
public Database database() {
return server;
}

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