Compare commits

...
Author SHA1 Message Date
rob bygrave f8e4ce6b4c [maven-release-plugin] prepare release ebean-test-12.5.1 2020-10-19 09:44:07 +13:00
rob bygrave cce496016d [maven-release-plugin] prepare for next development iteration 2020-10-19 09:38:53 +13:00
rob bygrave 2c4d5dc304 [maven-release-plugin] prepare release ebean-querybean-12.5.1 2020-10-19 09:38:42 +13:00
rob bygrave 1c981130b6 [maven-release-plugin] prepare for next development iteration 2020-10-19 09:34:13 +13:00
rob bygrave c18d1fa288 [maven-release-plugin] prepare release ebean-externalmapping-xml-12.5.1 2020-10-19 09:34:01 +13:00
rob bygrave 5287d93a58 [maven-release-plugin] prepare for next development iteration 2020-10-19 09:30:52 +13:00
rob bygrave 6e6055fb84 [maven-release-plugin] prepare release ebean-autotune-12.5.1 2020-10-19 09:30:40 +13:00
rob bygrave c2ea8b3d56 Prepare manual release of autotune, externalmapping-xml, querybean and test modules 2020-10-19 09:29:54 +13:00
rob bygrave 5885d724c4 Prepare manual release of autotune, externalmapping-xml, querybean and test modules 2020-10-19 09:27:58 +13:00
rob bygrave 90d028640d No effective change - bump maven tiles plugin to 2.18 2020-10-16 18:11:01 +13:00
rob bygrave b8d92f1846 [maven-release-plugin] prepare for next development iteration 2020-10-16 16:08:33 +13:00
rob bygrave e41d2eed7f [maven-release-plugin] prepare release ebean-parent-12.5.1 2020-10-16 16:08:22 +13:00
rob bygrave 8c7a84be9c No effective change - tidy tests that create unregistered Database instances (shutdown) 2020-10-16 16:04:52 +13:00
rob bygrave 63116f25ec Bump ebean-datasource to 6.1 2020-10-16 15:39:29 +13:00
rob bygrave eac05571c8 Update tests for kotlin-querybean-generator to use junit5 2020-10-16 15:38:52 +13:00
rob bygrave a6ad043142 #2082 - Test scope for kotlin-querybean-generator ebean-querybean dependency 2020-10-16 12:23:59 +13:00
SnōwballandGitHub bcc8040afe Scalar type querybeans generics error (#2082)
* Add failing test case for generic querybeans

Types with generics arguments have not been processed correctly, they
will lose their generics. This is not critical in Java, as the language
has to be backwards compatible with Java 1.4, but will still become
highlighted as a warning in all common IDEs.

In Kotlin however, it's not a warning but a compile error.

* Fix problem with generics in scalar type arg

This fixes the issue introduced with ScalarType aware querybeans.
2020-10-16 09:57:32 +13:00
rob bygrave ee73fd47d5 No effective change - tidy javadoc 2020-10-16 00:53:55 +13:00
rob bygrave 064b3ceaa4 #2080 - Refactor convert from sychronized to ReentrantLock
DatabaseFactory, DbPrimary, ScalarTypeArrayList etc
2020-10-16 00:46:13 +13:00
rob bygrave 54ada6e07b #2080 - ebean-autotune - Refactor convert from sychronized to ReentrantLock 2020-10-16 00:28:23 +13:00
Rob BygraveandGitHub 14181932ec Refactor synchronized to ReentrantLock (#2081) 2020-10-16 00:20:42 +13:00
rob bygrave 0faa6a8efd Reset back pom after manual release of ebean-autotune 2020-10-16 00:16:21 +13:00
rob bygrave f94eb9b75e [maven-release-plugin] prepare for next development iteration 2020-10-16 00:03:55 +13:00
rob bygrave 817436b00d [maven-release-plugin] prepare release ebean-autotune-12.5.0 2020-10-16 00:03:42 +13:00
rob bygrave a089a36f9d Prepare manual release of ebean-autotune 2020-10-16 00:03:07 +13:00
rob bygrave 1f1868fdd3 #2079 - Refactor to make Jackson core an optional dependency 2020-10-15 22:04:36 +13:00
rob bygrave 8ac49e537d #2078 - Bump to avaje-config 1.1 - makes snakeyaml dependency optional 2020-10-15 16:51:48 +13:00
rob bygrave 133cf95c6d Reset poms for externalmapping-xml querybean and ebean-test modules after manual release take 2 2020-10-14 00:00:17 +13:00
rob bygrave 2caf4bcccd [maven-release-plugin] prepare for next development iteration 2020-10-13 23:29:19 +13:00
rob bygrave e8f0e2f4bf [maven-release-plugin] prepare release ebean-test-12.5.0 2020-10-13 23:29:05 +13:00
rob bygrave 8bde42fb16 [maven-release-plugin] prepare for next development iteration 2020-10-13 23:25:06 +13:00
rob bygrave 2bb1e40c44 [maven-release-plugin] prepare release ebean-querybean-12.5.0 2020-10-13 23:24:52 +13:00
rob bygrave 1ac1e19db0 Manually release ebean-test and ebean-querybean module 12.5.0 by itself
Take 2 with correct groupId
2020-10-13 23:23:58 +13:00
rob bygrave 85a0eb0afb [maven-release-plugin] prepare for next development iteration 2020-10-13 23:16:42 +13:00
rob bygrave a6470b48ff [maven-release-plugin] prepare release ebean-externalmapping-xml-12.5.0 2020-10-13 23:16:30 +13:00
rob bygrave ebde00a137 Manually release ebean-externalmapping-xml module 12.5.0 by itself
Take 2 with correct groupId
2020-10-13 23:16:07 +13:00
rob bygrave bb6425a0c1 Manually release ebean-externalmapping-xml module 12.5.0 by itself
Take 2 with correct groupId
2020-10-13 23:15:00 +13:00
rob bygrave abff32c418 Manually release ebean-externalmapping-xml module 12.5.0 by itself
Take 2 with correct groupId
2020-10-13 23:13:58 +13:00
75f26b1f62 Bump junit from 4.12 to 4.13.1 in /ebean-test (#2077)
Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-10-13 11:51:36 +13:00
rob bygrave fc4ee15a2a Reset poms for externalmapping-xml querybean and ebean-test modules after manual release 2020-10-13 11:45:46 +13:00
rob bygrave 6cb21f3e73 [maven-release-plugin] prepare for next development iteration 2020-10-13 11:17:39 +13:00
rob bygrave 18663c8983 [maven-release-plugin] prepare release ebean-externalmapping-xml-12.5.0 2020-10-13 11:17:27 +13:00
rob bygrave 0d9094984a Manually release ebean-externalmapping-xml module 12.5.0 by itself 2020-10-13 11:16:52 +13:00
rob bygrave bd05f2c2ba [maven-release-plugin] prepare for next development iteration 2020-10-13 11:09:06 +13:00
rob bygrave 1cc167341b [maven-release-plugin] prepare release ebean-test-12.5.0 2020-10-13 11:08:54 +13:00
rob bygrave 4a313245b5 Manually release ebean-test module 12.5.0 by itself 2020-10-13 11:08:21 +13:00
rob bygrave 8744435eb6 [maven-release-plugin] prepare for next development iteration 2020-10-13 11:04:13 +13:00
rob bygrave dfdcdcf321 [maven-release-plugin] prepare release ebean-querybean-12.5.0 2020-10-13 11:04:02 +13:00
rob bygrave e203d4d191 Try to release ebean-querybean module 12.5.0 by itself 2020-10-13 11:03:18 +13:00
rob bygrave d4c345b989 Try to release ebean-querybean module 12.5.0 by itself
For some unknown reason this module is missing from central after the release.
2020-10-13 11:01:16 +13:00
rob bygrave 541271efb7 Bump tiles etc to newly released 12.5.0 2020-10-12 23:42:08 +13:00
rob bygrave 489781f89d [maven-release-plugin] prepare for next development iteration 2020-10-12 22:35:21 +13:00
rob bygrave 9180289551 [maven-release-plugin] prepare release ebean-parent-12.5.0 2020-10-12 22:35:09 +13:00
rob bygrave b15958e766 Bump to 12.5.0-SNAPSHOT 2020-10-12 17:33:30 +13:00
rob bygrave 49c64c1eb5 Add Automatic-Module-Name entries MANIFEST.MF 2020-10-12 16:45:57 +13:00
rob bygrave a53168bd00 Add Automatic-Module-Name entries MANIFEST.MF 2020-10-12 16:21:29 +13:00
rob bygrave c783f26340 #2076 - Remove JAXB as dependency of ebean-api
- Move JAXB detection to ebean-ddlgen
- JAXB as test dependency of ebean-core
2020-10-12 16:10:07 +13:00
rob bygrave 050a3e2368 #2076 - Refactor DbDefaultValue internals - remove dependency on javax.xml.bind.DatatypeConverter for verify of value 2020-10-12 15:37:39 +13:00
rob bygrave 49b1bd54c3 #2075 - Refactor external mapping (i.e. named queries from ebean.xml etc) - extract api and separate module 2020-10-12 14:54:25 +13:00
rob bygrave f57db28f1c #2075 - Refactor external mapping api and use ServiceLoader 2020-10-10 17:12:13 +13:00
rob bygrave b22bffe770 #2074 - Refactor extract ebean-ddlgen module. In future this module would expected to be a test only dependency 2020-10-10 12:28:02 +13:00
rob bygrave b9047bf280 #2073 - Refactor internals for DdlGenerator use use ServiceLoader 2020-10-09 22:58:47 +13:00
rob bygrave a6f5ab8074 Refactor internals - move DbOffline, split VisitAllUsing into VisitProperties 2020-10-09 18:02:40 +13:00
rob bygrave 60becb6346 #2072 - Extract ebean-api module - NB: this includes moving ShutdownManager and small adjustment to DocStore/Elastic SPI 2020-10-09 17:12:27 +13:00
rob bygrave 11839aca5e Refactor to ServiceLoad MetricFactory implementation 2020-10-09 14:17:21 +13:00
rob bygrave 86aed458dd Move ShutdownManager into io.ebean.event 2020-10-09 14:13:52 +13:00
rob bygrave fa4130ba8e Fix travis testing for ebean-querybean module 2020-10-09 10:29:35 +13:00
rob bygrave 77995fda0a #2065 - Fix missed tests for - Refactor SQL generation - remove excess whitespace 2020-10-09 10:17:23 +13:00
rob bygrave 5112253d19 Fix for travis build of ebean-test module 2020-10-09 10:04:15 +13:00
rob bygrave 89c3e23410 Fix for travis build of ebean-autotune module tests 2020-10-09 09:50:43 +13:00
rob bygrave b8858d91f0 Modify Autotune module tests with surefire output
Also add to ebean-bom
2020-10-09 09:37:26 +13:00
rob bygrave 46a42f4ef7 Modify Autotune tests use an explicit datasource 2020-10-09 09:13:33 +13:00
rob bygrave 42f9c8fd59 Modify Autotune tests use an explicit datasource 2020-10-09 08:47:08 +13:00
rob bygrave 6560a46b2d Drop version of maven plugin due to travis cache 2020-10-09 01:01:45 +13:00
rob bygrave 4da86481e8 #2071 - Add ebean-bom module 2020-10-09 00:40:24 +13:00
rob bygrave bde133ef79 #2070 - Add top level ebean module 2020-10-09 00:31:19 +13:00
rob bygrave 8780ac0902 #2070 - Rename ebean module to ebean-core, add top level ebean module 2020-10-09 00:26:37 +13:00
rob bygrave 038db79737 #2069 - Add ebean-querybean, querybean-generator and kotlin-querybean-generator as modules 2020-10-09 00:02:09 +13:00
rob bygrave bc055fea25 #2068 - Add ebean-test as module 2020-10-08 23:48:19 +13:00
rob bygrave ab283efed7 Use ebean-parent and inherit version 2020-10-08 23:46:36 +13:00
rob bygrave d113ddc525 #2067 - Extract ebean-autotune into separate module 2020-10-08 23:34:56 +13:00
Rob BygraveandGitHub 7c36439daf Refactor move into ebean-core directory (#2066) 2020-10-08 21:31:18 +13:00
rob bygrave 7193b035b2 #2062 - Update enhancement agent to use ASM 9 2020-10-08 17:23:16 +13:00
Rob BygraveandGitHub de22b7bf27 Refactor SQL generation - remove excess whitespace (double spaces before where, join and order by) (#2065) 2020-10-07 21:28:33 +13:00
rob bygrave 694518db0a [maven-release-plugin] prepare for next development iteration 2020-10-07 20:43:11 +13:00
rob bygrave b721017dd5 [maven-release-plugin] prepare release ebean-12.4.2 2020-10-07 20:42:59 +13:00
rob bygrave de5346437f Bump maven plugin 2020-10-07 20:39:53 +13:00
rob bygrave 1669649706 #2064 - Generated sql is missing a space near to the "dtype and softdelete" join-conditions when "fetch join" is used 2020-10-07 17:12:51 +13:00
rob bygrave 3f816c49c9 #2063 - Updating bean - L2 Bean cache update + l2 cache update on "Many Ids" when they have not change - can lead to race 2020-10-07 15:26:31 +13:00
rob bygrave e31ae49bc5 #2063 - Failing test for - Updating bean - L2 Bean cache update + l2 cache update on "Many Ids" when they have not change - can lead to race 2020-10-07 15:12:13 +13:00
rob bygrave bdf8381518 Update test only - TestAttributeConverter 2020-10-07 14:16:55 +13:00
rob bygrave 7eb185ce9b Refactor remove message.properties resource in favour of simple error messages and logs 2020-09-24 23:40:05 +12:00
rob bygrave f175b198e6 Merge branch 'FOCONIS-test_beancache_wrong_result' 2020-09-24 22:15:09 +12:00
rob bygrave de734665cd #2061 - Fix for L2 bean cache loaded using lazy loading on mutated partially loaded bean
The fix is when the property is dirty (mutated) put the original value into the cache entry.
2020-09-24 22:14:48 +12:00
Jonas Pöhler (JPo) c5eb6fa034 ADD: failing testcase for wrong bean caching
Signed-off-by: Jonas Pöhler (JPo) <jonas.poehler@foconis.de>
2020-09-23 15:19:59 +02:00
rob bygrave 5706c73272 [maven-release-plugin] prepare for next development iteration 2020-09-17 23:59:24 +12:00
rob bygrave c5a899c0e8 [maven-release-plugin] prepare release ebean-12.4.1 2020-09-17 23:59:12 +12:00
rob bygrave 50eb7d78fb Bump to 12.4.1-SNAPSHOT 2020-09-17 23:46:46 +12:00
rob bygrave 13e805b31c No effective change - organise imports on generated EQLLexer and EQLParser 2020-09-17 23:03:56 +12:00
rob bygrave 3531db0e53 #2060 - Bump ANTLR to 4.8-1 (from 4.7.2) and add support for "leOrNull" and "geOrNull" expressions from #2059 2020-09-17 23:01:09 +12:00
rob bygrave 87243a871d No effective change - tidy OrmQueryRequest 2020-09-17 22:46:22 +12:00
rob bygrave f2159fed71 #2058 - .findVersionsBetween() for PG and MySql... should use inclusive/exclusive and it is instead is exclusive/exclusive 2020-09-17 22:38:42 +12:00
rob bygrave 740fd63f35 #2059 - ENH: Add convenience expressions leOrNull() and geOrNull() ... [ property >= value or property is null ] 2020-09-17 22:23:54 +12:00
rob bygrave 2ad99794ea No effective change - tidy whitespace 2020-09-14 21:05:38 +12:00
rob bygrave 775f184450 No effective change - tidy whitespace from SaveManyBeans and BeanPropertyAssocMany 2020-09-14 20:57:21 +12:00
rob bygrave 4492a87a3f No effective change - tidy DefaultTypeFactory 2020-09-14 20:39:22 +12:00
rob bygrave 18d5d01d48 #2049 - Tidy after ServerConfig -> DatabaseConfig 2020-09-14 20:35:20 +12:00
Rob BygraveandGitHub 90b1b88be6 Update CsvCallback API to use Database instead of EbeanServer (#2010)
* Update CsvCallback API to use Database instead of EbeanServer
2020-09-14 18:33:12 +12:00
Rob BygraveandGitHub 6839f869f5 #2049 - Migrate to DatabaseConfig from ServerConfig (#2057) 2020-09-14 18:30:51 +12:00
rob bygrave 488762957a [maven-release-plugin] prepare for next development iteration 2020-09-08 13:28:26 +12:00
rob bygrave ec016cab17 [maven-release-plugin] prepare release ebean-12.3.9 2020-09-08 13:28:15 +12:00
rob bygrave 7c28f01923 Bump parent pom 2020-09-08 13:26:37 +12:00
Rob BygraveandGitHub 54da22eee6 Merge pull request #2056 from ebean-orm/feature/DbContext
#2055 - Refactor internals - Extract DbContext from Ebean and hold Database rather than EbeanServer
2020-09-08 09:33:10 +12:00
rob bygrave 6772b6e87e #2055 - Refactor internals - Extract DbContext from Ebean and hold Database rather than EbeanServer 2020-09-08 09:29:06 +12:00
rob bygrave 9856ebd540 #2055 - Refactor internals - Extract DbContext from Ebean and hold Database rather than EbeanServer 2020-09-08 09:25:32 +12:00
rob bygrave f96ac6e6fe No effective change - tidy Ebean, EbeanVersion 2020-09-07 21:55:21 +12:00
rob bygrave 4c5618b04b #2054 - Invalid SQL with History findVersions() on bean with @EmbeddedId - ... ORDER BY T0.NULL[*] ... 2020-09-07 18:25:25 +12:00
rob bygrave a77de9e5e6 No effective change - trim whitespace for IdBinderEmbedded 2020-09-07 18:00:12 +12:00
rob bygrave da29330a2a #2053 - Refactor tidy StringHelper.replace replacing with just String.replace where possible 2020-09-04 18:04:10 +12:00
rob bygrave d0f9d4a9a6 #2053 - Refactor tidy StringHelper.replaceString 2020-09-04 17:42:09 +12:00
rob bygrave 61ee67ee41 #2053 - Refactor tidy StringHelper.replaceString 2020-09-04 17:36:10 +12:00
rob bygrave 3117acd2d7 #2053 - Refactor tidy StringHelper.delimitedToMap 2020-09-04 13:37:25 +12:00
rob bygrave 4cee41d8d6 #2053 - Refactor tidy StringHelper - replace replaceStringMulti() with removeNewLines() 2020-09-04 13:21:13 +12:00
rob bygrave f4a58938bd #2053 - Refactor tidy StringHelper - just tidy 2020-09-04 13:09:55 +12:00
rob bygrave 4ce84f694f #2053 - Refactor tidy internals - Clean up StringHelper 2020-09-04 13:04:14 +12:00
rob bygrave 8eb248b966 #2052 - Refactor tidy internals - Use String.replace() rather than literal pattern replaceAll() 2020-09-04 12:53:43 +12:00
rob bygrave c294d8e568 #2051 - Bump config dependency from io.avaje:config to io.avaje:avaje-config 2020-09-03 17:18:14 +12:00
rob bygrave e923316ce9 Change to use maven <optional>true</optional> rather than scope provided 2020-09-03 17:13:23 +12:00
rob bygrave f611068a03 #2050 - Refactor internals - remove dependency on java.beans 2020-09-03 14:45:27 +12:00
rob bygrave dd880ac09b #2044 - Using @AttributeOverrides when override nullable 2020-08-31 14:38:23 +12:00
rob bygrave dbe24a4041 [maven-release-plugin] prepare for next development iteration 2020-08-26 11:37:29 +12:00
rob bygrave 1f32dc2dc5 [maven-release-plugin] prepare release ebean-12.3.8 2020-08-26 11:37:17 +12:00
rob bygrave b2ce9db8a8 #2048 - IllegalStateException: No query cache enabled on __. Need explicit @Cache(enableQueryCache=true) ... when ebean.disableL2Cache=true l2 2020-08-26 11:33:23 +12:00
rob bygrave a626690918 #2044 - Using @AttributeOverrides also override length, scale and columnDefinition 2020-08-25 09:48:01 +12:00
rob bygrave 0d511d51a6 #2044 - Using @AttributeOverrides breaking generated SQL (when override nullable and no column name) 2020-08-25 09:22:15 +12:00
rob bygrave 854f467504 No effective change - update ddl review h2 2020-08-25 09:08:11 +12:00
rob bygrave d3cc393edc No effective change - update ddl review postgres 2020-08-25 09:04:21 +12:00
Rob BygraveandGitHub 002014f930 For #2038 - updated from 12.3.6 to 12.3.7 - NPE BeanDescriptor.findPropertyFromPath(BeanDescriptor.java:1965) (#2047)
* #2038 - lazy loading ToMany with path

* #2038 - Failing test for NPE BeanDescriptor.findPropertyFromPath(BeanDescriptor.java:1965)

* #2038 Refactor internals DbReadContext use BeanPropertyAssocMany
2020-08-24 18:40:36 +12:00
rob bygrave c8d352b0a8 Add a better error message for #2038 NPE at BeanDescriptor.java:1965 2020-08-05 16:44:45 +12:00
rob bygrave 3796f2b267 No effective change - organise imports on tests 2020-08-05 16:39:10 +12:00
peterko2017andGitHub 4ef5abceca Add STI Discrimination on Reference Associations (#2041)
* Update SqlTreeNodeBean#appendFromBaseTable to add
discriminator values to the join
* Update tests to reflect new generated SQL
2020-08-05 16:33:34 +12:00
rob bygrave 4eda4201de Javadoc only change for RawSql 2020-07-30 16:22:09 +12:00
rob bygrave 933aa30149 Javadoc only change - replace at sign and fix javadoc 2020-07-27 16:41:30 +12:00
rob bygrave 0c80b3078a #2037 - Refactor simplify TransactionCallback to lambda
- Move to use generic try catch exception
- Convert to lambda method calls
2020-07-24 13:19:56 +12:00
rob bygrave 7317847aa7 #2037 - Allow PostCommit transaction callback to recursively add another PostCommit callback 2020-07-24 13:16:18 +12:00
rob bygrave 444644f759 #2037 - Allow PostCommit transaction callback to recursively add another PostCommit callback 2020-07-24 13:16:00 +12:00
rob bygrave f704da641d No effective change - Modify test only adding extra asserts for #2036 2020-07-24 11:54:15 +12:00
rob bygrave a1d2f4c1af [maven-release-plugin] prepare for next development iteration 2020-07-14 12:52:50 +12:00
rob bygrave b7469da5b1 [maven-release-plugin] prepare release ebean-12.3.7 2020-07-14 12:52:39 +12:00
rob bygrave 2897968a54 Bump maven plugin - no effective change 2020-07-14 12:50:47 +12:00
rob bygrave 6360fad701 Refactor tidy NoopCallOriginFactory 2020-07-14 11:11:14 +12:00
rob bygrave dbc97aa28c Remove the duplicate TestSoftDeleteBasic.testFindSoftDeletedList()
Hmmm, my bad. I merged the branch manually and that didn't remove the PR so I've merged this twice now and hence ended up with a duplicate method. All good, just removing this duplicate method.
2020-07-14 09:47:07 +12:00
SnōwballandGitHub a231c136a9 Add failing test case for softdeletes (#2034)
Example:
One X can have many Ys. Ys can be soft deleted.

Y1 -> X1 -> Y1

Y1 is soft deleted

When Y1 is loaded, lazy-loading X1 and then lazy-loading the list of Ys associated with X1,
the list should contain Y1. This test asserts that is true.
2020-07-14 09:43:54 +12:00
rob bygrave c6487e56cf Merge branch 'tobias--soft_deletes_not_included' 2020-07-14 09:33:26 +12:00
rob bygrave dac0a97a3f #2035 - lazy-loading soft-deleted list from lazy-loaded bean doesn't remember includeSoftDeletes 2020-07-14 09:32:52 +12:00
rob bygrave ff0274f72c Merge branch 'soft_deletes_not_included' of https://github.com/tobias-/ebean into tobias--soft_deletes_not_included 2020-07-13 18:02:04 +12:00
rob bygrave ddee202bcc No effective change - tidy SqlTreeNodeBean 2020-07-10 10:52:22 +12:00
rob bygrave e1522a4a68 No effective change - tidy test TestSoftDeleteBasic 2020-07-10 10:48:28 +12:00
rob bygrave 7bc6170587 #2032 - Objects that occur in query is not filtered by @SoftDelete (when query has predicates on a ToMany path the associated soft delete predicates are not included) 2020-07-10 10:00:52 +12:00
rob bygrave 0322c19261 Merge branch 'tobias--softdeleted_where' 2020-07-10 09:57:45 +12:00
Tobias 18ae0a7833 Add failing test case for softdeletes
Example:
One X can have many Ys. Ys can be soft deleted.

Y1 -> X1 -> Y1

Y1 is soft deleted

When Y1 is loaded, lazy-loading X1 and then lazy-loading the list of Ys associated with X1,
the list should contain Y1. This test asserts that is true.
2020-07-09 20:56:33 +02:00
Tobias e99db44ddf Add test for soft deleted children
When a child is referenced in the query, Ebean should make sure
that the child (or any of the objects connecting it in the query)
is deleted.

Ie. if a query requires a child to have a certain value, it should
filter out those children that are soft deleted. It should also perform
the deleted check on all objects leading up to that child.

E.g. assuming that all objects are soft deletable, the following where():

DB.find(Alpha.class).where()
.eq("alpha.beta.gamma.name", "bar")

should generate a query with
"t0.deleted = false AND t1.deleted = false AND t2.deleted = false AND t2.name = 'bar'"
2020-07-07 12:33:43 +02:00
rob bygrave 361de9ea99 Update error thrown to use DatabaseConfig rather than ServerConfig 2020-07-06 14:37:56 +12:00
rob bygrave 99732b30b1 No effective change - tidy test TestHstore 2020-07-01 15:38:58 +12:00
rob bygrave dd5e5819b8 No effective change - Javadoc for ServerConfig 2020-06-30 23:07:27 +12:00
rob bygrave b4330679b8 #2029 Opps, fix tests 2020-06-30 10:59:03 +12:00
rob bygrave 59447ad261 #2029 - ENH: Add database.getPlatform(); ... to obtain the underlying database platform being used 2020-06-29 21:56:18 +12:00
rob bygrave 3bd20a424a [maven-release-plugin] prepare for next development iteration 2020-06-29 18:07:38 +12:00
rob bygrave 4ac3a8d1ad [maven-release-plugin] prepare release ebean-12.3.6 2020-06-29 18:07:27 +12:00
rob bygrave 5a8f8b3a83 #2027 - querybean generator support for @EbeanComponent 2020-06-29 18:01:28 +12:00
rob bygrave 7c01cec466 [maven-release-plugin] prepare for next development iteration 2020-06-29 17:21:19 +12:00
rob bygrave 30ad4260f0 [maven-release-plugin] prepare release ebean-12.3.5 2020-06-29 17:21:08 +12:00
rob bygrave ab421d6f2b No effective change - trim whitespace in BaseTableDdl 2020-06-29 17:15:35 +12:00
rob bygrave 0b807addc7 No effective change - test tidy 2020-06-29 17:09:02 +12:00
rob bygrave bb03ef5693 No effective change - test tidy 2020-06-29 15:51:34 +12:00
rob bygrave 248a7b1062 #2004 - MariaDB DDL review 2020-06-29 15:50:08 +12:00
rob bygrave 9da28262b4 #2004 - MariaDB History useLegacyDatetimeCode=false required to properly handle server timezone 2020-06-29 14:51:24 +12:00
rob bygrave fc8dd18fd1 #2004 - MariaDB History DDL using add/drop system versioning 2020-06-29 14:03:21 +12:00
rob bygrave 70ba658442 #2026 - Postgres DDL - modify type generates wrong alter sql. Needs explicit cast / using clause. 2020-06-29 12:12:10 +12:00
rob bygrave 70b730657f #2028 - Refactor internals of smart persistence context to reference "parent" rather than copy beans (adjustment of #2021) 2020-06-29 08:48:24 +12:00
rob bygrave bf3cb7e2e2 No effective change - tidy test BeanDescriptor_registerTest 2020-06-26 15:49:35 +12:00
rob bygrave c2708ecc76 No effective change - Refactor tidy BeanDescriptor internals - trimQueryPlans() etc 2020-06-23 22:14:11 +12:00
rob bygrave 896aba3053 No effective change - trim whitespace 2020-06-23 22:03:21 +12:00
rob bygrave f78b602a90 No effective change - trim whitespace 2020-06-23 21:08:30 +12:00
rob bygrave 306c1b5cf6 No effective change - EntityBeanIntercept tidy javadoc 2020-06-23 20:57:31 +12:00
rob bygrave cdf2718ca9 No effective change - refactor EntityBeanIntercept reverse internal notEqual() method 2020-06-23 20:43:08 +12:00
rob bygrave 967ca0c9f3 No effective change - add some more tests for EntityBeanIntercept 2020-06-23 17:09:15 +12:00
rob bygrave 607acb1b4e No effective change - tidy DefaultPersistenceContext 2020-06-23 16:35:53 +12:00
rob bygrave 5f923945e9 No effective change - trim whitespace 2020-06-23 16:35:36 +12:00
rob bygrave 11fbe8bf5b [maven-release-plugin] prepare for next development iteration 2020-06-19 23:23:32 +12:00
rob bygrave 0544fa7ab4 [maven-release-plugin] prepare release ebean-12.3.4 2020-06-19 23:23:21 +12:00
rob bygrave 51eed9bfe4 Testing - default to h2 2020-06-19 23:20:46 +12:00
Rob BygraveandGitHub 32ce1f1d59 #2004 - MariaDb specific platform with @History support (initial) (#2023)
#2004 - MariaDb specific platform with @History support (initial)
2020-06-19 23:20:07 +12:00
rob bygrave f445c118a0 #2025 - Make findStream & findLargeStream the same - deprecate findLargeStream 2020-06-19 23:17:47 +12:00
rob bygrave a8ff918bb3 #2024 - Change default "fetchBuffer" for findEach/iterate/stream queries to 100 2020-06-19 22:36:24 +12:00
rob bygrave 729aeae0d7 No effective change - trim whitespace 2020-06-19 22:13:50 +12:00
rob bygrave 17a9341287 #2006 - Auto register AttributeConverter with Ebean (using @Converter) 2020-06-19 20:33:58 +12:00
rob bygrave c863014fec Javadoc improvements for #2022 - use of index params like ?1, ?2, ?3 etc 2020-06-18 16:04:13 +12:00
rob bygrave 8170db4101 Bump ebean-annotation which has MariaDB platform enum
As a step for #2004
Means we can add a specific platform for MariaDB separate from MySql
2020-06-18 11:30:43 +12:00
rob bygrave 434a5117a2 Bump to ebean-datasource 5.1
This will expose pool size which can be exposed as a gauge metric (the current size of main connection pool and readonly connection pool)
2020-06-18 11:10:01 +12:00
rob bygrave 85ed8cd784 Test update only - TestSqlUpdateBindMultipleLists 2020-06-18 11:07:45 +12:00
rob bygrave 9b70900267 #2021 - Use smarter persistence context for findEach/iterate/stream queries - improve performance of un-tuned findEach/iterate/stream queries that invoke lazy loading 2020-06-17 21:50:11 +12:00
rob bygrave 0e33d58bb2 Bump ebean-maven-plugin to 12.3.4 2020-06-17 21:47:14 +12:00
rob bygrave 9d9d13060c #2020 - Fix potential connection leak in query-iterator WITH lazyLoadBufferSize (Refer #1164) 2020-06-17 17:10:16 +12:00
rob bygrave e071eecd59 Tidy test only - TestQueryFindEachWhile 2020-06-17 15:37:58 +12:00
rob bygrave bc8e254a65 Tidy tests - delete duplicate test TestQueryFindVisit.java 2020-06-17 13:31:18 +12:00
rob bygrave e0e369904c Tidy test only - TestQueryFindIterate 2020-06-17 13:30:34 +12:00
rob bygrave bd85ba17a1 No effective change - tidy TestQueryFindEach 2020-06-16 17:00:23 +12:00
rob bygrave 8801b8d8ca No effective change - tidy TestQueryFindEach 2020-06-16 16:55:49 +12:00
rob bygrave ebd6c535ab No effective change - tidy TestRawSqlParsing 2020-06-12 15:04:36 +12:00
rob bygrave 5c771a7219 Add tests for RawSql with ${where} and ${andWhere} placeholders 2020-06-12 15:03:05 +12:00
rob bygrave eb6f722385 Put back javadoc maven plugin 2020-06-09 20:03:47 +12:00
rob bygrave cef4f59b2c [maven-release-plugin] prepare for next development iteration 2020-06-08 21:58:31 +12:00
rob bygrave 67352ab3b2 [maven-release-plugin] prepare release ebean-12.3.3 2020-06-08 21:58:19 +12:00
rob bygrave 4a21395cda Comment out javadoc maven plugin temporarily 2020-06-08 21:56:07 +12:00
rob bygrave fcd7f8b6cf Bump ebean-maven-plugin 2020-06-08 20:00:22 +12:00
rob bygrave 4565719728 #2017 - ENH: Add option for different initialDelay to BackgroundExecutor.executePeriodically() 2020-06-05 18:31:07 +12:00
rob bygrave cbdf5609b2 #2015 - Dto instance id fields are not populated when queried using DtoQuery (and no select clause is specified) 2020-05-27 22:05:39 +12:00
rob bygrave f97359502b Refactor internals - DtoMeta DtoMappingRequest
Refactor move most of the code mapping DB columns to bean setters from DtoMeta to DtoMappingRequest
2020-05-27 22:04:03 +12:00
rob bygrave ffaf00c064 Improve error message throw on DTO unmapped DB column 2020-05-27 21:39:16 +12:00
rob bygrave f6f9511d2a #2014 - IllegalArgumentException: No rule for io.ebeaninternal.dbmigration.migration.RenameColumn 2020-05-27 21:00:42 +12:00
rob bygrave 5e94c26094 No effective change - update TestQueryInIdTypeConversion 2020-05-27 15:53:01 +12:00
rob bygrave 5aaed4e12b #2016 - L2 Cache - missing puts with explicit bean cache + findByIds/keys + after transaction writes 2020-05-26 23:42:44 +12:00
rob bygrave c29a57b5ec No effective change - update TestBeanCache Ebean -> DB 2020-05-26 23:19:23 +12:00
rob bygrave 998b8cc192 #2011 - Change query.orderBy() to not be deprecated 2020-05-15 14:06:28 +12:00
rob bygrave 9c1d930fb8 #2012 - Change ExpressionList.orderBy(String) to return ExpressionList<T>
Plus #2011 remove @Deprecated for orderBy
2020-05-15 14:06:06 +12:00
rob bygrave d6d7537a9c #2012 - Change ExpressionList.orderBy(String) to return ExpressionList<T> 2020-05-15 14:05:15 +12:00
rob bygrave 92e83c49d9 [maven-release-plugin] prepare for next development iteration 2020-05-12 22:39:42 +12:00
rob bygrave d758590da4 [maven-release-plugin] prepare release ebean-12.3.2 2020-05-12 22:39:31 +12:00
rob bygrave 21a5efa9b9 Tidy tests - tidy up TestCsvReader and TestCsvReaderWithCallback 2020-05-12 21:28:31 +12:00
rob bygrave 55a2cb12bb #2007 - Encrypted fields unable to be mapped when using DtoQuery 2020-05-12 21:11:28 +12:00
rob bygrave 293700acc0 #2007 - Encrypted fields unable to be mapped when using DtoQuery 2020-05-12 20:25:56 +12:00
rob bygrave 8980a3b6fd No functional change - tidy DbEncrypt, AbstractDbEncrypt 2020-05-12 16:34:08 +12:00
rob bygrave 72efc5d7d6 #2005 - Mark Ebean as deprecated - migrate to io.ebean.Database (EbeanServer -> Database) 2020-05-11 23:15:02 +12:00
rob bygrave 84589fcce6 Bump the versions of ebean-maven-plugin and maven-surefire-plugin 2020-05-11 23:09:24 +12:00
rob bygrave a0e44aedf3 Fix IllegalStateException to use correct dependency io.ebean:ebean-elastic in error message 2020-05-11 20:29:58 +12:00
rob bygrave 41102aca35 Add clearBatch() on BatchedPstmt construction 2020-05-08 23:32:24 +12:00
rob bygrave 548cea432e Fix test UpdateQueryTest for PG 2020-05-08 23:22:23 +12:00
rob bygrave 592cb37693 Reset test default to H2 2020-05-08 23:01:59 +12:00
rob bygrave f2178bf0a6 #2003 - Bump ebean-datasource to 4.9.2 with optional driver 2020-05-04 12:41:14 +12:00
rob bygrave 5cae425b09 #2002 - Support maxRows with delete query 2020-05-04 12:28:52 +12:00
rob bygrave 94b78f1c2d [maven-release-plugin] prepare for next development iteration 2020-04-30 23:41:07 +12:00
rob bygrave 561affef0f [maven-release-plugin] prepare release ebean-12.3.1 2020-04-30 23:40:56 +12:00
Rob BygraveandGitHub 3310d2186d Remove autoCommitMode and explicitTransactionBeginMode (#1993)
These are legacy options that we don't want anyone using going forward.
2020-04-30 23:36:24 +12:00
Rob BygraveandGitHub 02bdace144 Change OraclePlatform to default to use Identity (rather than sequence) (#1976)
* Change OraclePlatform to default to use Identity

- Keep Oracle11Platform to default to Sequence
- Refactor rename Oracle10Ddl to OracleDdl

* Change OraclePlatform to default to use Identity

- DDL review changes in src/test

* Bump ebean-test-docker for StartOracle
2020-04-30 23:35:20 +12:00
rob bygrave 7c17098f17 Bump pom version to 12.3.1-SNAPSHOT 2020-04-30 23:34:13 +12:00
rob bygrave 6f194ce95d #2001 - Add convenient alternative to set read-only url (on the main DataSourceConfig) 2020-04-30 23:19:08 +12:00
rob bygrave dbe473d5a1 #1996 - Fix for MySQLSyntaxErrorException when update in bulk using idIn(). 2020-04-30 21:33:02 +12:00
rob bygrave ed0e9e7006 #1999 - Additionally support empty string for read only url with config.isAutoReadOnlyDataSource() 2020-04-29 22:15:15 +12:00
rob bygrave 2a03198393 #1999 - Additionally support "none" for read only url
"none" can then be used as a special literal value in configuration for "no read-only jdbc url"
2020-04-29 22:07:27 +12:00
rob bygrave 6f1472abe0 #2000 - Tests only - bump sql server to 2019-GA-ubuntu-16.04 2020-04-28 22:13:57 +12:00
rob bygrave 6dea4f0890 #1996 - MySQLSyntaxErrorException when update in bulk. 2020-04-28 21:24:25 +12:00
rob bygrave 4a4ec42cdc #1999 - Refactor read-only DataSource initialisation 2020-04-28 21:10:43 +12:00
rob bygrave 92ea8e3738 #1998 - Refactor internals rename createQueryTransaction() to createReadOnlyTransaction() 2020-04-25 17:38:54 +12:00
rob bygrave c349832d35 #1997 - Modify @Transactional(readOnly=true) to use the read only DataSource 2020-04-25 17:33:33 +12:00
rob bygrave 90493ad57d #1995 - Fix for DatabaseConfig.isLocalOnlyL2Cache() ... to set localL2Caching = true
This has the effect that the l2 cache notification occurs in the foreground when isLocalOnlyL2Cache is true (not background)
2020-04-23 13:11:20 +12:00
rob bygrave 5012f59371 [maven-release-plugin] prepare for next development iteration 2020-04-21 23:01:48 +12:00
rob bygrave 149e63a272 [maven-release-plugin] prepare release ebean-12.2.6 2020-04-21 23:01:37 +12:00
rob bygrave d52a00a8fb #1995 - ENH: Add DatabaseConfig.isLocalOnlyL2Cache() ... to support disabling l2 cache plugins 2020-04-21 23:00:13 +12:00
rob bygrave f0dcec95dd [maven-release-plugin] prepare for next development iteration 2020-04-21 22:00:29 +12:00
rob bygrave 2653931881 [maven-release-plugin] prepare release ebean-12.2.5 2020-04-21 22:00:18 +12:00
rob bygrave 85207086e6 #1995 - ENH: Add DatabaseConfig.isLocalOnlyL2Cache() ... to support disabling l2 cache plugins 2020-04-21 21:55:51 +12:00
rob bygrave d0b0b02d6a [maven-release-plugin] prepare for next development iteration 2020-04-15 08:47:38 +12:00
rob bygrave 34fa1def77 [maven-release-plugin] prepare release ebean-12.2.4 2020-04-15 08:47:26 +12:00
rob bygrave 9f1aa958fc Bump ebean-maven-plugin 2020-04-15 08:35:24 +12:00
rob bygrave cdc5eefc69 EntityBeanIntercept.isOrphanDelete() - Additional refactor for #1988 2020-04-14 23:17:56 +12:00
Jonas PöhlerandGitHub c9588586c9 Removing elements with @OrderColumn with a tree depth > 1 doesn't work (#1988)
* ADD: failing testcase for orderColumn when tree depth > 1

* FIX: no update with @OrderColumn on treeDepth > 1 and avoid needless updates

* ADD: failing testcase for removing models in oneToMany relation with @OrderColumn

Signed-off-by: Jonas Pöhler (JPo) <jonas.poehler@foconis.de>

* ADD: failing test for faulty element reordering in a entityBean tree with version

Signed-off-by: Jonas Pöhler (JPo) <jonas.poehler@foconis.de>

* FIX: incorrect behaviour when reordering or removing elements from collection with @OrderColumn.

Signed-off-by: Jonas Pöhler (JPo) <jonas.poehler@foconis.de>
2020-04-14 23:07:00 +12:00
rob bygrave 52735179d9 Bump maven plugin 2020-04-14 22:44:46 +12:00
rob bygrave cef1fb9e80 #1992 - IllegalArgumentException: Expecting only yaml or properties file but got [ort] 2020-04-14 22:42:26 +12:00
rob bygrave c7e1964aae #1991 - NPE in MCompoundUniqueConstraint.<init>(MCompoundUniqueConstraint.java:66) 2020-04-14 21:28:03 +12:00
rob bygrave 6d43883f77 #1990 - NPE with @Cache and setting naturalKey to null 2020-04-14 20:57:42 +12:00
rob bygrave f06f99dfc3 Refactor remove unnecessary BeanDescriptorManager.setProfileIds() method
As it is no longer necessary (profileIds no longer used)
2020-04-12 17:13:54 +12:00
rob bygrave 41e600be45 Merge branch 'bugfix/order_column_l1_cache' of https://github.com/FOCONIS/ebean into FOCONIS-bugfix/order_column_l1_cache 2020-04-12 16:37:00 +12:00
Rob BygraveandGitHub 62a81c531a Merge pull request #1986 from FOCONIS/bugfix/order_column_reference_abstract
@OrderColumn is ignored on relations referencing a abstract inheritance-model
2020-04-12 16:32:15 +12:00
Rob BygraveandGitHub 2cb1a626c4 Merge pull request #1985 from FOCONIS/bugfix/order_column_tree_depth
Update is missing for relations with @OrderColumn from a tree depth > 1
2020-04-12 16:19:01 +12:00
Jonas Pöhler (JPo) 18cde36b9d FIX: cache not being cleared in persistence context on reorder with @OrderColumn
Signed-off-by: Jonas Pöhler (JPo) <jonas.poehler@foconis.de>
2020-04-08 16:05:09 +02:00
Jonas Pöhler (JPo) e05b6b78ad ADD: failing testcase for not cleared beancache in persistence context on reorder with @OrderColumn
Signed-off-by: Jonas Pöhler (JPo) <jonas.poehler@foconis.de>
2020-04-08 16:04:49 +02:00
rob bygrave 58c49deb06 [maven-release-plugin] prepare for next development iteration 2020-04-08 14:59:42 +12:00
rob bygrave 4a41e88162 [maven-release-plugin] prepare release ebean-12.2.3 2020-04-08 14:59:30 +12:00
rob bygrave 2e5becf48c Refactor rename to MySqlDataTimeZone and OracleDataTimeZone 2020-04-08 14:57:58 +12:00
rob bygrave 4094339407 #1984 - ENH: Add DB.script() ... to access ScriptRunner from DB 2020-04-08 14:13:57 +12:00
rob bygrave bf24949efb #1982 - conflict with eureka config generate StringIndexOutOfBoundsException with 12.2.1 version 2020-04-08 13:49:13 +12:00
Jonas Pöhler (JPo) 3b4549a7ee FIX: @OrderColumn not working when referencing the parent of a inheritance structure 2020-04-06 16:22:33 +02:00
Jonas Pöhler (JPo) f194fdb132 ADD: failing testcase for @OrderColumn working when referencing the parent of a inheritance structure 2020-04-06 16:08:21 +02:00
Jonas Pöhler (JPo) 2d274c46fa FIX: no update with @OrderColumn on treeDepth > 1 and avoid needless updates 2020-04-06 15:34:43 +02:00
Jonas Pöhler (JPo) b61e9af750 ADD: failing testcase for orderColumn when tree depth > 1 2020-04-06 15:14:23 +02:00
rob bygrave a01362abad #1980 Remove the volatile that was added for NPE in EntityBeanIntercept 2020-03-25 22:03:52 +13:00
Rob BygraveandGitHub 4387c662b6 Merge pull request #1981 from tobias-/issue_1980_NPE
Use temp variable to avoid NPE race
2020-03-25 21:06:00 +13:00
Tobias ecdd027b3e Use temp variable to avoid NPE race
resolve #1980
2020-03-25 07:01:32 +01:00
rob bygrave 2b0f572f4d [maven-release-plugin] prepare for next development iteration 2020-03-25 16:15:44 +13:00
rob bygrave 0a1704e6a9 [maven-release-plugin] prepare release ebean-12.2.2 2020-03-25 16:15:32 +13:00
rob bygrave 854c208f92 Bump ebean-maven-plugin 2020-03-25 15:55:57 +13:00
rob bygrave e6f604764c #1980 - NullPointerException in EntityBeanIntercept 2020-03-25 15:54:16 +13:00
Rob BygraveandGitHub 9b501b3dc8 Merge pull request #1979 from FOCONIS/bugfix/order_column_on_inheritance_model
@OrderColumn does not work on inheritance models
2020-03-23 22:28:57 +13:00
Jonas PöhlerandGitHub c2fb23a25c "insert into table default values" is invalid MySQL syntax (#1978)
* ADD: failing testcase for "insert into table default values;" is invalid MySql syntax

* FIX: "insert into table default values;" is invalid MySql syntax
2020-03-23 22:09:28 +13:00
Jonas Pöhler (JPo) 1ad7ace9bd FIX: error with @OrderColumn on model with inheritance 2020-03-20 10:22:16 +01:00
Jonas Pöhler (JPo) 6a3a7eafea ADD: failing testcase for @OrderColumn on model with inheritance 2020-03-20 10:20:52 +01:00
rob bygrave 896aed0b38 No effective change - change to avaje-jsr305 2020-03-17 22:38:05 +13:00
rob bygrave f7359aacd7 No effective change - update tests for oracle ddl 2020-03-17 22:25:52 +13:00
rob bygrave d77fb9265b No effective change - update oracle ddl review 2020-03-17 22:25:04 +13:00
rob bygrave db27844eca [maven-release-plugin] prepare for next development iteration 2020-03-13 09:28:33 +13:00
rob bygrave 61be1683b2 [maven-release-plugin] prepare release ebean-12.2.1 2020-03-13 09:28:23 +13:00
rob bygrave 27a1f35356 Bump ebean-maven-plugin to 12.2.1 2020-03-12 23:46:40 +13:00
rob bygrave f0c0b7ebcc #1974 - Turn on by default loadModuleInfo - aka auto register entity beans using query bean generated code 2020-03-12 23:45:35 +13:00
rob bygrave f4c646cdc1 Bump pom to 12.2.1-SNAPSHOT 2020-03-10 23:00:10 +13:00
rob bygrave 48abc73e50 #1973 - L2Cache, Inheritance and Lazy-Loading loads the parent Class not the Child 2020-03-10 22:52:13 +13:00
rob bygrave 91a327a5e7 #1972 - Change BigDecimal to map by default DB type DECIMAL(16,3) rather than DECIMAL(38) 2020-03-09 17:05:08 +13:00
Rob BygraveandGitHub a861e8bdcc Remove reading mapping annotations from "Getters" with associated refactoring for performance (#1971)
* #1970 - Change test code only moving mapping annotations to fields

First step in remove support for mapping annotations on "Getters" (so field only target for mapping annotations)

* #1970 - Remove reading mapping annotations from "Getters"

* #1970 - Refactor to use simple annotation lookup where possible

* #1970 - Remove GenerationType.TABLE and SequenceGenerator from type/class

* #1970 - Refactor meta annotation reading

* #1970 - Read @Aggregation as a meta annotation
2020-03-09 16:09:41 +13:00
Rob BygraveandGitHub 7692d9782a Merge pull request #1968 from ebean-orm/feature/refactorRenameTxnBatchMethods
Refactor rename Transaction methods - setBatchGetGeneratedKeys(), setBatchFlushOnMixed() setBatchFlushOnQuery() ... (remove the "batch" part)
2020-03-05 09:31:13 +13:00
rob bygrave 524e3e31f0 Refactor rename Transaction setGetGeneratedKeys(), setFlushOnMixed() setFlushOnQuery() ... (remove the "batch" part) 2020-03-05 01:10:41 +13:00
rob bygrave d69d96a400 #1967 - Refactor internals reverse default columnAliasPrefix to null from "c" 2020-03-05 00:56:22 +13:00
rob bygrave 0ce39c73f1 Test only update postgres DDL review 2020-03-05 00:21:36 +13:00
rob bygrave 82d6294dcb Test only update h2 DDL review 2020-03-05 00:13:41 +13:00
rob bygrave ba01103f48 #1965 @Identity with sequence ddl generation 2020-03-05 00:13:08 +13:00
Rob BygraveandGitHub 3e14ec6a5a Merge pull request #1965 from ebean-orm/feature/identityMode2
Support for @Identity - with cache, generated by (ALWAYS/BY DEFAULT), start, increment options
2020-03-04 22:56:44 +13:00
rob bygrave b9d5d35850 Set testing default back to H2 2020-03-04 22:55:51 +13:00
rob bygrave 04adc35ccd Support for @Identity - Fix sequence name propagation 2020-03-04 22:49:08 +13:00
rob bygrave bfc2b57df5 Support for @Identity - use identity options with sequence 2020-03-04 21:29:56 +13:00
rob bygrave a5880fca97 Support for @Identity - update sql server ddl review 2020-03-04 21:23:50 +13:00
rob bygrave 8685f2056a Support for @Identity - update ddl review 2020-03-04 17:18:01 +13:00
rob bygrave 2ac19bea1a Support for @Identity - with start, increment, cache 2020-03-04 16:59:42 +13:00
rob bygrave 9410f82f5a Support for @Identity - update default sequence increment 2020-03-03 22:36:59 +13:00
rob bygrave 21382a52ed Support for @Identity - split IdentityMode and DeployIdentityMode 2020-03-03 22:36:27 +13:00
rob bygrave f871259f20 Support for @Identity - split IdentityMode and DeployIdentityMode 2020-03-03 22:36:27 +13:00
rob bygrave eb765056fd Support for @Identity - initial refactor to add IdentityMode 2020-03-03 22:36:27 +13:00
rob bygrave ddf3c753d6 Ability to use order(<orderByClause>) on filterMany() (related to #1943) #1964 2020-03-03 22:31:01 +13:00
rob bygrave 4767aff046 Test only update sql server DDL review 2020-03-03 22:03:24 +13:00
rob bygrave 75846edd97 Test only update H2 DDL review 2020-03-03 21:20:19 +13:00
rob bygrave f7c6745de1 Ci Testing - remove test/resources/dbmigration/migrationtest/postgres9 2020-03-01 13:09:37 +13:00
rob bygrave f080f16e63 #1962 - Refactor simplify Postgres platforms to POSTGRES and POSTGRES9 2020-03-01 12:53:34 +13:00
rob bygrave 9135f87253 CI Testing - ParentQueryTest cascade on parent.data 2020-03-01 12:42:03 +13:00
rob bygrave 90ccf2d8b4 CI Testing - ParentQueryTest cascade on parent.data 2020-03-01 12:29:54 +13:00
rob bygrave 11409f8c09 CI Testing - ParentQueryTest cascade on parent.data 2020-03-01 12:23:16 +13:00
rob bygrave fb472a0304 CI Testing - ParentQueryTest truncate 2020-03-01 12:12:01 +13:00
rob bygrave 04c9007d22 CI Testing - Update travis to not both with oraclejdk8 which is no longer available 2020-03-01 11:55:31 +13:00
rob bygrave 8f75a04ad0 CI Testing - Update travis to xenial & postgresql: 10 2020-03-01 11:45:56 +13:00
Rob BygraveandGitHub 2236e4bfd7 Refactor PlatformDdl separate call to asIdentityColumn() (#1961) 2020-03-01 10:42:41 +13:00
rob bygrave 6d1c3738de #1960 - CVEs - Update postgresql and h2 jdbc drivers (provided scope only) 2020-02-28 16:22:48 +13:00
rob bygrave 20160144f5 No effective change - remove unused snakeyaml.version from pom 2020-02-22 14:42:00 +13:00
rob bygrave 891166507d Test only - restore postgres9 and postgres10 migration resources for CI postgres 2020-02-22 13:36:33 +13:00
rob bygrave bce97b1063 Test only - add dummy files for pg9 and pg10 DbMigrationTest for running on CI (with old postgres) 2020-02-22 12:54:16 +13:00
Rob BygraveandGitHub c5b960c588 Merge pull request #1959 from ebean-orm/feature/1955
#1953 - Do we need SqlServer2005Platform and SqlServer2005SqlLimiter?
2020-02-22 12:47:13 +13:00
rob bygrave 009b400ed3 Test only - delete test/resources/dbmigration/migrationtest/postgres10 and postgres9 2020-02-22 12:45:07 +13:00
rob bygrave b6ee6ade8c Test only - update ddl review for postgres 2020-02-22 12:44:00 +13:00
rob bygrave 0891c067d5 #1953 - Do we need SqlServer2005Platform and SqlServer2005SqlLimiter? 2020-02-22 11:48:16 +13:00
Rob BygraveandGitHub 7b3b32f0ff Merge pull request #1957 from ebean-orm/feature/1955
#1955 #1956  SqlQuery.mapToScalar() and SqlQuery.mapTo(RowMapper)
2020-02-22 11:25:48 +13:00
rob bygrave 3878b02cff #1956 - Add SqlQuery - mapTo( RowMapper) ... to deprecate findOne(RowMapper) 2020-02-22 10:50:23 +13:00
rob bygrave 92995b807e #1955 - mapToScalar - Add SqlQuery.mapToScalar( <class> ).findOne() / findList() ... to deprecate findSingleAttribute() 2020-02-22 10:09:44 +13:00
Rob BygraveandGitHub 907d36123d OraclePlatform update (ANSI row limiting with OFFSET), Oracle11Platform for old behaviour (#1951)
* #1947 - Oracle change to use concat operator rather than function

* #1947 - setMaxRows(1).findIds() under Oracle returns wrong result

* #1950 - Change OraclePlatform to use ANSI row limiting - OFFSET and NEXT ROWS, old platform as Oracle11Platform

* Revert test default to H2

* #1947 - Oracle & Oracle11 platform
2020-02-22 09:28:34 +13:00
Rob BygraveandGitHub 2db95f909d Merge pull request #1944 from ebean-orm/feature/1943
#1943 - Use limit & offset via setFirstRow() and setMaxRows() on filterMany()
2020-02-22 09:26:03 +13:00
rob bygrave 5213e8b653 Fix test merge for StartPostgres9 - using int for port 2020-02-22 09:24:58 +13:00
Rob BygraveandGitHub 2314fd267f Split Postgres platform into Postgres10 & Postgres9 (DDL - generated by default as identity) (#1921)
* Split Postgres platform into Postgres10 & Postgres9

- Use "generated by default as identity" for Postgres10 identity columns

* Add postgres9 migrationtest resources

* Set default back to h2

* Add postgres10 migration test resources
2020-02-22 09:18:05 +13:00
Rob BygraveandGitHub b24f093bbb Remove io.ebean.meta.MetricType as it is unnecessary (#1923) 2020-02-22 09:17:14 +13:00
Rob BygraveandGitHub 444c868124 Refactor to use avaje config (#1894)
* Move to use Avaje Config for properties loading
2020-02-22 09:11:37 +13:00
rob bygrave 81b16b8f73 [maven-release-plugin] prepare for next development iteration 2020-02-22 08:59:33 +13:00
rob bygrave 850db70be3 [maven-release-plugin] prepare release ebean-12.1.13 2020-02-22 08:59:20 +13:00
rob bygrave ee81ee4d7c test only update of ddl review for mysql-create-all.sql 2020-02-22 08:50:32 +13:00
Rob BygraveandGitHub 4cbeb282eb Merge pull request #1954 from boeckers/added_MySqlDbExpression.json
Add JSON expression handing for MySql - MySqlDbExpression.json
2020-02-22 08:40:09 +13:00
Michael Böckers 5278c010ba added MySqlDbExpression.json 2020-02-21 12:58:18 +01:00
rob bygrave ea490a5ac3 Collect the DB schemas in the model via MTable 2020-02-21 17:16:28 +13:00
rob bygrave e4390ed8a2 #1952 - Entity bean with @Id and ONLY @WhenCreated treated as reference bean - not inserted 2020-02-21 00:14:23 +13:00
Rob BygraveandGitHub a23d9f7db8 Merge pull request #1949 from sebastianmrozek/master
Test usingDatabase with a non default db
2020-02-20 22:43:53 +13:00
Sebastian Mrozek b1704ff5dc Test usingDatabase with a non default db
Move the test to separate class with better name.
2020-02-20 22:13:38 +13:00
rob bygrave c0d752b445 #1941 - @History it seems does not work well when it got generated with ebean.allQuotedIdentifiers enabled 2020-02-20 16:51:07 +13:00
Rob BygraveandGitHub ef5ea59559 Merge pull request #1948 from ebean-orm/feature/queryUsingDatabase
ENH: Add query.usingDatabase(database)
2020-02-20 16:42:25 +13:00
rob bygrave de42655bbd Refactor tests using assertSql() helper method
This helper method trims column alias from the sql (for Oracle)
2020-02-20 15:08:43 +13:00
rob bygrave 661230909c ENH: Add query.usingDatabase(database) - add better test 2020-02-19 11:48:47 +13:00
rob bygrave e9325a81f7 ENH: Add query.usingDatabase(database) 2020-02-19 11:41:06 +13:00
Rob BygraveandGitHub 78b9066345 Merge pull request #1946 from ebean-orm/feature/orderByDeprecate
Deprecate orderBy() migrate to order()
2020-02-19 10:00:15 +13:00
rob bygrave 1959e01844 Javadoc update only - change server to database in examples 2020-02-18 23:43:39 +13:00
rob bygrave cf6179c86b Deprecate orderBy() migrate to order() - update javadoc 2020-02-18 23:36:48 +13:00
rob bygrave 168dacffa7 Deprecate orderBy() migrate to order() 2020-02-18 23:27:43 +13:00
rob bygrave e0d322d80a #1943 - Return ExpressionList<T> from setMaxRows() setFirstRow() to allow fluid style
This is to allow fluid style use of setMaxRows() setFirstRow() with filterMany query
2020-02-17 17:19:27 +13:00
rob bygrave 1dd0f3cbf8 #1943 - Use limit & offset via setFirstRow() and setMaxRows() on filterMany() 2020-02-17 17:05:01 +13:00
rob bygrave 6961bf5787 #1945 - ENH: Add query.orderById(boolean) to ExpressionList ... improve fluid style 2020-02-17 16:47:37 +13:00
rob bygrave a14288b06d Refactor tidy DefaultExpressionList, no functional change 2020-02-17 16:40:03 +13:00
rob bygrave 171d1a19f4 #1937 - When add a new col with @DbComment in Entity,the DbMigration does not generate comment ddl 2020-02-17 14:19:19 +13:00
rob bygrave cbaaad89ab #1942 - Bump datasource to 4.7.3, includes - datasource.offline() closes busy connections ... should let them close on return 2020-02-17 11:51:40 +13:00
Rob BygraveandGitHub 413290a040 Merge pull request #1939 from ebean-orm/feature/1938
#1938 - API consistency add setParameters(varargs) & setParameter() - migrate from setNextParameter() and setParams()
2020-02-17 11:37:34 +13:00
rob bygrave 8feb100ac6 #1938 - API consistency add setParameters(varargs) & setParameter() - migrate from setNextParameter() and setParams() 2020-02-15 02:01:02 +13:00
rob bygrave d236988035 [maven-release-plugin] prepare for next development iteration 2020-02-09 22:23:59 +13:00
rob bygrave df0d84424c [maven-release-plugin] prepare release ebean-12.1.12 2020-02-09 22:23:48 +13:00
rob bygrave fb30a15a5b Update to ebean-maven-plugin 12.1.12 2020-02-09 22:21:14 +13:00
rob bygrave 3707d611b1 No effective change - EBasicVer extend Model 2020-02-07 22:07:38 +13:00
rob bygrave 60aa720777 No effective change - javadoc format SpiTransaction 2020-02-07 20:53:08 +13:00
rob bygrave 427152a894 Add test for IllegalStateException("Transaction is Inactive") 2020-02-07 20:15:59 +13:00
rob bygrave 3e43d544fb #1936 - ENH: Add saveAll(Object... beans) ... using varargs for DB and Database 2020-02-07 16:10:11 +13:00
rob bygrave 62b1da1be2 #1935 - ENH: Add DB.createTransaction() 2020-02-07 15:52:26 +13:00
rob bygrave 8b4eae2f91 #1934 - ENH: Add methods to Model that take explicit transaction - save(transaction), delete(transaction) ... 2020-02-07 13:00:59 +13:00
rob bygrave 4ed3a18b9d #1933 - ENH: Add DtoQuery.usingTransaction(Transaction) ... dto query with supplied transaction 2020-02-07 12:42:10 +13:00
Rob BygraveandGitHub 3c9d7e3127 Merge pull request #1925 from ebean-orm/feature/refatorTxnProfile
#1924 - Refactor for Transaction profiling - base on ProfileLocation / remove profileId
2020-02-04 22:38:44 +13:00
rob bygrave a89744a7bd No functional change - fix error message in DataSourceConfigurationException throw by Ebean 2020-02-03 22:34:10 +13:00
Rob BygraveandGitHub 5962f14874 Merge pull request #1928 from ebean-orm/feature/1755
FIX: Regression of #1775 - set date for other platforms (non MySQL) broken, when ebean.dataTimeZone is set to GMT
2020-02-01 16:03:33 +13:00
Roland Pramlandrob bygrave f161a38334 FIX: Regression of #1775 - set date for other platfroms broken, when ebean.dataTimeZone is set to GMT 2020-02-01 15:59:18 +13:00
Roland Pramlandrob bygrave 13f8da6b2e FIX: Add cause to exception 2020-02-01 14:07:09 +13:00
rob bygrave 9ad14c5306 #1926 - Postgres (Multi value bind) fix related to empty idIn() expression 2020-02-01 14:05:12 +13:00
rob bygrave 61ed4a5a74 Merge branch 'master' of github.com:ebean-orm/ebean 2020-02-01 13:51:48 +13:00
Rob BygraveandGitHub 275f2dbc98 Merge pull request #1927 from ebean-orm/foconis-cache-emptylist
Fix cache emptylist and Fix / improvement for UUIDv1Generator mac address detection
2020-02-01 13:51:25 +13:00
Roland Pramlandrob bygrave 521b6a36ef changed ip.ebeaninternal.api.SpiQuery to io.ebean.Query in Server.exists 2020-02-01 13:46:28 +13:00
Roland Pramlandrob bygrave 0a6c26e5d3 FIX: Virtual Prüfung 2020-02-01 13:38:56 +13:00
Roland Pramlandrob bygrave 33416bffd0 FIX: Detecting MAC address improved 2020-02-01 13:38:44 +13:00
Roland Pramlandrob bygrave 4ce484f3f2 FIX: Cache also empty lists 2020-02-01 13:38:21 +13:00
rob bygrave cacf033647 Merge branch 'foc-imports' 2020-02-01 13:18:55 +13:00
rob bygrave e3dba6bfe1 Failing test for idIn() empty 2020-02-01 13:18:42 +13:00
Roland Pramlandrob bygrave c0b6f291a1 FIX: handle empty collection in "in (...)" queries 2020-02-01 13:06:37 +13:00
rob bygrave 9eab67d82e #1924 - Refactor for Transaction profiling - base on ProfileLocation / remove profileId 2020-02-01 11:31:43 +13:00
rob bygrave 840cb2ee7b [maven-release-plugin] prepare for next development iteration 2020-01-30 18:53:46 +13:00
rob bygrave e0f171b638 [maven-release-plugin] prepare release ebean-12.1.11 2020-01-30 18:53:35 +13:00
rob bygrave 2bb52a9581 #1922 - Performance - Too pessimistic synchronized block for lazy loading on reference bean or l2 cache bean 2020-01-30 18:48:39 +13:00
Rob BygraveandGitHub f1cf94365c Merge pull request #1920 from ebean-orm/feature/createIndexConcurrently
ENH: Add support for Postgres create index concurrently
2020-01-29 20:36:44 +13:00
rob bygrave a894924e96 #1920 Support @Index concurrently and definition 2020-01-29 20:22:32 +13:00
rob bygrave 680a11a532 No effective change - postgres ddl review update 2020-01-29 16:54:23 +13:00
rob bygrave 605150de5c Update ebean-migration to 12.1.3 with support for Postgres create index concurrently 2020-01-29 11:29:29 +13:00
rob bygrave 5ff44703cf [maven-release-plugin] prepare for next development iteration 2020-01-28 14:01:58 +13:00
rob bygrave 99175bf679 [maven-release-plugin] prepare release ebean-12.1.10 2020-01-28 14:01:47 +13:00
rob bygrave acff330b37 #1918 - Ebean 12.1.9 breaks Guice in Stage.PRODUCTION mode for multi tenant apps 2020-01-28 12:07:07 +13:00
rob bygrave df63eeaa8c #1915 - Regression with DiscriminatorValue since #1361 2020-01-28 10:21:29 +13:00
rob bygrave 07aa39c5de #1917 - PostgresPlatform (9+) does not support IdType.IDENTITY? 2020-01-28 09:46:24 +13:00
Rob BygraveandGitHub c51a1b07a4 Merge pull request #1914 from ebean-orm/feature/indexPlatform
ENH: Support @Index platforms attribute - platform specific indexes
2020-01-16 09:23:28 +13:00
rob bygrave bb56725b12 Use unique index rather than constraint when using formula [like lower(column)] 2020-01-15 16:58:55 +13:00
rob bygrave 099adcf6cd Refactor tidy ModelBuildPropertyVisitor - no functional change 2020-01-15 15:52:37 +13:00
rob bygrave 05be24b8b2 ENH: Support @Index platforms attribute - platform specific indexes
This is a potential alternative to using extra-dll.xml. Might be
appropriate to use over extra-dll in small simple cases.

We might look to extend this in the future to allow full raw platform specific ddl - the ability to specify the entire create index statement.
2020-01-15 15:47:14 +13:00
Rob BygraveandGitHub 7d98355d39 Merge pull request #1913 from ebean-orm/feature/MaxMin
Change to use @Aggregation as meta annotation - support newly added @Max, @Min, @Avg annotations
2020-01-14 16:41:44 +13:00
rob bygrave 56562915bf #1912 - Allow @Index(unique=true) to support formula in columns 2020-01-14 16:20:02 +13:00
rob bygrave 07f4ad2500 Change to use @Aggregation as meta annotation - support newly added @Max, @Min, @Avg annotations 2020-01-14 16:14:14 +13:00
rob bygrave 22e43f5fa7 [maven-release-plugin] prepare for next development iteration 2020-01-11 00:01:01 +13:00
rob bygrave 3127bc2154 [maven-release-plugin] prepare release ebean-12.1.9 2020-01-11 00:00:50 +13:00
Rob BygraveandGitHub 8aa1ed6676 Merge pull request #1909 from ebean-orm/feature/mySqlJson
For MySql map @DbJson to mysql JSON db type
2020-01-10 23:59:18 +13:00
rob bygrave 8a0dea1218 #1910 - Change javadoc generation to no longer use pygments doclet (code highlighting) 2020-01-10 23:37:19 +13:00
rob bygrave 1e266a1532 #1895 - Ebean creates invalid sql for particular @ManyToOne 2020-01-10 23:32:58 +13:00
rob bygrave 57cfd25eb5 #1903 - Add ability to set migration path via DbMigration 2020-01-10 16:06:18 +13:00
rob bygrave 2bcce2e648 For MySql map @DbJson to mysql JSON db type 2020-01-10 14:48:26 +13:00
rob bygrave f6e45a6999 For MySql map @DbJson to mysql JSON db type 2020-01-10 14:39:55 +13:00
rob bygrave fa3de7158e No effective change - update mysql ddl review in src/test/ddl-review 2020-01-10 14:15:50 +13:00
rob bygrave 792785dabe Fix for #1902 #1908 - change allowing view based entities to be autoTunable 2020-01-10 14:02:12 +13:00
Rob BygraveandGitHub d0cd74b400 Merge pull request #1908 from FOCONIS/test-setdefaultselectclause
Testcase for #1902
2020-01-10 13:41:24 +13:00
rob bygrave 71d762ab97 #1907 - SQL Server DB Migration for uuid property @NotNull - should drop index before drop constraint 2020-01-10 13:09:11 +13:00
Roland Praml e00713aa29 Testcase for #1902 2020-01-10 01:03:38 +01:00
rob bygrave d70a49e105 No effective change - refactor tidy DefaultOrmQuery 2020-01-10 12:55:05 +13:00
Roland Pramlandrob bygrave 159a9a8e54 #1902 - SingleAttributeQueries with child selection only does not work with autoTune=false (e.g. Views) 2020-01-10 12:49:20 +13:00
rob bygrave db027eb030 #1904 - Bump datasource to 4.7.1 2020-01-09 15:19:17 +13:00
rob bygrave ec55b2f096 Refactor for query plan capture with initial threshold micros - part 3
Use QueryPlanInit
2019-12-24 02:02:11 +13:00
Rob BygraveandGitHub b854943a86 Merge pull request #1899 from ebean-orm/feature/queryPlanCapture
Refactor for query plan capture with initial threshold micros
2019-12-24 00:54:37 +13:00
rob bygrave 8a263d243c Refactor for query plan capture with initial threshold micros - part 2 2019-12-24 00:29:46 +13:00
Rob BygraveandGitHub 0a4f93adc5 #1897 - Indexes names, like index, unique, primary and foreign keys does not honor ebean.allQuotedIdentifiers (#1898) 2019-12-23 18:43:41 +13:00
rob bygrave ffb11019fa #1896 - ebean.allQuotedIdentifiers is ignored for @JoinColumn 2019-12-23 13:30:28 +13:00
rob bygrave 6fcac27dfe Refactor for query plan capture with initial threshold micros 2019-12-23 10:28:08 +13:00
rob bygrave 71295077a5 [maven-release-plugin] prepare for next development iteration 2019-12-17 23:44:36 +13:00
rob bygrave ddbad284ad [maven-release-plugin] prepare release ebean-12.1.8 2019-12-17 23:44:25 +13:00
rob bygrave 1fcec429b0 #1893 - @DbArray with @NotNull ... should persist empty db array rather than fail NOT NULL constraint 2019-12-17 20:33:03 +13:00
rob bygrave c6062fe93e #1893 - @DbArray with @NotNull ... should persist empty db array rather than fail NOT NULL constraint 2019-12-17 20:27:53 +13:00
rob bygrave d8d35b7dd9 #1893 - Failing test for @DbArray with @NotNull 2019-12-17 16:42:09 +13:00
rob bygrave 590cd07d67 #1892 - Refactor change internal use of Ebean to DB 2019-12-13 14:20:51 +13:00
rob bygrave 5cd74bc468 #1892 - Refactor change internal use of Ebean to DB 2019-12-13 14:17:05 +13:00
rob bygrave 502b20be67 #1891 - Deprecate createSqlQuery() ... migrate to sqlQuery() 2019-12-13 13:58:14 +13:00
rob bygrave b3077d44f6 #1890 - Deprecate createSqlUpdate() ... migrate to sqlUpdate() 2019-12-13 13:48:53 +13:00
rob bygrave d4b35cb445 #1889 - NPE at Str.java:16) when using DB.sqlUpdate(...).addBatch() without any bind parameters 2019-12-13 13:35:54 +13:00
rob bygrave 91e7540a39 #1888 - Bump ebean-migration 12.1.2 with updated avaje classpath scanner 2019-12-13 13:06:13 +13:00
rob bygrave 06bd60aaf7 Bump to 12.1.8-SNAPSHOT to align version with query bean generator 2019-12-13 12:42:42 +13:00
rob bygrave 3db2a69312 #1885 - ENH: Add ModuleInfoLoader ... to support automatic registration of entity classes (via generated code using querybean generator) 2019-12-12 01:33:27 +13:00
rob bygrave 5a983b9e0d No effective change - fix spelling in comments 2019-12-11 23:22:30 +13:00
rob bygrave ab7b34779a [maven-release-plugin] prepare for next development iteration 2019-12-06 20:22:43 +13:00
rob bygrave c7aad6078e [maven-release-plugin] prepare release ebean-12.1.6 2019-12-06 20:22:33 +13:00
rob bygrave ccfe9c39cd Bump enhancement plugin 2019-12-06 20:19:17 +13:00
rob bygrave dbdac04883 Add more tests for cascade save on tree structure 2019-12-06 20:18:50 +13:00
rob bygrave 1d369c002d #1880 - Change javadoc references from Cdir to Cidr 2019-12-05 21:20:19 +13:00
rob bygrave 5a1be81603 #1881 - Update Postgres init helper procedures for DB table partitions 2019-12-05 20:10:15 +13:00
rob bygrave dee73da1aa Drop travis Postgres back to 9.6 2019-12-05 17:22:39 +13:00
rob bygrave a7dde87c5f Bump travis to Postgres 11.2 maybe ? 2019-12-05 17:20:23 +13:00
rob bygrave 60fadd448d Bump travis to Postgres 11 2019-12-05 17:12:58 +13:00
rob bygrave 0140d09007 Update tests to use io.avaje:mod-uuid 2019-12-05 10:32:19 +13:00
rob bygrave da5604a38d #1880 - Cidr type stored as INET (instead of CIDR) + named as Cdir (typo) 2019-12-05 08:59:39 +13:00
rob bygrave 937df1395c #1882 - ENH: Add JsonContext.toJsonPretty() ... for pretty JSON output of beans and lists of beans 2019-12-04 22:55:52 +13:00
rob bygrave 89c05007c2 #1881 - Update Postgres init helper procedures for DB table partitions 2019-12-04 22:07:05 +13:00
rob bygrave 4cc9278183 Update review ddl for Postgres 2019-12-04 21:29:58 +13:00
rob bygrave 9841a2c03a #1880 - Cidr type stored as INET (instead of CIDR) + named as Cdir (typo) 2019-12-04 21:28:27 +13:00
rob bygrave 74929472d9 #1879 - For metrics reporting for timed metrics with location by default only report on initial collection 2019-12-03 23:53:13 +13:00
rob bygrave e274a4c512 #1878 - Remove metric type from metric json output 2019-12-03 21:06:13 +13:00
rob bygrave 5d93c44475 #1877 - Adjust metric names add "orm." prefix for orm queries, "dto." for dto queries 2019-12-03 21:01:03 +13:00
rob bygrave 63b802d0b8 [maven-release-plugin] prepare for next development iteration 2019-12-03 10:19:47 +13:00
rob bygrave 1d7e751b60 [maven-release-plugin] prepare release ebean-12.1.5 2019-12-03 10:19:37 +13:00
rob bygrave 5f8690fb87 #1876 - findMap() does not use/hit natural key cache 2019-12-02 18:37:42 +13:00
rob bygrave e093675444 #1875 - Refactor simplify MetaTimedMetric removing unrequired getStartTime() and getBeanCount() 2019-11-29 23:42:00 +13:00
Rob BygraveandGitHub a04594540c #1873 - Refactor metrics reporting and collection, simplify removing MetricOrmQueryNode, MetricOrmQueryOrigin (#1874)
* #1873 - Refactor metrics reporting and collection, simplify removing MetricOrmQueryNode, MetricOrmQueryOrigin

* #1873 - fix test
2019-11-29 23:35:21 +13:00
rob bygrave 269f2de333 #1872 - Reporting ORM metrics defaults to suppressing sql and location after initial collection 2019-11-29 22:15:51 +13:00
rob bygrave be12910aec #1872 - Reporting ORM metrics defaults to suppressing sql and location after initial collection 2019-11-29 22:05:58 +13:00
rob bygrave 996e582a85 No effective change - add simple UnderscoreNamingConvention tests 2019-11-29 21:03:44 +13:00
rob bygrave aa4c6b7889 No effective change - add simple UnderscoreNamingConvention tests 2019-11-29 21:01:23 +13:00
rob bygrave 27a4e8951d #1870 - Whether DtoMeta.findproperty needs to add is prefix 2019-11-29 20:54:28 +13:00
rob bygrave 1fc4082abe #1869 - out of order nextId() sequence generation 2019-11-29 19:58:12 +13:00
rob bygrave 1c5d7a97e1 Bump pom to 12.1.5-SNAPSHOT 2019-11-29 17:19:23 +13:00
rob bygrave 67c2e1d24c #1871 - Add ability to write metrics in JSON form to Appendable 2019-11-29 17:19:01 +13:00
rob bygrave eb292e017e #1868 - Change the Metric "sqlHash" into a hash of the SQL + name + location 2019-11-20 20:15:32 +13:00
Rob BygraveandGitHub 88839f7613 Refactor rename method ProfileLocation.shortDescription() to location() (#1859) 2019-11-20 20:01:45 +13:00
rob bygrave ca71fef74a #1867 - Change enhancement for @DbArray ... to handle nulls (like OneToMany and ManyToMany) 2019-11-20 19:59:01 +13:00
rob bygrave 6c91ed0c76 #1866 - Refactor logging messages for L2 cache - "PUT ALL" -> "MPUT" 2019-11-20 00:26:26 +13:00
rob bygrave 8761c0486d #1865 - ENH: Add metric collection for ORM insert update and delete 2019-11-19 20:31:48 +13:00
rob bygrave fee6a9f04a Bump to 12.1.4 of the maven plugin 2019-11-19 20:28:23 +13:00
rob bygrave 17ff04e2b9 #1865 - ENH: Add metric collection for ORM insert update and delete 2019-11-19 20:27:04 +13:00
rob bygrave aa11095d17 Reduce to package visibility for internals BatchDepthComparator, BatchedBeanHolder, BatchedPstmtHolder 2019-11-18 23:14:25 +13:00
rob bygrave c2a30f786f #1864 - L2 cache miss for natural key property of type UUID 2019-11-17 17:06:38 +13:00
rob bygrave 9b0dd2b0c4 Turn off logging 2019-11-16 21:54:31 +13:00
rob bygrave aa96d10491 Refactor tidy after #1863. Add NaturalKeyEntrySimple for single property natural key lookup. 2019-11-16 21:48:37 +13:00
rob bygrave dfefbecf44 #1863 - L2 cache miss on natural key cache when multiple properties that include a ManyToOne 2019-11-16 17:03:34 +13:00
rob bygrave 738f19491a #1860 - Non failing test for - @PreUpdate is not working with .update()
Add a "other" property that is made dirty/set on preUpdate
2019-11-11 22:00:19 +13:00
rob bygrave 61257bea7f #1860 - Non failing test for - @PreUpdate is not working with .update() 2019-11-11 21:54:26 +13:00
rob bygrave 566a01d815 #1858 - Modify JSON dumped metrics to include metric type and location for timed metrics 2019-11-10 21:23:26 +13:00
rob bygrave a7116d1606 No effective change - tidy only 2019-11-10 11:36:28 +13:00
rob bygrave 615a2aea46 [maven-release-plugin] prepare for next development iteration 2019-11-07 16:43:25 +13:00
rob bygrave 20d538c428 [maven-release-plugin] prepare release ebean-12.1.3 2019-11-07 16:43:15 +13:00
rob bygrave 01054bf470 #1855 - Add MetaInfoManager collectMetricsAsJson() 2019-11-07 16:35:25 +13:00
rob bygrave affd720390 #1854 - Use profile location label to automatically give good metric name for @Transactional (with profile location enhancement) 2019-11-07 11:18:26 +13:00
rob bygrave 7d77df58c5 #1780 - Add tests for this RawSql case 2019-11-06 23:30:21 +13:00
rob bygrave 51fad2dec6 Refactor CQueryBuilder extract method, no effective change. 2019-11-06 23:29:33 +13:00
rob bygrave 997378ce72 Refactor internal XServiceProvider service loading 2019-11-06 22:01:37 +13:00
rob bygrave 1a8a43603e #1849 - JoinColumn not found when using @Encrypted(dbEncryption = true) and findCount 2019-11-06 20:33:56 +13:00
rob bygrave d2c88bf7c6 #1853 - Classpath problem with avaje-classpath-scanner 2019-11-06 19:53:35 +13:00
rob bygrave 0929147b08 No effective change - tidy test TestQueryFindPagedList 2019-10-18 17:23:31 +13:00
rob bygrave ecab219635 #1848 - ENH: Add EmptyPagedList ... as helper implementation of PagedList<T> 2019-10-18 17:22:19 +13:00
rob bygrave 7a974320ed #1846 - Test for - Inheritance cascade of fields with bean inheritance
Note this includes the workaround RootBean.preRemove(), so doesn't fail
2019-10-18 16:20:38 +13:00
rob bygrave 1b7dc83a9a ENH: Add DB.getBeanId() ... to match database.getBeanId() 2019-10-18 16:08:42 +13:00
rob bygrave 9827d9056f No effective change - add delete batch test with M2M generated sql 2019-10-18 15:51:18 +13:00
rob bygrave c8d5d9b552 No effective change - update test 2019-10-18 15:38:50 +13:00
rob bygrave dac55ab8e9 #1847 - Delete bean with ManyToMany to always delete from intersection (not required cascade REMOVE) 2019-10-18 15:35:21 +13:00
rob bygrave de75bcdaf9 [maven-release-plugin] prepare for next development iteration 2019-10-17 15:25:28 +13:00
3691 changed files with 45623 additions and 47736 deletions
+2 -3
View File
@@ -1,15 +1,14 @@
dist: trusty
dist: xenial
sudo: required
language: java
jdk:
- oraclejdk8
- openjdk11
git:
depth: 3
addons:
postgresql: "9.6"
postgresql: 10
# apt:
# packages:
# - mysql-server-5.7
+8 -1
View File
@@ -7,4 +7,11 @@ do
echo ${file}
cat ${file}
echo
done
done
for file in ebean-autotune/target/surefire-reports/*.txt
do
echo ${file}
cat ${file}
echo
done
+141
View File
@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.5.2-SNAPSHOT</version>
</parent>
<artifactId>ebean-api</artifactId>
<properties>
<jackson-core.version>2.11.3</jackson-core.version>
<jackson-databind.version>2.11.3</jackson-databind.version>
</properties>
<dependencies>
<!--
Projects are expected to explicit depend on version
of slf4j that they want to use
-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-config</artifactId>
<version>1.1</version>
</dependency>
<!--
Class retention Nonnull and Nullable annotations
to assist with IDE auto-completion with Ebean API
-->
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-jsr305</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>persistence-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-annotation</artifactId>
<version>6.13</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-types</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>6.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>12.1.4</version>
</dependency>
<!-- Jackson core used internally by Ebean -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-core.version}</version>
<optional>true</optional>
</dependency>
<!-- provided scope for JsonNode support -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-databind.version}</version>
<optional>true</optional>
</dependency>
<!-- Provided scope so that the H2HistoryTrigger can live in Ebean core
and not require a separate module for it -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.199</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
<optional>true</optional>
</dependency>
<!-- provided scope to read validation annotations Size etc -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<archive>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -31,15 +31,18 @@ public interface BackgroundExecutor {
* Execute a task periodically with a fixed delay between each execution.
* <p>
* For example, execute a runnable every minute.
* </p>
* <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)}
* </p>
*/
void executePeriodically(Runnable r, long delay, TimeUnit unit);
/**
* Execute a task periodically additionally with an initial delay different from delay.
*/
void executePeriodically(Runnable r, long initialDelay, long delay, TimeUnit unit);
/**
* Schedules a Runnable for one-shot action that becomes enabled after the given delay.
*
@@ -14,7 +14,7 @@ import java.util.Optional;
*
* public class CustomerFinder extends BeanFinder<Long,Customer> {
*
* @Inject
* Inject
* public CustomerFinder(Database database) {
* super(Customer.class, database);
* }
@@ -9,10 +9,10 @@ import java.util.Collection;
* <p>
* <pre>{@code
*
* @Repository
* Repository
* public class CustomerRepository extends BeanRepository<Long,Customer> {
*
* @Inject
* Inject
* public CustomerRepository(Database server) {
* super(Customer.class, server);
* }
@@ -2,7 +2,6 @@ package io.ebean;
import io.ebean.annotation.TxIsolation;
import io.ebean.cache.ServerCacheManager;
import io.ebean.config.DatabaseConfig;
import io.ebean.plugin.Property;
import io.ebean.text.csv.CsvReader;
import io.ebean.text.json.JsonContext;
@@ -61,7 +60,9 @@ import java.util.concurrent.Callable;
*
* }</pre>
*/
public class DB {
public final class DB {
private static final DbContext context = DbContext.getInstance();
/**
* Hide constructor.
@@ -73,7 +74,7 @@ public class DB {
* Return the default database.
*/
public static Database getDefault() {
return Ebean.getDefaultServer();
return context.getDefault();
}
/**
@@ -82,25 +83,24 @@ public class DB {
* @param name The name of the database
*/
public static Database byName(String name) {
return Ebean.getServer(name);
return context.get(name);
}
// /**
// * Register the server with this Ebean singleton. Specify if the registered
// * server is the primary/default server.
// */
// public static void register(EbeanServer server, boolean defaultServer) {
// serverMgr.register(server, defaultServer);
// }
//
// /**
// * Backdoor for registering a mock implementation of EbeanServer as the default server.
// */
// protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
// EbeanServer originalPrimaryServer = serverMgr.defaultServer;
// serverMgr.registerWithName(name, server, defaultServer);
// return originalPrimaryServer;
// }
/**
* Return the ScriptRunner for the default database.
* <p>
* Useful to run SQL scripts that are resources. For example a test script
* for inserting seed data for a particular test.
*
* <pre>{@code
*
* DB.script().run("/scripts/test-script.sql")
*
* }</pre>
*/
public static ScriptRunner script() {
return getDefault().script();
}
/**
* Return the ExpressionFactory from the default database.
@@ -177,6 +177,18 @@ public class DB {
return getDefault().beginTransaction();
}
/**
* Create a new transaction that is not held in TransactionThreadLocal.
* <p>
* 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();
}
/**
* Start a transaction additionally specifying the isolation level.
*
@@ -443,6 +455,13 @@ public class DB {
return getDefault().saveAll(beans);
}
/**
* Save all the beans from a Collection.
*/
public static int saveAll(Object... beans) throws OptimisticLockException {
return getDefault().saveAll(beans);
}
/**
* This method checks the uniqueness of a bean. I.e. if the save will work. It will return the
* properties that violates an unique / primary key. This may be done in an UI save action to
@@ -651,7 +670,7 @@ public class DB {
* // find orders and their customers
* List<Order> list = DB.find(Order.class)
* .fetch("customer")
* .orderBy("id")
* .order("id")
* .findList();
*
* // sort by customer name ascending, then by order shipDate
@@ -737,8 +756,11 @@ public class DB {
}
/**
* Deprecated - migrate to sqlQuery().
* <p>
* This is an alias for {@link #sqlQuery(String)}.
*/
@Deprecated
public static SqlQuery createSqlQuery(String sql) {
return sqlQuery(sql);
}
@@ -761,8 +783,11 @@ public class DB {
}
/**
* Deprecated - migrate to sqlUpdate().
* <p>
* This is an alias for {@link #sqlUpdate(String)}.
*/
@Deprecated
public static SqlUpdate createSqlUpdate(String sql) {
return sqlUpdate(sql);
}
@@ -1203,6 +1228,13 @@ public class DB {
return getDefault().getBeanState(bean);
}
/**
* Return the value of the Id property for a given bean.
*/
public static Object getBeanId(Object bean) {
return getDefault().getBeanId(bean);
}
/**
* Return the manager of the level 2 cache ("L2" cache).
*/
@@ -1,9 +1,9 @@
package io.ebean;
import io.ebean.annotation.Platform;
import io.ebean.annotation.TxIsolation;
import io.ebean.cache.ServerCacheManager;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.ServerConfig;
import io.ebean.meta.MetaInfoManager;
import io.ebean.plugin.Property;
import io.ebean.plugin.SpiServer;
@@ -93,6 +93,11 @@ import java.util.concurrent.Callable;
*/
public interface Database {
/**
* Shutdown the Database instance.
*/
void shutdown();
/**
* Shutdown the Database instance programmatically.
* <p>
@@ -123,7 +128,7 @@ public interface Database {
String getName();
/**
* Return the ExpressionFactory for this server.
* Return the ExpressionFactory for this database.
*/
ExpressionFactory getExpressionFactory();
@@ -133,6 +138,25 @@ public interface Database {
*/
MetaInfoManager getMetaInfoManager();
/**
* Return the platform used for this database instance.
* <p>
* Note many platforms have multiple specific platform types so often we want to
* get the base platform via {@link Platform#base()}.
* </p>
* <pre>{@code
*
* Platform platform = database.getPlatform().base();
* if (platform == Platform.MYSQL) {
* // do MySql specific function
* }
*
* }</pre>
*
* @return platform for this database instance
*/
Platform getPlatform();
/**
* Return the extended API intended for use by plugins.
*/
@@ -376,7 +400,7 @@ public interface Database {
* // find orders and their customers
* List<Order> list = database.find(Order.class)
* .fetch("customer")
* .orderBy("id")
* .order("id")
* .findList();
*
* // sort by customer name ascending, then by order shipDate
@@ -465,8 +489,11 @@ 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);
/**
@@ -485,8 +512,11 @@ 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);
/**
@@ -856,7 +886,7 @@ public interface Database {
* <pre>{@code
* public class Order { ...
*
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
* OneToMany(cascade=CascadeType.ALL, mappedBy="order")
* List<OrderDetail> details;
* ...
* }
@@ -876,6 +906,11 @@ public interface Database {
*/
int saveAll(Collection<?> beans) throws OptimisticLockException;
/**
* Save all the beans.
*/
int saveAll(Object... beans) throws OptimisticLockException;
/**
* Delete the bean.
* <p>
@@ -1051,7 +1086,6 @@ public interface Database {
* Integer returnValue = (Integer) cs.getObject(3);
*
* }</pre>
*
*/
int execute(CallableSql callableSql);
@@ -1299,7 +1333,7 @@ public interface Database {
* public void run() {
* User u1 = database.find(User.class, 1);
* ...
* }
* }
* });
*
* }</pre>
@@ -1348,7 +1382,7 @@ public interface Database {
* User u1 = database.find(User.class, 1);
* ...
* return u1.getEmail();
* }
* }
* });
*
* }</pre>
@@ -0,0 +1,157 @@
package io.ebean;
import io.ebean.config.ContainerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.service.SpiContainer;
import io.ebean.service.SpiContainerFactory;
import javax.persistence.PersistenceException;
import java.util.Iterator;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.concurrent.locks.ReentrantLock;
/**
* Creates Database instances.
* <p>
* This uses either DatabaseConfig or properties in the application.properties file to
* configure and create a Database instance.
* </p>
* <p>
* The Database instance can either be registered with the DB singleton or
* not. The DB singleton effectively holds a map of Database by a name.
* If the Database is registered with the DB singleton you can retrieve it
* later via {@link DB#byName(String)}.
* </p>
* <p>
* One Database can be nominated as the 'default/primary' Database. Many
* methods on the DB singleton such as {@link DB#find(Class)} are just a
* convenient way of using the 'default/primary' Database.
* </p>
*/
public class DatabaseFactory {
private static final ReentrantLock lock = new ReentrantLock(false);
private static SpiContainer container;
static {
EbeanVersion.getVersion();
}
/**
* Initialise the container with clustering configuration.
* <p>
* Call this prior to creating any Database instances or alternatively set the
* ContainerConfig on the DatabaseConfig when creating the first Database instance.
*/
public static void initialiseContainer(ContainerConfig containerConfig) {
lock.lock();
try {
getContainer(containerConfig);
} finally {
lock.unlock();
}
}
/**
* Create using properties to configure the database.
*/
public static Database create(String name) {
lock.lock();
try {
return getContainer(null).createServer(name);
} finally {
lock.unlock();
}
}
/**
* Create using the DatabaseConfig object to configure the database.
*/
public static Database create(DatabaseConfig config) {
lock.lock();
try {
if (config.getName() == null) {
throw new PersistenceException("The name is null (it is required)");
}
Database server = createInternal(config);
if (config.isRegister()) {
DbPrimary.setSkip(true);
DbContext.getInstance().register(server, config.isDefaultServer());
}
return server;
} finally {
lock.unlock();
}
}
/**
* Create using the DatabaseConfig additionally specifying a classLoader to use as the context class loader.
*/
public static Database createWithContextClassLoader(DatabaseConfig config, ClassLoader classLoader) {
lock.lock();
try {
ClassLoader currentContextLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
try {
return DatabaseFactory.create(config);
} finally {
// set the currentContextLoader back
Thread.currentThread().setContextClassLoader(currentContextLoader);
}
} finally {
lock.unlock();
}
}
/**
* Shutdown gracefully all Database instances cleaning up any resources as required.
* <p>
* This is typically invoked via JVM shutdown hook and not explicitly called.
* </p>
*/
public static void shutdown() {
lock.lock();
try {
container.shutdown();
} finally {
lock.unlock();
}
}
private static Database createInternal(DatabaseConfig config) {
return getContainer(config.getContainerConfig()).createServer(config);
}
/**
* Get the EbeanContainer initialising it if necessary.
*
* @param containerConfig the configuration controlling clustering communication
*/
private static SpiContainer getContainer(ContainerConfig containerConfig) {
// thread safe in that all calling methods hold lock
if (container != null) {
return container;
}
if (containerConfig == null) {
// effectively load configuration from ebean.properties
Properties properties = DbPrimary.getProperties();
containerConfig = new ContainerConfig();
containerConfig.loadFromProperties(properties);
}
container = createContainer(containerConfig);
return container;
}
/**
* Create the container instance using the configuration.
*/
protected static SpiContainer createContainer(ContainerConfig containerConfig) {
Iterator<SpiContainerFactory> factories = ServiceLoader.load(SpiContainerFactory.class).iterator();
if (factories.hasNext()) {
return factories.next().create(containerConfig);
}
throw new IllegalStateException("Service loader didn't find a SpiContainerFactory?");
}
}
@@ -0,0 +1,139 @@
package io.ebean;
import io.ebean.config.BeanNotEnhancedException;
import io.ebean.datasource.DataSourceConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.PersistenceException;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
/**
* Holds Database instances.
*/
final class DbContext {
private static final Logger logger = LoggerFactory.getLogger(DbContext.class);
static {
EbeanVersion.getVersion();
}
private static final DbContext INSTANCE = new DbContext();
private final ConcurrentHashMap<String, Database> concMap = new ConcurrentHashMap<>();
private final HashMap<String, Database> syncMap = new HashMap<>();
private final ReentrantLock lock = new ReentrantLock(false);
/**
* The 'default' Database.
*/
private Database defaultDatabase;
private DbContext() {
try {
if (!DbPrimary.isSkip()) {
// look to see if there is a default server defined
String defaultName = DbPrimary.getDefaultServerName();
logger.debug("defaultName:{}", defaultName);
if (defaultName != null && !defaultName.trim().isEmpty()) {
defaultDatabase = getWithCreate(defaultName.trim());
}
}
} catch (BeanNotEnhancedException e) {
throw e;
} catch (DataSourceConfigurationException e) {
String msg = "Configuration error creating DataSource for the default Database." +
" This typically means a missing application-test.yaml or missing ebean-test dependency." +
" See https://ebean.io/docs/trouble-shooting#datasource";
throw new DataSourceConfigurationException(msg, e);
} catch (Throwable e) {
logger.error("Error trying to create the default Database", e);
throw new RuntimeException(e);
}
}
/**
* Return the shared singleton instance.
*/
static DbContext getInstance() {
return INSTANCE;
}
/**
* Return the default database.
*/
Database getDefault() {
if (defaultDatabase == null) {
String msg = "The default Database has not been defined?";
msg += " This is normally set via the ebean.datasource.default property.";
msg += " Otherwise it should be registered programmatically via registerServer()";
throw new PersistenceException(msg);
}
return defaultDatabase;
}
/**
* Return the database by name.
*/
Database get(String name) {
if (name == null || name.isEmpty()) {
return defaultDatabase;
}
Database server = concMap.get(name);
if (server != null) {
return server;
}
return getWithCreate(name);
}
/**
* Read, create and put of Databases.
*/
private Database getWithCreate(String name) {
lock.lock();
try {
Database server = syncMap.get(name);
if (server == null) {
// register when creating server this way
server = DatabaseFactory.create(name);
register(server, false);
}
return server;
} finally {
lock.unlock();
}
}
/**
* Register a server so we can get it by its name.
*/
void register(Database server, boolean isDefault) {
registerWithName(server.getName(), server, isDefault);
}
private void registerWithName(String name, Database server, boolean isDefault) {
lock.lock();
try {
concMap.put(name, server);
syncMap.put(name, server);
if (isDefault) {
defaultDatabase = server;
}
} finally {
lock.unlock();
}
}
Database mock(String name, Database server, boolean defaultServer) {
Database originalPrimaryServer = this.defaultDatabase;
registerWithName(name, server, defaultServer);
return originalPrimaryServer;
}
}
@@ -0,0 +1,96 @@
package io.ebean;
import io.avaje.config.Config;
import java.util.Properties;
import java.util.concurrent.locks.ReentrantLock;
/**
* Provides singleton state for the default database.
* <p/>
* Intended for internal use as part of bootup, construction, registration of the default database.
*/
class DbPrimary {
private static final ReentrantLock lock = new ReentrantLock(false);
private static String defaultServerName;
private static boolean skip;
/**
* Set whether to skip automatically creating the primary database.
*/
static void setSkip(boolean skip) {
lock.lock();
try {
DbPrimary.skip = skip;
} finally {
lock.unlock();
}
}
/**
* Return true to skip automatically creating the primary database.
*/
static boolean isSkip() {
lock.lock();
try {
return skip;
} finally {
lock.unlock();
}
}
/**
* Return the default database name.
*/
static String getDefaultServerName() {
lock.lock();
try {
getProperties();
return defaultServerName;
} finally {
lock.unlock();
}
}
/**
* Return the default configuration Properties.
*/
static Properties getProperties() {
lock.lock();
try {
if (defaultServerName == null) {
defaultServerName = determineDefaultServerName();
}
return Config.asProperties();
} finally {
lock.unlock();
}
}
/**
* Determine and return the default server name checking system environment variables and then global properties.
*/
private static String determineDefaultServerName() {
String defaultServerName = System.getenv("EBEAN_DB");
defaultServerName = System.getProperty("db", defaultServerName);
defaultServerName = System.getProperty("ebean_db", defaultServerName);
if (isEmpty(defaultServerName)) {
defaultServerName = Config.get("datasource.default", null);
if (isEmpty(defaultServerName)) {
defaultServerName = Config.get("ebean.default.datasource", null);
}
}
if (defaultServerName == null) {
defaultServerName = "db";
}
return defaultServerName;
}
/**
* Return true if the string is null or empty.
*/
private static boolean isEmpty(String value) {
return value == null || value.trim().isEmpty();
}
}
@@ -1,7 +1,7 @@
package io.ebean;
import io.ebeanservice.docstore.api.DocQueryRequest;
import io.ebeanservice.docstore.api.RawDoc;
import io.ebean.docstore.DocQueryContext;
import io.ebean.docstore.RawDoc;
import javax.annotation.Nullable;
import java.io.IOException;
@@ -61,7 +61,7 @@ public interface DocumentStore {
* <pre>{@code
*
* Customer customer =
* server.find(Customer.class)
* database.find(Customer.class)
* .setUseDocStore(true)
* .setId(42)
* .findOne();
@@ -69,7 +69,7 @@ public interface DocumentStore {
* }</pre>
*/
@Nullable
<T> T find(DocQueryRequest<T> request);
<T> T find(DocQueryContext<T> request);
/**
* Execute the find list query. This request is prepared to execute secondary queries.
@@ -79,14 +79,14 @@ public interface DocumentStore {
* <pre>{@code
*
* List<Customer> newCustomers =
* server.find(Customer.class)
* database.find(Customer.class)
* .setUseDocStore(true)
* .where().eq("status, Customer.Status.NEW)
* .findList();
*
* }</pre>
*/
<T> List<T> findList(DocQueryRequest<T> request);
<T> List<T> findList(DocQueryContext<T> request);
/**
* Execute the query against the document store returning the paged list.
@@ -99,7 +99,7 @@ public interface DocumentStore {
* <pre>{@code
*
* PagedList<Customer> newCustomers =
* server.find(Customer.class)
* database.find(Customer.class)
* .setUseDocStore(true)
* .where().eq("status, Customer.Status.NEW)
* .setMaxRows(50)
@@ -107,7 +107,7 @@ public interface DocumentStore {
*
* }</pre>
*/
<T> PagedList<T> findPagedList(DocQueryRequest<T> request);
<T> PagedList<T> findPagedList(DocQueryContext<T> request);
/**
* Execute the query against the document store with the expectation of a large set of results
@@ -120,7 +120,7 @@ public interface DocumentStore {
* </p>
* <pre>{@code
*
* server.find(Order.class)
* database.find(Order.class)
* .setUseDocStore(true)
* .where()... // perhaps add predicates
* .findEach((Order order) -> {
@@ -129,7 +129,7 @@ public interface DocumentStore {
*
* }</pre>
*/
<T> void findEach(DocQueryRequest<T> query, Consumer<T> consumer);
<T> void findEach(DocQueryContext<T> query, Consumer<T> consumer);
/**
* Execute the query against the document store with the expectation of a large set of results
@@ -145,11 +145,11 @@ public interface DocumentStore {
* </p>
* <pre>{@code
*
* server.find(Order.class)
* database.find(Order.class)
* .setUseDocStore(true)
* .where()... // perhaps add predicates
* .findEachWhile(new Predicate<Order>() {
* @Override
* Override
* public void accept(Order bean) {
* // process the bean
*
@@ -161,7 +161,7 @@ public interface DocumentStore {
*
* }</pre>
*/
<T> void findEachWhile(DocQueryRequest<T> query, Predicate<T> consumer);
<T> void findEachWhile(DocQueryContext<T> query, Predicate<T> consumer);
/**
* Find each processing raw documents.
@@ -190,7 +190,7 @@ public interface DocumentStore {
* Drop the index from the document store (similar to DDL drop table).
* <pre>{@code
*
* DocumentStore documentStore = server.docStore();
* DocumentStore documentStore = database.docStore();
*
* documentStore.dropIndex("product_copy");
*
@@ -202,7 +202,7 @@ public interface DocumentStore {
* Create an index given a mapping file as a resource in the classPath (similar to DDL create table).
* <pre>{@code
*
* DocumentStore documentStore = server.docStore();
* DocumentStore documentStore = database.docStore();
*
* // uses product_copy.mapping.json resource
* // ... to define mappings for the index
@@ -289,7 +289,7 @@ public interface DocumentStore {
* <pre>{@code
*
* // predicates to select the source documents to copy
* Query<Product> query = server.find(Product.class)
* Query<Product> query = database.find(Product.class)
* .where()
* .ge("whenModified", new Timestamp(since))
* .ge("name", "A")
@@ -77,12 +77,29 @@ public interface DtoQuery<T> {
Optional<T> findOneOrEmpty();
/**
* The same as bind for named parameters.
* Bind all the parameters using index positions.
* <p>
* Binds each parameter moving the index position each time.
* <p>
* A convenience for multiple calls to {@link #setParameter(Object)}
*/
DtoQuery<T> setParameters(Object... value);
/**
* Bind the next parameter using index position.
* <p>
* Bind the parameter using index position starting at 1 and incrementing.
* <p>
*/
DtoQuery<T> setParameter(Object value);
/**
* Bind the named parameter.
*/
DtoQuery<T> setParameter(String name, Object value);
/**
* The same as bind for positioned parameters.
* Bind the parameter by its index position (1 based like JDBC).
*/
DtoQuery<T> setParameter(int position, Object value);
@@ -136,4 +153,8 @@ public interface DtoQuery<T> {
*/
DtoQuery<T> setBufferFetchSizeHint(int bufferFetchSizeHint);
/**
* Use the explicit transaction to execute the query.
*/
DtoQuery<T> usingTransaction(Transaction transaction);
}
@@ -2,152 +2,33 @@ package io.ebean;
import io.ebean.annotation.TxIsolation;
import io.ebean.cache.ServerCacheManager;
import io.ebean.config.BeanNotEnhancedException;
import io.ebean.config.ServerConfig;
import io.ebean.datasource.DataSourceConfigurationException;
import io.ebean.plugin.Property;
import io.ebean.text.csv.CsvReader;
import io.ebean.text.json.JsonContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
/**
* Deprecated - please migrate to use <code>io.ebean.DB</code>.
* <p>
* Ebean is a registry of {@link Database} by name. Ebean has now been renamed to {@link DB}.
* <p>
* Ebean is effectively this is an alias for {@link DB} which is the new and improved name for Ebean.
* <p>
* The preference is to use DB and Database rather than Ebean and EbeanServer.
*/
@Deprecated
public final class Ebean {
private static final Logger logger = LoggerFactory.getLogger(Ebean.class);
static {
EbeanVersion.getVersion(); // initialises the version class and logs the version.
}
/**
* Manages creation and cache of Databases.
*/
private static final Ebean.ServerManager serverMgr = new Ebean.ServerManager();
/**
* Helper class for managing fast and safe access and creation of Databases.
*/
private static final class ServerManager {
/**
* Cache for fast concurrent read access.
*/
private final ConcurrentHashMap<String, EbeanServer> concMap = new ConcurrentHashMap<>();
/**
* Cache for synchronized read, creation and put. Protected by the monitor object.
*/
private final HashMap<String, EbeanServer> syncMap = new HashMap<>();
private final Object monitor = new Object();
/**
* The 'default' Database.
*/
private EbeanServer defaultServer;
private ServerManager() {
try {
if (!PrimaryServer.isSkip()) {
// look to see if there is a default server defined
String defaultName = PrimaryServer.getDefaultServerName();
logger.debug("defaultName:{}", defaultName);
if (defaultName != null && !defaultName.trim().isEmpty()) {
defaultServer = getWithCreate(defaultName.trim());
}
}
} catch (BeanNotEnhancedException e) {
throw e;
} catch (DataSourceConfigurationException e) {
String msg = "Configuration error creating DataSource for the default Database." +
" This typically means a missing application-test.yaml or missing ebean-test-config dependency." +
" See https://ebean.io/docs/trouble-shooting#datasource";
throw new DataSourceConfigurationException(msg, e);
} catch (Throwable e) {
logger.error("Error trying to create the default Database", e);
throw new RuntimeException(e);
}
}
private EbeanServer getDefaultServer() {
if (defaultServer == null) {
String msg = "The default Database has not been defined?";
msg += " This is normally set via the ebean.datasource.default property.";
msg += " Otherwise it should be registered programmatically via registerServer()";
throw new PersistenceException(msg);
}
return defaultServer;
}
private EbeanServer get(String name) {
if (name == null || name.isEmpty()) {
return defaultServer;
}
// non-synchronized read
EbeanServer server = concMap.get(name);
if (server != null) {
return server;
}
// synchronized read, create and put
return getWithCreate(name);
}
/**
* Synchronized read, create and put of Databases.
*/
private EbeanServer getWithCreate(String name) {
synchronized (monitor) {
EbeanServer server = syncMap.get(name);
if (server == null) {
// register when creating server this way
server = EbeanServerFactory.create(name);
register(server, false);
}
return server;
}
}
/**
* Register a server so we can get it by its name.
*/
private void register(EbeanServer server, boolean isDefaultServer) {
registerWithName(server.getName(), server, isDefaultServer);
}
private void registerWithName(String name, EbeanServer server, boolean isDefaultServer) {
synchronized (monitor) {
concMap.put(name, server);
syncMap.put(name, server);
if (isDefaultServer) {
defaultServer = server;
}
}
}
}
private static final DbContext context = DbContext.getInstance();
private Ebean() {
}
@@ -171,7 +52,7 @@ public final class Ebean {
* @param name the name of the server, can use null for the 'default server'
*/
public static EbeanServer getServer(String name) {
return serverMgr.get(name);
return (EbeanServer)context.get(name);
}
/**
@@ -181,11 +62,31 @@ public final class Ebean {
* </p>
*/
public static EbeanServer getDefaultServer() {
return serverMgr.getDefaultServer();
return (EbeanServer)context.getDefault();
}
/**
* Return the ExpressionFactory from the default server.
* Register the server with this Ebean singleton. Specify if the registered
* server is the primary/default database.
*/
@Deprecated
public static void register(EbeanServer server, boolean defaultServer) {
context.register(server, defaultServer);
}
/**
* Backdoor for registering a mock implementation of EbeanServer as the default database.
*/
protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
return (EbeanServer)context.mock(name, server, defaultServer);
}
private static Database getDefault() {
return context.getDefault();
}
/**
* Return the ExpressionFactory from the default database.
* <p>
* The ExpressionFactory is used internally by the query and ExpressionList to
* build the WHERE and HAVING clauses. Alternatively you can use the
@@ -202,24 +103,7 @@ public final class Ebean {
* </p>
*/
public static ExpressionFactory getExpressionFactory() {
return serverMgr.getDefaultServer().getExpressionFactory();
}
/**
* Register the server with this Ebean singleton. Specify if the registered
* server is the primary/default server.
*/
public static void register(EbeanServer server, boolean defaultServer) {
serverMgr.register(server, defaultServer);
}
/**
* Backdoor for registering a mock implementation of EbeanServer as the default server.
*/
protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
EbeanServer originalPrimaryServer = serverMgr.defaultServer;
serverMgr.registerWithName(name, server, defaultServer);
return originalPrimaryServer;
return getDefault().getExpressionFactory();
}
/**
@@ -235,7 +119,7 @@ public final class Ebean {
* </p>
*/
public static Object nextId(Class<?> beanType) {
return serverMgr.getDefaultServer().nextId(beanType);
return getDefault().nextId(beanType);
}
/**
@@ -281,7 +165,7 @@ public final class Ebean {
* </p>
*/
public static Transaction beginTransaction() {
return serverMgr.getDefaultServer().beginTransaction();
return getDefault().beginTransaction();
}
/**
@@ -290,7 +174,7 @@ public final class Ebean {
* @param isolation the Transaction isolation level
*/
public static Transaction beginTransaction(TxIsolation isolation) {
return serverMgr.getDefaultServer().beginTransaction(isolation);
return getDefault().beginTransaction(isolation);
}
/**
@@ -343,7 +227,7 @@ public final class Ebean {
* }</pre>
*/
public static Transaction beginTransaction(TxScope scope) {
return serverMgr.getDefaultServer().beginTransaction(scope);
return getDefault().beginTransaction(scope);
}
/**
@@ -351,7 +235,7 @@ public final class Ebean {
* in scope.
*/
public static Transaction currentTransaction() {
return serverMgr.getDefaultServer().currentTransaction();
return getDefault().currentTransaction();
}
/**
@@ -381,21 +265,21 @@ public final class Ebean {
* @throws PersistenceException if there is no currently active transaction
*/
public static void register(TransactionCallback transactionCallback) throws PersistenceException {
serverMgr.getDefaultServer().register(transactionCallback);
getDefault().register(transactionCallback);
}
/**
* Commit the current transaction.
*/
public static void commitTransaction() {
serverMgr.getDefaultServer().commitTransaction();
getDefault().commitTransaction();
}
/**
* Rollback the current transaction.
*/
public static void rollbackTransaction() {
serverMgr.getDefaultServer().rollbackTransaction();
getDefault().rollbackTransaction();
}
/**
@@ -423,14 +307,14 @@ public final class Ebean {
* }</pre>
*/
public static void endTransaction() {
serverMgr.getDefaultServer().endTransaction();
getDefault().endTransaction();
}
/**
* Mark the current transaction as rollback only.
*/
public static void setRollbackOnly() {
serverMgr.getDefaultServer().currentTransaction().setRollbackOnly();
getDefault().currentTransaction().setRollbackOnly();
}
/**
@@ -441,7 +325,7 @@ public final class Ebean {
* </p>
*/
public static Map<String, ValuePair> diff(Object a, Object b) {
return serverMgr.getDefaultServer().diff(a, b);
return getDefault().diff(a, b);
}
/**
@@ -462,7 +346,7 @@ public final class Ebean {
* <pre>{@code
* public class Order { ...
*
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
* OneToMany(cascade=CascadeType.ALL, mappedBy="order")
* List<OrderDetail> details;
* ...
* }
@@ -475,7 +359,7 @@ public final class Ebean {
* </p>
*/
public static void save(Object bean) throws OptimisticLockException {
serverMgr.getDefaultServer().save(bean);
getDefault().save(bean);
}
/**
@@ -483,14 +367,14 @@ public final class Ebean {
* want to explicitly insert it.
*/
public static void insert(Object bean) {
serverMgr.getDefaultServer().insert(bean);
getDefault().insert(bean);
}
/**
* Insert a collection of beans.
*/
public static void insertAll(Collection<?> beans) {
serverMgr.getDefaultServer().insertAll(beans);
getDefault().insertAll(beans);
}
/**
@@ -513,7 +397,7 @@ public final class Ebean {
* }</pre>
*/
public static void markAsDirty(Object bean) throws OptimisticLockException {
serverMgr.getDefaultServer().markAsDirty(bean);
getDefault().markAsDirty(bean);
}
/**
@@ -528,16 +412,6 @@ public final class Ebean {
* <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>
* <b>{@link ServerConfig#setUpdatesDeleteMissingChildren(boolean)}: </b> When cascade saving to a
* OneToMany or ManyToMany the updatesDeleteMissingChildren setting controls if any other children
* that are in the database but are not in the collection are deleted.
* </p>
* <p>
* <b>{@link ServerConfig#setUpdateChangesOnly(boolean)}: </b> The updateChangesOnly setting
* controls if only the changed properties are included in the update or if all the loaded
* properties are included instead.
* </p>
* <pre>{@code
*
* // A 'stateless update' example
@@ -550,14 +424,14 @@ public final class Ebean {
* }</pre>
*/
public static void update(Object bean) throws OptimisticLockException {
serverMgr.getDefaultServer().update(bean);
getDefault().update(bean);
}
/**
* Update the beans in the collection.
*/
public static void updateAll(Collection<?> beans) throws OptimisticLockException {
serverMgr.getDefaultServer().updateAll(beans);
getDefault().updateAll(beans);
}
/**
@@ -566,7 +440,7 @@ public final class Ebean {
* @param bean The bean to merge
*/
public static void merge(Object bean) {
serverMgr.getDefaultServer().merge(bean);
getDefault().merge(bean);
}
/**
@@ -576,14 +450,14 @@ public final class Ebean {
* @param options The options to control the merge
*/
public static void merge(Object bean, MergeOptions options) {
serverMgr.getDefaultServer().merge(bean, options);
getDefault().merge(bean, options);
}
/**
* Save all the beans from a Collection.
*/
public static int saveAll(Collection<?> beans) throws OptimisticLockException {
return serverMgr.getDefaultServer().saveAll(beans);
return getDefault().saveAll(beans);
}
/**
@@ -634,7 +508,7 @@ public final class Ebean {
*/
@Nonnull
public static Set<Property> checkUniqueness(Object bean) {
return serverMgr.getDefaultServer().checkUniqueness(bean);
return getDefault().checkUniqueness(bean);
}
/**
@@ -642,7 +516,7 @@ public final class Ebean {
*/
@Nonnull
public static Set<Property> checkUniqueness(Object bean, Transaction transaction) {
return serverMgr.getDefaultServer().checkUniqueness(bean, transaction);
return getDefault().checkUniqueness(bean, transaction);
}
/**
@@ -665,56 +539,56 @@ public final class Ebean {
* </p>
*/
public static boolean delete(Object bean) throws OptimisticLockException {
return serverMgr.getDefaultServer().delete(bean);
return getDefault().delete(bean);
}
/**
* Delete the bean in permanent fashion (will not use soft delete).
*/
public static boolean deletePermanent(Object bean) throws OptimisticLockException {
return serverMgr.getDefaultServer().deletePermanent(bean);
return getDefault().deletePermanent(bean);
}
/**
* Delete the bean given its type and id.
*/
public static int delete(Class<?> beanType, Object id) {
return serverMgr.getDefaultServer().delete(beanType, id);
return getDefault().delete(beanType, id);
}
/**
* Delete permanent the bean given its type and id.
*/
public static int deletePermanent(Class<?> beanType, Object id) {
return serverMgr.getDefaultServer().deletePermanent(beanType, id);
return getDefault().deletePermanent(beanType, id);
}
/**
* Delete several beans given their type and id values.
*/
public static int deleteAll(Class<?> beanType, Collection<?> ids) {
return serverMgr.getDefaultServer().deleteAll(beanType, ids);
return getDefault().deleteAll(beanType, ids);
}
/**
* Delete permanent several beans given their type and id values.
*/
public static int deleteAllPermanent(Class<?> beanType, Collection<?> ids) {
return serverMgr.getDefaultServer().deleteAllPermanent(beanType, ids);
return getDefault().deleteAllPermanent(beanType, ids);
}
/**
* Delete all the beans in the Collection.
*/
public static int deleteAll(Collection<?> beans) throws OptimisticLockException {
return serverMgr.getDefaultServer().deleteAll(beans);
return getDefault().deleteAll(beans);
}
/**
* Delete permanent all the beans in the Collection (will not use soft delete).
*/
public static int deleteAllPermanent(Collection<?> beans) throws OptimisticLockException {
return serverMgr.getDefaultServer().deleteAllPermanent(beans);
return getDefault().deleteAllPermanent(beans);
}
/**
@@ -725,7 +599,7 @@ public final class Ebean {
* </p>
*/
public static void refresh(Object bean) {
serverMgr.getDefaultServer().refresh(bean);
getDefault().refresh(bean);
}
/**
@@ -743,7 +617,7 @@ public final class Ebean {
* @param manyPropertyName the property name of the List Set or Map to refresh.
*/
public static void refreshMany(Object bean, String manyPropertyName) {
serverMgr.getDefaultServer().refreshMany(bean, manyPropertyName);
getDefault().refreshMany(bean, manyPropertyName);
}
/**
@@ -768,7 +642,7 @@ public final class Ebean {
* @param id the id value
*/
public static <T> T getReference(Class<T> beanType, Object id) {
return serverMgr.getDefaultServer().getReference(beanType, id);
return getDefault().getReference(beanType, id);
}
/**
@@ -794,7 +668,7 @@ public final class Ebean {
* // find orders and their customers
* List<Order> list = Ebean.find(Order.class)
* .fetch("customer")
* .orderBy("id")
* .order("id")
* .findList();
*
* // sort by customer name ascending, then by order shipDate
@@ -811,7 +685,7 @@ public final class Ebean {
* @param sortByClause the properties to sort the list by
*/
public static <T> void sort(List<T> list, String sortByClause) {
serverMgr.getDefaultServer().sort(list, sortByClause);
getDefault().sort(list, sortByClause);
}
/**
@@ -861,10 +735,12 @@ public final class Ebean {
*/
@Nullable
public static <T> T find(Class<T> beanType, Object id) {
return serverMgr.getDefaultServer().find(beanType, id);
return getDefault().find(beanType, id);
}
/**
* Deprecated - migrate to DB.sqlQuery().
* <p>
* Create a SqlQuery for executing native sql
* query statements.
* <p>
@@ -872,22 +748,24 @@ public final class Ebean {
* annotation for examples.
* </p>
*/
@Deprecated
public static SqlQuery createSqlQuery(String sql) {
return serverMgr.getDefaultServer().createSqlQuery(sql);
return getDefault().sqlQuery(sql);
}
/**
* Deprecated - migrate to DB.sqlUpdate().
* <p>
* Create a sql update for executing native dml statements.
* <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>
*/
@Deprecated
public static SqlUpdate createSqlUpdate(String sql) {
return serverMgr.getDefaultServer().createSqlUpdate(sql);
return getDefault().sqlUpdate(sql);
}
/**
@@ -896,7 +774,7 @@ public final class Ebean {
* @see CallableSql
*/
public static CallableSql createCallableSql(String sql) {
return serverMgr.getDefaultServer().createCallableSql(sql);
return getDefault().createCallableSql(sql);
}
/**
@@ -928,16 +806,14 @@ public final class Ebean {
* }</pre>
*/
public static <T> Update<T> createUpdate(Class<T> beanType, String ormUpdate) {
return serverMgr.getDefaultServer().createUpdate(beanType, ormUpdate);
return getDefault().createUpdate(beanType, ormUpdate);
}
/**
* Create a CsvReader for a given beanType.
*/
public static <T> CsvReader<T> createCsvReader(Class<T> beanType) {
return serverMgr.getDefaultServer().createCsvReader(beanType);
return getDefault().createCsvReader(beanType);
}
/**
@@ -952,7 +828,7 @@ public final class Ebean {
* @return The query
*/
public static <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
return serverMgr.getDefaultServer().createNamedQuery(beanType, namedQuery);
return getDefault().createNamedQuery(beanType, namedQuery);
}
/**
@@ -975,8 +851,7 @@ public final class Ebean {
* @return A ORM Query object for this beanType
*/
public static <T> Query<T> createQuery(Class<T> beanType) {
return serverMgr.getDefaultServer().createQuery(beanType);
return getDefault().createQuery(beanType);
}
/**
@@ -1013,8 +888,7 @@ public final class Ebean {
* @return The query with expressions defined as per the parsed query statement
*/
public static <T> Query<T> createQuery(Class<T> beanType, String eql) {
return serverMgr.getDefaultServer().createQuery(beanType, eql);
return getDefault().createQuery(beanType, eql);
}
/**
@@ -1029,8 +903,7 @@ public final class Ebean {
* @return A ORM Query object for this beanType
*/
public static <T> Query<T> find(Class<T> beanType) {
return serverMgr.getDefaultServer().find(beanType);
return getDefault().find(beanType);
}
/**
@@ -1053,7 +926,7 @@ public final class Ebean {
* @return The query to set parameters and execute
*/
public static <T> Query<T> findNative(Class<T> beanType, String nativeSql) {
return serverMgr.getDefaultServer().findNative(beanType, nativeSql);
return getDefault().findNative(beanType, nativeSql);
}
/**
@@ -1068,7 +941,7 @@ public final class Ebean {
* @param <T> The type of the DTO bean.
*/
public static <T> DtoQuery<T> findDto(Class<T> dtoType, String sql) {
return serverMgr.getDefaultServer().findDto(dtoType, sql);
return getDefault().findDto(dtoType, sql);
}
/**
@@ -1090,7 +963,7 @@ public final class Ebean {
* @return The update query to use
*/
public static <T> UpdateQuery<T> update(Class<T> beanType) {
return serverMgr.getDefaultServer().update(beanType);
return getDefault().update(beanType);
}
/**
@@ -1104,7 +977,7 @@ public final class Ebean {
* </p>
*/
public static <T> Filter<T> filter(Class<T> beanType) {
return serverMgr.getDefaultServer().filter(beanType);
return getDefault().filter(beanType);
}
/**
@@ -1147,7 +1020,7 @@ public final class Ebean {
* @see Ebean#execute(CallableSql)
*/
public static int execute(SqlUpdate sqlUpdate) {
return serverMgr.getDefaultServer().execute(sqlUpdate);
return getDefault().execute(sqlUpdate);
}
/**
@@ -1175,7 +1048,7 @@ public final class Ebean {
* @see Ebean#execute(SqlUpdate)
*/
public static int execute(CallableSql callableSql) {
return serverMgr.getDefaultServer().execute(callableSql);
return getDefault().execute(callableSql);
}
/**
@@ -1193,13 +1066,13 @@ public final class Ebean {
* public void run() {
* User u1 = Ebean.find(User.class, 1);
* ...
* }
* }
* });
*
* }</pre>
*/
public static void execute(TxScope scope, Runnable r) {
serverMgr.getDefaultServer().execute(scope, r);
getDefault().execute(scope, r);
}
/**
@@ -1226,7 +1099,7 @@ public final class Ebean {
* }</pre>
*/
public static void execute(Runnable r) {
serverMgr.getDefaultServer().execute(r);
getDefault().execute(r);
}
/**
@@ -1245,13 +1118,13 @@ public final class Ebean {
* User u1 = Ebean.find(User.class, 1);
* ...
* return u1.getEmail();
* }
* }
* });
*
* }</pre>
*/
public static <T> T executeCall(TxScope scope, Callable<T> c) {
return serverMgr.getDefaultServer().executeCall(scope, c);
return getDefault().executeCall(scope, c);
}
/**
@@ -1284,7 +1157,7 @@ public final class Ebean {
* }</pre>
*/
public static <T> T executeCall(Callable<T> c) {
return serverMgr.getDefaultServer().executeCall(c);
return getDefault().executeCall(c);
}
/**
@@ -1318,8 +1191,7 @@ public final class Ebean {
* @param deletes true if rows on the table where deleted
*/
public static void externalModification(String tableName, boolean inserts, boolean updates, boolean deletes) {
serverMgr.getDefaultServer().externalModification(tableName, inserts, updates, deletes);
getDefault().externalModification(tableName, inserts, updates, deletes);
}
/**
@@ -1329,14 +1201,14 @@ public final class Ebean {
* </p>
*/
public static BeanState getBeanState(Object bean) {
return serverMgr.getDefaultServer().getBeanState(bean);
return getDefault().getBeanState(bean);
}
/**
* Return the manager of the server cache ("L2" cache).
*/
public static ServerCacheManager getServerCacheManager() {
return serverMgr.getDefaultServer().getServerCacheManager();
return getDefault().getServerCacheManager();
}
/**
@@ -1344,14 +1216,14 @@ public final class Ebean {
* queries.
*/
public static BackgroundExecutor getBackgroundExecutor() {
return serverMgr.getDefaultServer().getBackgroundExecutor();
return getDefault().getBackgroundExecutor();
}
/**
* Return the JsonContext for reading/writing JSON.
*/
public static JsonContext json() {
return serverMgr.getDefaultServer().json();
return getDefault().json();
}
}
@@ -1,6 +1,7 @@
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
@@ -8,6 +9,7 @@ package io.ebean;
* <p>
* The preference is to use DB and Database rather than Ebean and EbeanServer.
*/
@Deprecated
public interface EbeanServer extends Database {
}
@@ -0,0 +1,77 @@
package io.ebean;
import io.ebean.config.ContainerConfig;
import io.ebean.config.ServerConfig;
import io.ebean.service.SpiContainer;
import io.ebean.service.SpiContainerFactory;
import javax.persistence.PersistenceException;
import java.util.Iterator;
import java.util.Properties;
import java.util.ServiceLoader;
/**
* 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();
}
}
@@ -6,22 +6,22 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* Class to determine the ebean version. (
* @author Roland Praml, FOCONIS AG
* Class to determine the ebean version.
*
* @author Roland Praml, FOCONIS AG
*/
public class EbeanVersion {
private EbeanVersion() {
}
private static final Logger logger = LoggerFactory.getLogger(EbeanVersion.class);
private static String version = "unknown";
static {
try {
Properties prop = new Properties();
try (InputStream in = Ebean.class.getResourceAsStream("/META-INF/maven/io.ebean/ebean/pom.properties")) {
try (InputStream in = DB.class.getResourceAsStream("/META-INF/maven/io.ebean/ebean/pom.properties")) {
if (in != null) {
prop.load(in);
in.close();
@@ -34,6 +34,10 @@ public class EbeanVersion {
}
}
private EbeanVersion() {
// hide
}
/**
* Returns the ebean version (read from /META-INF/maven/io.ebean/ebean/pom.properties)
*/
@@ -0,0 +1,74 @@
package io.ebean;
import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Future;
/**
* An empty PagedList.
* <p>
* For use in application code when we need to return a PagedList but don't want to
* execute a query.
* </p>
*
* <pre>{@code
*
* PagedList<Customer> empty = PagedList.emptyList();
*
* }</pre>
*/
public class EmptyPagedList<T> implements PagedList<T> {
@Override
public void loadCount() {
// do nothing
}
@Nonnull
@Override
public Future<Integer> getFutureCount() {
return null;
}
@Nonnull
@Override
public List<T> getList() {
return Collections.emptyList();
}
@Override
public int getTotalCount() {
return 0;
}
@Override
public int getTotalPageCount() {
return 0;
}
@Override
public int getPageSize() {
return 0;
}
@Override
public int getPageIndex() {
return 0;
}
@Override
public boolean hasNext() {
return false;
}
@Override
public boolean hasPrev() {
return false;
}
@Override
public String getDisplayXtoYofZ(String to, String of) {
return "";
}
}
@@ -34,14 +34,14 @@ public class Expr {
* Equal To - property equal to the given value.
*/
public static Expression eq(String propertyName, Object value) {
return Ebean.getExpressionFactory().eq(propertyName, value);
return DB.getExpressionFactory().eq(propertyName, value);
}
/**
* Not Equal To - property not equal to the given value.
*/
public static Expression ne(String propertyName, Object value) {
return Ebean.getExpressionFactory().ne(propertyName, value);
return DB.getExpressionFactory().ne(propertyName, value);
}
/**
@@ -49,38 +49,38 @@ public class Expr {
* using a lower() function to make it case insensitive).
*/
public static Expression ieq(String propertyName, String value) {
return Ebean.getExpressionFactory().ieq(propertyName, value);
return DB.getExpressionFactory().ieq(propertyName, value);
}
/**
* In Range - property >= value1 and property < value2.
* In Range - {@code property >= value1 and property < value2}.
* <p>
* Unlike Between inRange is "half open" and usually more useful for use with dates or timestamps.
* </p>
*/
public static Expression inRange(String propertyName, Object value1, Object value2) {
return Ebean.getExpressionFactory().inRange(propertyName, value1, value2);
return DB.getExpressionFactory().inRange(propertyName, value1, value2);
}
/**
* Between - property between the two given values.
*/
public static Expression between(String propertyName, Object value1, Object value2) {
return Ebean.getExpressionFactory().between(propertyName, value1, value2);
return DB.getExpressionFactory().between(propertyName, value1, value2);
}
/**
* Between - value between two given properties.
*/
public static Expression between(String lowProperty, String highProperty, Object value) {
return Ebean.getExpressionFactory().betweenProperties(lowProperty, highProperty, value);
return DB.getExpressionFactory().betweenProperties(lowProperty, highProperty, value);
}
/**
* Greater Than - property greater than the given value.
*/
public static Expression gt(String propertyName, Object value) {
return Ebean.getExpressionFactory().gt(propertyName, value);
return DB.getExpressionFactory().gt(propertyName, value);
}
/**
@@ -88,42 +88,42 @@ public class Expr {
* value.
*/
public static Expression ge(String propertyName, Object value) {
return Ebean.getExpressionFactory().ge(propertyName, value);
return DB.getExpressionFactory().ge(propertyName, value);
}
/**
* Less Than - property less than the given value.
*/
public static Expression lt(String propertyName, Object value) {
return Ebean.getExpressionFactory().lt(propertyName, value);
return DB.getExpressionFactory().lt(propertyName, value);
}
/**
* Less Than or Equal to - property less than or equal to the given value.
*/
public static Expression le(String propertyName, Object value) {
return Ebean.getExpressionFactory().le(propertyName, value);
return DB.getExpressionFactory().le(propertyName, value);
}
/**
* Is Null - property is null.
*/
public static Expression isNull(String propertyName) {
return Ebean.getExpressionFactory().isNull(propertyName);
return DB.getExpressionFactory().isNull(propertyName);
}
/**
* Is Not Null - property is not null.
*/
public static Expression isNotNull(String propertyName) {
return Ebean.getExpressionFactory().isNotNull(propertyName);
return DB.getExpressionFactory().isNotNull(propertyName);
}
/**
* Case insensitive {@link #exampleLike(Object)}
*/
public static ExampleExpression iexampleLike(Object example) {
return Ebean.getExpressionFactory().iexampleLike(example);
return DB.getExpressionFactory().iexampleLike(example);
}
/**
@@ -131,14 +131,14 @@ public class Expr {
* LikeType.RAW (you need to add you own wildcards % and _).
*/
public static ExampleExpression exampleLike(Object example) {
return Ebean.getExpressionFactory().exampleLike(example);
return DB.getExpressionFactory().exampleLike(example);
}
/**
* Create the query by Example expression specifying more options.
*/
public static ExampleExpression exampleLike(Object example, boolean caseInsensitive, LikeType likeType) {
return Ebean.getExpressionFactory().exampleLike(example, caseInsensitive, likeType);
return DB.getExpressionFactory().exampleLike(example, caseInsensitive, likeType);
}
/**
@@ -146,7 +146,7 @@ public class Expr {
* characters % (percentage) and _ (underscore).
*/
public static Expression like(String propertyName, String value) {
return Ebean.getExpressionFactory().like(propertyName, value);
return DB.getExpressionFactory().like(propertyName, value);
}
/**
@@ -155,14 +155,14 @@ public class Expr {
* a lower() function to make the expression case insensitive.
*/
public static Expression ilike(String propertyName, String value) {
return Ebean.getExpressionFactory().ilike(propertyName, value);
return DB.getExpressionFactory().ilike(propertyName, value);
}
/**
* Starts With - property like value%.
*/
public static Expression startsWith(String propertyName, String value) {
return Ebean.getExpressionFactory().startsWith(propertyName, value);
return DB.getExpressionFactory().startsWith(propertyName, value);
}
/**
@@ -170,14 +170,14 @@ public class Expr {
* lower() function to make the expression case insensitive.
*/
public static Expression istartsWith(String propertyName, String value) {
return Ebean.getExpressionFactory().istartsWith(propertyName, value);
return DB.getExpressionFactory().istartsWith(propertyName, value);
}
/**
* Ends With - property like %value.
*/
public static Expression endsWith(String propertyName, String value) {
return Ebean.getExpressionFactory().endsWith(propertyName, value);
return DB.getExpressionFactory().endsWith(propertyName, value);
}
/**
@@ -185,14 +185,14 @@ public class Expr {
* function to make the expression case insensitive.
*/
public static Expression iendsWith(String propertyName, String value) {
return Ebean.getExpressionFactory().iendsWith(propertyName, value);
return DB.getExpressionFactory().iendsWith(propertyName, value);
}
/**
* Contains - property like %value%.
*/
public static Expression contains(String propertyName, String value) {
return Ebean.getExpressionFactory().contains(propertyName, value);
return DB.getExpressionFactory().contains(propertyName, value);
}
/**
@@ -200,42 +200,42 @@ public class Expr {
* function to make the expression case insensitive.
*/
public static Expression icontains(String propertyName, String value) {
return Ebean.getExpressionFactory().icontains(propertyName, value);
return DB.getExpressionFactory().icontains(propertyName, value);
}
/**
* For collection properties that are empty (have not existing elements).
*/
public static Expression isEmpty(String propertyName) {
return Ebean.getExpressionFactory().isEmpty(propertyName);
return DB.getExpressionFactory().isEmpty(propertyName);
}
/**
* For collection properties that are not empty (have existing elements).
*/
public static Expression isNotEmpty(String propertyName) {
return Ebean.getExpressionFactory().isNotEmpty(propertyName);
return DB.getExpressionFactory().isNotEmpty(propertyName);
}
/**
* In - property has a value in the array of values.
*/
public static Expression in(String propertyName, Object[] values) {
return Ebean.getExpressionFactory().in(propertyName, values);
return DB.getExpressionFactory().in(propertyName, values);
}
/**
* In - using a subQuery.
*/
public static Expression in(String propertyName, Query<?> subQuery) {
return Ebean.getExpressionFactory().in(propertyName, subQuery);
return DB.getExpressionFactory().in(propertyName, subQuery);
}
/**
* In - property has a value in the collection of values.
*/
public static Expression in(String propertyName, Collection<?> values) {
return Ebean.getExpressionFactory().in(propertyName, values);
return DB.getExpressionFactory().in(propertyName, values);
}
/**
@@ -272,14 +272,14 @@ public class Expr {
* }</pre>
*/
public static Expression inOrEmpty(String propertyName, Collection<?> values) {
return Ebean.getExpressionFactory().inOrEmpty(propertyName, values);
return DB.getExpressionFactory().inOrEmpty(propertyName, values);
}
/**
* Id Equal to - ID property is equal to the value.
*/
public static Expression idEq(Object value) {
return Ebean.getExpressionFactory().idEq(value);
return DB.getExpressionFactory().idEq(value);
}
/**
@@ -292,7 +292,7 @@ public class Expr {
* @param propertyMap a map keyed by property names.
*/
public static Expression allEq(Map<String, Object> propertyMap) {
return Ebean.getExpressionFactory().allEq(propertyMap);
return DB.getExpressionFactory().allEq(propertyMap);
}
/**
@@ -303,7 +303,7 @@ public class Expr {
* </p>
*/
public static Expression raw(String raw, Object value) {
return Ebean.getExpressionFactory().raw(raw, value);
return DB.getExpressionFactory().raw(raw, value);
}
/**
@@ -314,14 +314,14 @@ public class Expr {
* </p>
*/
public static Expression raw(String raw, Object[] values) {
return Ebean.getExpressionFactory().raw(raw, values);
return DB.getExpressionFactory().raw(raw, values);
}
/**
* Add raw expression with no parameters.
*/
public static Expression raw(String raw) {
return Ebean.getExpressionFactory().raw(raw);
return DB.getExpressionFactory().raw(raw);
}
/**
@@ -329,7 +329,7 @@ public class Expr {
*/
public static Expression and(Expression expOne, Expression expTwo) {
return Ebean.getExpressionFactory().and(expOne, expTwo);
return DB.getExpressionFactory().and(expOne, expTwo);
}
/**
@@ -337,7 +337,7 @@ public class Expr {
*/
public static Expression or(Expression expOne, Expression expTwo) {
return Ebean.getExpressionFactory().or(expOne, expTwo);
return DB.getExpressionFactory().or(expOne, expTwo);
}
/**
@@ -345,7 +345,7 @@ public class Expr {
*/
public static Expression not(Expression exp) {
return Ebean.getExpressionFactory().not(exp);
return DB.getExpressionFactory().not(exp);
}
/**
@@ -353,7 +353,7 @@ public class Expr {
*/
public static <T> Junction<T> conjunction(Query<T> query) {
return Ebean.getExpressionFactory().conjunction(query);
return DB.getExpressionFactory().conjunction(query);
}
/**
@@ -361,6 +361,6 @@ public class Expr {
*/
public static <T> Junction<T> disjunction(Query<T> query) {
return Ebean.getExpressionFactory().disjunction(query);
return DB.getExpressionFactory().disjunction(query);
}
}
@@ -155,7 +155,7 @@ public interface ExpressionFactory {
Expression ineObject(String propertyName, Object value);
/**
* In Range - property >= value1 and property < value2.
* In Range - {@code property >= value1 and property < value2}.
* <p>
* Unlike Between inRange is "half open" and usually more useful for use with dates or timestamps.
* </p>
@@ -199,6 +199,14 @@ public interface ExpressionFactory {
*/
Expression gtOrNull(String propertyName, Object value);
/**
* Greater than or Equal to OR Null <code> >= or null </code>
* <p>
* A convenient expression combining GE and Is Null. Most often useful for range
* expressions where the top range value is nullable.
*/
Expression geOrNull(String propertyName, Object value);
/**
* Greater Than - property greater than the given value.
*/
@@ -218,6 +226,14 @@ public interface ExpressionFactory {
*/
Expression ltOrNull(String propertyName, Object value);
/**
* Less Than or Equal to OR Null <code> <= or null </code>
* <p>
* A convenient expression combining LE and Is Null. Most often useful for range
* expressions where the bottom range value is nullable.
*/
Expression leOrNull(String propertyName, Object value);
/**
* Less Than - property less than the given value.
*/
@@ -30,7 +30,7 @@ import java.util.function.Predicate;
* </p>
* <p>
* The ExpressionList also duplicates methods that are found on the Query such
* as findList() and orderBy(). The purpose of these methods is provide a fluid
* as findList() and order(). The purpose of these methods is provide a fluid
* API. The upside of this approach is that you can build and execute a query
* via chained methods. The down side is that this ExpressionList object has
* more methods than you would initially expect (the ones duplicated from
@@ -52,6 +52,14 @@ public interface ExpressionList<T> {
*/
Query<T> query();
/**
* Controls, if paginated queries should always append an 'order by id' statement at the end to
* guarantee a deterministic sort result. This may affect performance.
* If this is not enabled, and an orderBy is set on the query, it's up to the programmer that
* this query provides a deterministic result.
*/
Query<T> orderById(boolean orderById);
/**
* Set the order by clause replacing the existing order by clause if there is
* one.
@@ -59,12 +67,18 @@ public interface ExpressionList<T> {
* This follows SQL syntax using commas between each property with the
* optional asc and desc keywords representing ascending and descending order
* respectively.
* </p>
* <p>
* This is EXACTLY the same as {@link #orderBy(String)}.
* </p>
*/
Query<T> order(String orderByClause);
ExpressionList<T> order(String orderByClause);
/**
* Set the order by clause replacing the existing order by clause if there is
* one.
* <p>
* This follows SQL syntax using commas between each property with the
* optional asc and desc keywords representing ascending and descending order
* respectively.
*/
ExpressionList<T> orderBy(String orderBy);
/**
* Return the OrderBy so that you can append an ascending or descending
@@ -72,7 +86,8 @@ public interface ExpressionList<T> {
* <p>
* This will never return a null. If no order by clause exists then an 'empty'
* OrderBy object is returned.
* </p>
* <p>
* This is the same as <code>orderBy()</code>
*/
OrderBy<T> order();
@@ -82,22 +97,15 @@ public interface ExpressionList<T> {
* <p>
* This will never return a null. If no order by clause exists then an 'empty'
* OrderBy object is returned.
* </p>
* <p>
* This is the same as <code>order()</code>
*/
OrderBy<T> orderBy();
/**
* Add an orderBy clause to the query.
*
* @see Query#orderBy(String)
*/
Query<T> orderBy(String orderBy);
/**
* Add an orderBy clause to the query.
*
* @see Query#orderBy(String)
* Deprecated migrate to {@link #orderBy(String)}
*/
@Deprecated
Query<T> setOrderBy(String orderBy);
/**
@@ -334,7 +342,7 @@ public interface ExpressionList<T> {
* List<String> names =
* DB.find(Customer.class)
* .select("name")
* .orderBy().asc("name")
* .order().asc("name")
* .findSingleAttributeList();
*
* }</pre>
@@ -347,7 +355,7 @@ public interface ExpressionList<T> {
* .setDistinct(true)
* .select("name")
* .where().eq("status", Customer.Status.NEW)
* .orderBy().asc("name")
* .order().asc("name")
* .setMaxRows(100)
* .findSingleAttributeList();
*
@@ -508,7 +516,7 @@ public interface ExpressionList<T> {
* @param expressions Filter expressions with and, or and ? or ?1 type bind parameters
* @param params Bind parameters used in the expressions
*/
Query<T> filterMany(String manyProperty, String expressions, Object... params);
ExpressionList<T> filterMany(String manyProperty, String expressions, Object... params);
/**
* Specify specific properties to fetch on the main/root bean (aka partial
@@ -559,14 +567,14 @@ public interface ExpressionList<T> {
*
* @see Query#setFirstRow(int)
*/
Query<T> setFirstRow(int firstRow);
ExpressionList<T> setFirstRow(int firstRow);
/**
* Set the maximum number of rows to fetch.
*
* @see Query#setMaxRows(int)
*/
Query<T> setMaxRows(int maxRows);
ExpressionList<T> setMaxRows(int maxRows);
/**
* Set the name of the property which values become the key of a map.
@@ -851,7 +859,7 @@ public interface ExpressionList<T> {
ExpressionList<T> inRangeWith(String lowProperty, String highProperty, Object value);
/**
* In Range - property >= value1 and property < value2.
* In Range - {@code property >= value1 and property < value2}.
* <p>
* Unlike Between inRange is "half open" and usually more useful for use with dates or timestamps.
* </p>
@@ -878,6 +886,11 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> gtOrNull(String propertyName, Object value);
/**
* Greater Than or Equal to OR Null - <code> >= or null </code>.
*/
ExpressionList<T> geOrNull(String propertyName, Object value);
/**
* Greater Than or Equal to - property greater than or equal to the given
* value.
@@ -894,6 +907,11 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> ltOrNull(String propertyName, Object value);
/**
* Less Than or Equal to OR Null - <code> <= or null </code>.
*/
ExpressionList<T> leOrNull(String propertyName, Object value);
/**
* Less Than or Equal to - property less than or equal to the given value.
*/
@@ -1243,26 +1261,35 @@ public interface ExpressionList<T> {
/**
* Add raw expression with a single parameter.
* <p>
* The raw expression should contain a single ? at the location of the
* parameter.
* </p>
* The raw expression should contain a single ? or ?1
* at the location of the parameter. We use ?1 when binding a
* collection for an IN expression.
* <p>
* When properties in the clause are fully qualified as table-column names
* then they are not translated. logical property name names (not fully
* qualified) will still be translated to their physical name.
* </p>
* <p>
* <h4>Example:</h4>
* <h4>Examples:</h4>
* <pre>{@code
*
* // use a database function
* raw("add_days(orderDate, 10) < ?", someDate)
*
* raw("name like ?", "Rob%")
*
* raw("name in (?1)", asList("Rob", "Fiona", "Jack"))
*
* raw("name = any(?)", asList("Rob", "Fiona", "Jack"))
*
* }</pre>
*
* <h4>Subquery example:</h4>
* <h4>Subquery examples:</h4>
* <pre>{@code
*
* // Bind collection using ?1
* .raw("id in (select c.id from o_customer c where c.name in (?1))", asList("Rob", "Fiona", "Jack"))
*
* // Using Postgres ANY expression
* .raw("t0.customer_id in (select customer_id from customer_group where group_id = any(?::uuid[]))", groupIds)
*
* }</pre>
@@ -1272,14 +1299,25 @@ public interface ExpressionList<T> {
/**
* Add raw expression with an array of parameters.
* <p>
* The raw expression should contain the same number of ? as there are
* parameters.
* </p>
* The raw expression should contain the same number of ? or ?1, ?2 ... bind parameters
* as there are values. We use ?1, ?2 etc when binding a collection for an IN expression.
* <p>
* When properties in the clause are fully qualified as table-column names
* then they are not translated. logical property name names (not fully
* qualified) will still be translated to their physical name.
* </p>
*
* <h4>Examples:</h4>
* <pre>{@code
*
* raw("unitPrice > ? and product.id > ?", 2, 3)
*
* raw("(status = ? or (orderDate < ? and shipDate is null) or customer.name like ?)",
* Order.Status.APPROVED,
* new Timestamp(System.currentTimeMillis()),
* "Rob")
*
* }</pre></pre>
*/
ExpressionList<T> raw(String raw, Object... values);
@@ -1451,7 +1489,7 @@ public interface ExpressionList<T> {
* .eq("status", Customer.Status.ACTIVE)
* .gt("id", 0)
* .endAnd()
* .orderBy().asc("name")
* .order().asc("name")
* .findList();
* }</pre>
*/
@@ -1472,7 +1510,7 @@ public interface ExpressionList<T> {
* .or()
* .eq("status", Customer.Status.ACTIVE)
* .isNull("anniversary")
* .orderBy().asc("name")
* .order().asc("name")
* .findList();
*
* }</pre>
@@ -1492,7 +1530,7 @@ public interface ExpressionList<T> {
* .eq("status", Customer.Status.ACTIVE)
* .gt("id", 0)
* .endAnd()
* .orderBy().asc("name")
* .order().asc("name")
* .findList();
*
* }</pre>
@@ -1526,7 +1564,7 @@ public interface ExpressionList<T> {
* .gt("id", 1)
* .eq("anniversary", onAfter)
* .endNot()
* .orderBy()
* .order()
* .asc("name")
* .findList();
*
@@ -1,8 +1,5 @@
package io.ebean;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.api.SpiTransaction;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.persistence.NonUniqueResultException;
@@ -70,7 +67,7 @@ public interface ExtendedServer {
*
* @return True if the query finds a matching row in the database
*/
<T> boolean exists(SpiQuery<?> ormQuery, SpiTransaction transaction);
<T> boolean exists(Query<?> ormQuery, Transaction transaction);
/**
* Return the number of 'top level' or 'root' entities this query should return.
@@ -95,11 +92,9 @@ public interface ExtendedServer {
* {@link #findEachWhile(Query, Predicate, Transaction)} is preferred
* to findIterate(). The reason is that those methods automatically take care of
* closing the queryIterator (and the underlying jdbc statement and resultSet).
* </p>
* <p>
* This is similar to findEach in that not all the result beans need to be held
* in memory at the same time and as such is good for processing large queries.
* </p>
*
* @see Query#findIterate()
* @see Query#findEach(Consumer)
@@ -109,7 +104,10 @@ public interface ExtendedServer {
<T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction);
/**
* Return the query result as a Stream using a single persistence context.
* Execute the query returning the result as a Stream.
* <p>
* Note that this can support very large queries iterating any number of results.
* To do so internally it can use multiple persistence contexts.
* <p>
* Note that the stream needs to be closed so use with try with resources.
* </p>
@@ -118,12 +116,17 @@ public interface ExtendedServer {
<T> Stream<T> findStream(Query<T> query, Transaction transaction);
/**
* Return the query result as a Stream (with multiple persistence contexts).
* Deprecated - migrate to findStream().
* <p>
* Execute the query returning the result as a Stream.
* <p>
* Note that this can support very large queries iterating any number of results.
* To do so internally it can use multiple persistence contexts.
* <p>
* Note that the stream needs to be closed so use with try with resources.
* </p>
*/
@Nonnull
@Deprecated
<T> Stream<T> findLargeStream(Query<T> query, Transaction transaction);
/**
@@ -360,7 +363,7 @@ public interface ExtendedServer {
* List<String> names =
* DB.find(Customer.class)
* .select("name")
* .orderBy().asc("name")
* .order().asc("name")
* .findSingleAttributeList();
*
* }</pre>
@@ -372,7 +375,7 @@ public interface ExtendedServer {
* .setDistinct(true)
* .select("name")
* .where().eq("status", Customer.Status.NEW)
* .orderBy().asc("name")
* .order().asc("name")
* .setMaxRows(100)
* .findSingleAttributeList();
*
@@ -86,7 +86,7 @@ public interface Filter<T> {
* expressions.
* </p>
* <p>
* Refer to {@link Ebean#sort(List, String)} for more detail.
* Refer to {@link DB#sort(List, String)} for more detail.
* </p>
*/
Filter<T> sort(String sortByClause);
@@ -32,17 +32,18 @@ import java.util.List;
* public List<Customer> findNew() {
* return query().where()
* .eq("status", Customer.Status.NEW)
* .orderBy("name")
* .order("name")
* .findList()
* }
* }
*
* @Entity
* Entity
* public class Customer extends BaseModel {
*
* public static final CustomerFinder find = new CustomerFinder();
* ...
*
* }
* }</pre>
* <p>
* When the Finder is registered as a field on Customer it can then be used like:
@@ -79,12 +80,13 @@ public class Finder<I, T> {
* // ... add extra customer specific finder methods
* }
*
* @Entity
* Entity
* public class Customer extends BaseModel {
*
* public static final CustomerFinder find = new CustomerFinder();
* ...
*
* }
* }</pre>
*/
public Finder(Class<T> type) {
@@ -32,19 +32,19 @@ import io.ebean.bean.EntityBean;
* // Typically there is a common base model that has some
* // common properties like the ones below
*
* @MappedSuperclass
* public class BaseModel extends Model {
* MappedSuperclass
* public class BaseModel extends Model {
*
* @Id Long id;
* Id Long id;
*
* @Version Long version;
* Version Long version;
*
* @WhenCreated Timestamp whenCreated;
* WhenCreated Timestamp whenCreated;
*
* @WhenUpdated Timestamp whenUpdated;
*
* ...
* WhenUpdated Timestamp whenUpdated;
*
* ...
* }
* }</pre>
* <p>
* <h3>Extend the Model</h3>
@@ -52,7 +52,7 @@ import io.ebean.bean.EntityBean;
*
* // Extend the mappedSuperclass
*
* @Entity @Table(name="o_account")
* Entity Table(name="o_account")
* public class Customer extends BaseModel {
*
* String name;
@@ -192,6 +192,13 @@ public abstract class Model {
db().save(this);
}
/**
* Save this entity with an explicit transaction.
*/
public void save(Transaction transaction) {
db().save(this, transaction);
}
/**
* Flush any batched changes to the database.
* <p>
@@ -212,6 +219,13 @@ public abstract class Model {
db().update(this);
}
/**
* Update this entity with an explicit transaction.
*/
public void update(Transaction transaction) {
db().update(this, transaction);
}
/**
* Insert this entity.
*
@@ -221,6 +235,13 @@ public abstract class Model {
db().insert(this);
}
/**
* Insert with an explicit transaction.
*/
public void insert(Transaction transaction) {
db().insert(this, transaction);
}
/**
* Delete this bean.
* <p>
@@ -242,6 +263,13 @@ public abstract class Model {
return db().delete(this);
}
/**
* Delete this entity with an explicit transaction.
*/
public boolean delete(Transaction transaction) {
return db().delete(this, transaction);
}
/**
* Delete a bean permanently without soft delete.
* <p>
@@ -255,6 +283,13 @@ public abstract class Model {
return db().deletePermanent(this);
}
/**
* Delete a bean permanently without soft delete using an explicit transaction.
*/
public boolean deletePermanent(Transaction transaction) {
return db().deletePermanent(this, transaction);
}
/**
* Refreshes this entity from the database.
*
@@ -1,7 +1,5 @@
package io.ebean;
import io.ebean.util.StringHelper;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@@ -341,7 +339,7 @@ public final class OrderBy<T> implements Serializable {
if (collation != null) {
if (collation.contains("${}")) {
// this is a complex collation, e.g. DB2 - we must replace the property
sb.append(StringHelper.replaceString(collation, "${}", property));
sb.append(collation.replace("${}", property));
} else {
sb.append(property);
sb.append(" collate ").append(collation);
@@ -60,6 +60,13 @@ import java.util.concurrent.Future;
*/
public interface PagedList<T> {
/**
* Return an empty PagedList.
*/
static <B> PagedList<B> emptyList() {
return new EmptyPagedList<>();
}
/**
* Initiate the loading of the total row count in the background.
* <pre>{@code
@@ -87,8 +94,8 @@ public interface PagedList<T> {
* Return the Future row count. You might get this if you wish to cancel the total row count query
* or specify a timeout for the row count query.
* <p>
* The loadRowCount() & getTotalRowCount() methods internally make use of this getFutureRowCount() method.
* Generally I expect people to prefer loadRowCount() & getTotalRowCount() over getFutureRowCount().
* The loadRowCount() and getTotalRowCount() methods internally make use of this getFutureRowCount() method.
* Generally I expect people to prefer loadRowCount() and getTotalRowCount() over getFutureRowCount().
* </p>
* <pre>{@code
*
@@ -18,7 +18,7 @@ import java.util.List;
*
* // where a bean is annotated with a complex
* // natural key made of several properties
* @Cache(naturalKey = {"store","code","sku"})
* Cache(naturalKey = {"store","code","sku"})
*
*
* Pairs pairs = new Pairs("sku", "code");
@@ -30,7 +30,7 @@ import java.util.List;
* .where()
* .eq("store", "def")
* .inPairs(pairs) // IN clause with 'pairs' of values
* .orderBy("sku desc")
* .order("sku desc")
*
* // query expressions cover the natural key properties
* // so we can choose to hit the L2 bean cache if we want
@@ -6,7 +6,7 @@ package io.ebean;
* Ebean has traditionally used Transaction scope for the PersistenceContext. This is used to change the scope to
* use (by default) and explicitly set the scope to use for an individual query.
*
* @see io.ebean.config.ServerConfig#setPersistenceContextScope(PersistenceContextScope)
* @see io.ebean.config.DatabaseConfig#setPersistenceContextScope(PersistenceContextScope)
* @see Query#setPersistenceContextScope(PersistenceContextScope)
*/
public enum PersistenceContextScope {
@@ -31,22 +31,37 @@ public interface ProfileLocation {
}
/**
* Obtain the location description.
* Obtain the description returning true if this is the initial call.
*/
String obtain();
boolean obtain();
/**
* Return a short version of the location description.
*/
String shortDescription();
String location();
/**
* Return the short label.
*/
String label();
/**
* Return the full location.
*/
String fullLocation();
/**
* Add execution time.
*/
void add(long executionTime);
/**
* Return true if this request should be traced.
*/
boolean trace();
/**
* Set the number of times to trace the transactions for this profile location.
*/
void setTraceCount(int traceCount);
}
@@ -25,7 +25,7 @@ import java.util.stream.Stream;
* .where()
* .like("customer.name","rob%")
* .gt("orderDate",lastWeek)
* .orderBy("customer.id, id desc")
* .order("customer.id, id desc")
* .setMaxRows(50)
* .findList();
*
@@ -283,7 +283,7 @@ public interface Query<T> {
/**
* Specify the PersistenceContextScope to use for this query.
* <p/>
* When this is not set the 'default' configured on {@link io.ebean.config.ServerConfig#setPersistenceContextScope(PersistenceContextScope)}
* When this is not set the 'default' configured on {@link io.ebean.config.DatabaseConfig#setPersistenceContextScope(PersistenceContextScope)}
* is used - this value defaults to {@link PersistenceContextScope#TRANSACTION}.
* <p/>
* Note that the same persistence Context is used for subsequent lazy loading and query join queries.
@@ -656,6 +656,11 @@ public interface Query<T> {
*/
Query<T> usingConnection(Connection connection);
/**
* Execute the query using the given database.
*/
Query<T> usingDatabase(Database database);
/**
* Execute the query returning the list of Id's.
* <p>
@@ -706,9 +711,9 @@ public interface Query<T> {
/**
* Execute the query returning the result as a Stream.
* <p>
* Note that this will hold all resulting beans in memory using a single
* persistence context. Use findLargeStream() for queries that expect to
* return a large number of results.
* Note that this can support very large queries iterating
* any number of results. To do so internally it can use
* multiple persistence contexts.
* </p>
* <pre>{@code
*
@@ -726,6 +731,8 @@ public interface Query<T> {
Stream<T> findStream();
/**
* Deprecated - migrate to findStream.
* <p>
* Execute the query returning the result as a Stream.
* <p>
* Note that this uses multiple persistence contexts such that we can use
@@ -744,6 +751,7 @@ public interface Query<T> {
* }</pre>
*/
@Nonnull
@Deprecated
Stream<T> findLargeStream();
/**
@@ -885,7 +893,7 @@ public interface Query<T> {
* List<String> names =
* DB.find(Customer.class)
* .select("name")
* .orderBy().asc("name")
* .order().asc("name")
* .findSingleAttributeList();
*
* }</pre>
@@ -898,7 +906,7 @@ public interface Query<T> {
* .setDistinct(true)
* .select("name")
* .where().eq("status", Customer.Status.NEW)
* .orderBy().asc("name")
* .order().asc("name")
* .setMaxRows(100)
* .findSingleAttributeList();
*
@@ -1183,6 +1191,30 @@ public interface Query<T> {
*/
Query<T> setParameter(int position, Object value);
/**
* Bind the next positioned parameter.
*
* <pre>{@code
*
* // a query with a positioned parameters
* String oql = "where status = ? and name = ?";
*
* List<Order> list = DB.createQuery(Order.class, oql)
* .setParameter(OrderStatus.NEW)
* .setParameter("Rob")
* .findList();
*
* }</pre>
*/
Query<T> setParameter(Object value);
/**
* Bind all the positioned parameters.
* <p>
* A convenience for multiple calls to {@link #setParameter(Object)}
*/
Query<T> setParameters(Object... values);
/**
* Set the Id value to query. This is used with findOne().
* <p>
@@ -1329,10 +1361,6 @@ public interface Query<T> {
* This follows SQL syntax using commas between each property with the
* optional asc and desc keywords representing ascending and descending order
* respectively.
* </p>
* <p>
* This is EXACTLY the same as {@link #order(String)}.
* </p>
*/
Query<T> orderBy(String orderByClause);
@@ -1343,10 +1371,6 @@ public interface Query<T> {
* This follows SQL syntax using commas between each property with the
* optional asc and desc keywords representing ascending and descending order
* respectively.
* </p>
* <p>
* This is EXACTLY the same as {@link #orderBy(String)}.
* </p>
*/
Query<T> order(String orderByClause);
@@ -1356,10 +1380,8 @@ public interface Query<T> {
* <p>
* This will never return a null. If no order by clause exists then an 'empty'
* OrderBy object is returned.
* </p>
* <p>
* This is EXACTLY the same as {@link #orderBy()}.
* </p>
* This is the same as <code>orderBy()</code>
*/
OrderBy<T> order();
@@ -1369,26 +1391,18 @@ public interface Query<T> {
* <p>
* This will never return a null. If no order by clause exists then an 'empty'
* OrderBy object is returned.
* </p>
* <p>
* This is EXACTLY the same as {@link #order()}.
* </p>
* This is the same as <code>order()</code>
*/
OrderBy<T> orderBy();
/**
* Set an OrderBy object to replace any existing OrderBy clause.
* <p>
* This is EXACTLY the same as {@link #setOrderBy(OrderBy)}.
* </p>
*/
Query<T> setOrder(OrderBy<T> orderBy);
/**
* Set an OrderBy object to replace any existing OrderBy clause.
* <p>
* This is EXACTLY the same as {@link #setOrder(OrderBy)}.
* </p>
*/
Query<T> setOrderBy(OrderBy<T> orderBy);
@@ -1524,17 +1538,6 @@ public interface Query<T> {
return setUseQueryCache(enabled ? CacheMode.ON : CacheMode.OFF);
}
/**
* Set an id to identify this query for profiling purposes.
* <p>
* The profileId is expected to be unique for a given bean type.
* </p>
* <p>
* Note that the profileId is treated as a short internally and has a MAX value of 32,767.
* </p>
*/
Query<T> setProfileId(int profileId);
/**
* Set the profile location of this query. This is used to relate query execution metrics
* back to a location like a specific line of code.
@@ -23,9 +23,9 @@ import java.util.Iterator;
* <h3>Try finally style</h3>
* <pre>{@code
*
* Query<Customer> query = server.find(Customer.class)
* Query<Customer> query = database.find(Customer.class)
* .where().gt("id", 0)
* .orderBy("id")
* .order("id")
* .setMaxRows(2);
*
* QueryIterator<Customer> it = query.findIterate();
@@ -6,17 +6,13 @@ package io.ebean;
* <p>
* If you don't want to build object graphs you can use {@link SqlQuery} instead
* which returns {@link SqlRow} objects rather than entity beans.
* </p>
* <p>
* <b>Unparsed RawSql:</b>
* </p>
* <p>
* When RawSql is created via {@link RawSqlBuilder#unparsed(String)} then Ebean can not
* modify the SQL at all. It can't add any extra expressions into the SQL.
* </p>
* <p>
* <b>Parsed RawSql:</b>
* </p>
* <p>
* When RawSql is created via {@link RawSqlBuilder#parse(String)} then Ebean will parse the
* SQL and find places in the SQL where it can add extra where expressions, add
@@ -24,16 +20,13 @@ package io.ebean;
* explicitly tell Ebean where these insertion points are you can place special
* strings into your SQL ({@code ${where}} or {@code ${andWhere}} and {@code ${having}} or
* {@code ${andHaving})}.
* </p>
* <p>
* If the SQL already includes a WHERE clause put in {@code ${andWhere}} in the location
* you want Ebean to add any extra where expressions. If the SQL doesn't have a
* WHERE clause put {@code ${where}} in instead. Similarly you can put in {@code ${having}} or
* {@code ${andHaving}} where you want Ebean put add extra having expressions.
* </p>
* <p>
* <b>Aggregates:</b>
* </p>
* <p>
* Often RawSql will be used with Aggregate functions (sum, avg, max etc). The
* follow example shows an example based on Total Order Amount -
@@ -44,38 +37,37 @@ package io.ebean;
* on RawSql and not based on a real DB Table or DB View. It has some properties
* to hold the values for the aggregate functions (sum etc) and a &#064;OneToOne
* to Order.
* </p>
* <p>
* <h3>Example OrderAggregate</h3>
* <pre>{@code
* ...
* // @Sql indicates to that this bean
* // is based on RawSql rather than a table
* // Sql indicates to that this bean
* // is based on RawSql rather than a table
*
* @Entity
* @Sql
* public class OrderAggregate {
* Entity
* Sql
* public class OrderAggregate {
*
* @OneToOne
* Order order;
* OneToOne
* Order order;
*
* Double totalAmount;
* Double totalAmount;
*
* Double totalItems;
*
* // getters and setters
* ...
* Double totalItems;
*
* // getters and setters
* ...
* }
* }</pre>
* <p>
*
* <h3>Example 1:</h3>
* <p>
*
* <pre>{@code
*
* String sql = " select order_id, o.status, c.id, c.name, sum(d.order_qty*d.unit_price) as totalAmount"
* + " from o_order o"
* + " join o_customer c on c.id = o.kcustomer_id "
* + " join o_order_detail d on d.order_id = o.id " + " group by order_id, o.status ";
* String sql = " select order_id, o.status, c.id, c.name, sum(l.order_qty*l.unit_price) as totalAmount"
* + " from order o"
* + " join customer c on c.id = o.customer_id "
* + " join order_line l on l.order_id = o.id " + " group by order_id, o.status ";
*
* RawSql rawSql = RawSqlBuilder.parse(sql)
* // map the sql result columns to bean properties
@@ -95,18 +87,17 @@ package io.ebean;
*
*
* }</pre>
* <p>
*
* <h3>Example 2:</h3>
* <p>
* The following example uses a FetchConfig().query() so that after the initial
* RawSql query is executed Ebean executes a secondary query to fetch the
* associated order status, orderDate along with the customer name.
* </p>
* <p>
*
* <pre>{@code
*
* String sql = " select order_id, 'ignoreMe', sum(d.order_qty*d.unit_price) as totalAmount "
* + " from o_order_detail d"
* String sql = " select order_id, 'ignoreMe', sum(l.order_qty*l.unit_price) as totalAmount "
* + " from order_line l"
* + " group by order_id ";
*
* RawSql rawSql = RawSqlBuilder.parse(sql)
@@ -125,25 +116,23 @@ package io.ebean;
* .findList();
*
* }</pre>
* <p>
* <h3>Example 3: tableAliasMapping</h3>
* <p>
* Instead of mapping each column you can map each table alias to a path using tableAliasMapping().
* </p>
* <pre>{@code
*
* String rs = "select o.id, o.status, c.id, c.name, "+
* " d.id, d.order_qty, p.id, p.name " +
* "from o_order o join o_customer c on c.id = o.kcustomer_id " +
* "join o_order_detail d on d.order_id = o.id " +
* "join o_product p on p.id = d.product_id " +
* " l.id, l.order_qty, p.id, p.name " +
* "from orders o join o_customer c on c.id = o.customer_id " +
* "join order_line l on l.order_id = o.id " +
* "join product p on p.id = l.product_id " +
* "where o.id <= :maxOrderId and p.id = :productId "+
* "order by o.id, d.id asc";
* "order by o.id, l.id asc";
*
* RawSql rawSql = RawSqlBuilder.parse(rs)
* .tableAliasMapping("c", "customer")
* .tableAliasMapping("d", "details")
* .tableAliasMapping("p", "details.product")
* .tableAliasMapping("l", "lines")
* .tableAliasMapping("p", "lines.product")
* .create();
*
* List<Order> ordersFromRaw = DB.find(Order.class)
@@ -154,9 +143,7 @@ package io.ebean;
*
* }</pre>
* <p>
* <p>
* Note that lazy loading also works with object graphs built with RawSql.
* </p>
*/
public interface RawSql {
@@ -18,11 +18,11 @@ import java.sql.SQLException;
* <pre>{@code
*
* //
* // A mapper from ResultSet into our CustomerDto bean
* // Map from ResultSet to CustomerDto bean
* //
* class CustomerMapper implements RowMapper<CustomerDto> {
*
* @Override
* Override
* public CustomerDto map(ResultSet rset, int rowNum) throws SQLException {
*
* long id = rset.getLong(1);
@@ -42,7 +42,8 @@ import java.sql.SQLException;
*
* CustomerDto rob = DB.sqlQuery(sql)
* .setParameter(1, "Rob")
* .findOne(CUSTOMER_MAPPER);
* .mapTo(CUSTOMER_MAPPER)
* .findOne();
*
*
* }</pre>
@@ -50,4 +50,13 @@ public interface ScriptRunner {
*/
void run(URL resource, Map<String, String> placeholderMap);
/**
* Run the raw provided DDL or SQL script.
*
* @param name The name of the script for logging purposes
* @param content The SQL content
* @param useAutoCommit Set to true to use auto commit true and continue when any errors occur
*/
void runScript(String name, String content, boolean useAutoCommit);
}
@@ -75,17 +75,15 @@ public interface SqlQuery extends Serializable {
SqlRow findOne();
/**
* Execute the query returning a single result using the mapper.
*
* @param mapper Used to map each ResultSet row into the result object.
* Deprecated migrate to use {@link #mapTo(RowMapper)}
*/
@Deprecated
<T> T findOne(RowMapper<T> mapper);
/**
* Execute the query returning a list using the mapper.
*
* @param mapper Used to map each ResultSet row into the result object.
* Deprecated migrate to use {@link #mapTo(RowMapper)}
*/
@Deprecated
<T> List<T> findList(RowMapper<T> mapper);
/**
@@ -125,77 +123,53 @@ public interface SqlQuery extends Serializable {
Optional<SqlRow> findOneOrEmpty();
/**
* Execute the query returning a single scalar attribute.
* <pre>@{code
* Deprecated - migrate to <code>.mapToScalar(attributeType).findOne()</code>.
* <pre>{@code
*
* String sql = "select max(unit_price) from o_order_detail where order_qty > ?";
*
* BigDecimal maxPrice = DB.sqlQuery(sql)
* .setParameter(1, 2)
* .findSingleAttribute(BigDecimal.class);
*
* }</pre>
*
* <p>
* The attributeType can be any scalar type that Ebean supports (includes javax time types, Joda types etc).
* </p>
*
* @param attributeType The type of the returned value
* .mapToScalar(BigDecimal.class)
* .findOne();
* }
*/
@Deprecated
<T> T findSingleAttribute(Class<T> attributeType);
/**
* Execute the query returning a single BigDecimal value.
* <p>
* This is an alias for <code>findSingleAttribute(BigDecimal.class)</code>
* </p>
* Deprecated - migrate to <code>.mapToScalar(BigDecimal.class).findOne()</code>.
* <pre>{@code
*
* .mapToScalar(BigDecimal.class)
* .findOne();
* }
*/
@Deprecated
BigDecimal findSingleDecimal();
/**
* Execute the query returning a single Long value.
* <p>
* This is an alias for <code>findSingleAttribute(Long.class)</code>
* </p>
* Deprecated - migrate to <code>.mapToScalar(Long.class).findOne()</code>.
* <pre>{@code
*
* .mapToScalar(Long.class)
* .findOne();
* }
*/
@Deprecated
Long findSingleLong();
/**
* Execute the query returning a list of scalar attribute values.
*
* Deprecated - migrate to <code>.mapToScalar(Long.class).findList()</code>.
* <pre>{@code
*
* String sql =
* " select (unit_price * order_qty) " +
* " from o_order_detail " +
* " where unit_price > ? " +
* " order by (unit_price * order_qty) desc";
*
* //
* List<BigDecimal> lineAmounts =
* DB.sqlQuery(sql)
* .setParameter(1, 3)
* .findSingleAttributeList(BigDecimal.class);
*
* }</pre>
*
* <p>
* The attributeType can be any scalar type that Ebean supports (includes javax time types, Joda types etc).
* </p>
*
* @param attributeType The type of the returned value
* .mapToScalar(Long.class)
* .findList();
* }
*/
@Deprecated
<T> List<T> findSingleAttributeList(Class<T> attributeType);
/**
* The same as bind for named parameters.
*/
SqlQuery setParameter(String name, Object value);
/**
* Set one of more positioned parameters.
* <p>
* This is a convenient alternative to multiple calls setParameter().
* This is a convenient alternative to multiple calls to {@link #setParameter(Object)}.
*
* <pre>{@code
*
@@ -203,27 +177,104 @@ public interface SqlQuery extends Serializable {
*
* List<SqlRow> list =
* DB.sqlQuery(sql)
* .setParams("Rob", Status.NEW)
* .setParameters("Rob", Status.NEW)
* .findList();
*
*
* // is the same as ...
* // effectively the same as ...
*
* .setParameter("Rob")
* .setParameter("Status.NEW)
*
* // and ...
*
* List<SqlRow> list =
* DB.sqlQuery(sql)
* .setParameter(1, "Rob")
* .setParameter(2, "Status.NEW)
* .findList();
*
* }</pre>
*/
SqlQuery setParameters(Object... values);
/**
* Deprecated migrate to setParameters(Object... values)
*/
@Deprecated
SqlQuery setParams(Object... values);
/**
* The same as bind for positioned parameters.
* Set the next bind parameter by position.
* <pre>{@code
*
* String sql = "select id, name from customer where name like ? and status = ?";
*
* List<SqlRow> list =
* DB.sqlQuery(sql)
* .setParameter("Rob")
* .setParameter("Status.NEW)
* .findList();
*
* // the same as ...
*
* .setParameters("Rob", Status.NEW)
*
* // and ...
*
* .setParameter(1, "Rob")
* .setParameter(2, "Status.NEW)
*
* }</pre>
*
* <p>
* When binding a collection of values into a IN expression we should use
* indexed parameters like ?1, ?2, ?3 etc rather than just ?.
* </p>
*
* <pre>{@code
*
* String sql = "select c.id, c.name from customer c where c.name in (?1)";
*
* List<SqlRow> rows = DB.sqlQuery(sql)
* .setParameter(asList("Rob", "Fiona", "Jack"))
* .findList();
*
*
* List<SqlRow> rows = DB.sqlQuery(sql)
* .setParameter(1, asList("Rob", "Fiona", "Jack"))
* .findList();
* }</pre>
*
* @param value The value to bind
*/
SqlQuery setParameter(Object value);
/**
* Bind the parameter by its index position (1 based like JDBC).
* <p>
* When binding a collection of values into a IN expression we should use
* indexed parameters like ?1, ?2, ?3 etc rather than just ?.
* </p>
*
* <pre>{@code
*
* String sql = "select c.id, c.name from customer c where c.name in (?1)";
*
* List<SqlRow> rows = DB.sqlQuery(sql)
* .setParameter(asList("Rob", "Fiona", "Jack"))
* .findList();
*
*
* List<SqlRow> rows = DB.sqlQuery(sql)
* .setParameter(1, asList("Rob", "Fiona", "Jack"))
* .findList();
* }</pre>
*/
SqlQuery setParameter(int position, Object value);
/**
* Bind the named parameter value.
*/
SqlQuery setParameter(String name, Object value);
/**
* Set the index of the first row of the results to return.
*/
@@ -260,4 +311,59 @@ public interface SqlQuery extends Serializable {
*/
SqlQuery setBufferFetchSizeHint(int bufferFetchSizeHint);
/**
* The query result maps to a single scalar value like Long, BigDecimal,
* String, UUID, OffsetDateTime etc.
* <p>
* Any scalar type Ebean is aware of can be used including java time
* types like Instant, LocalDate, OffsetDateTime, UUID, Inet, Cdir etc.
*
* <pre>{@code
*
* String sql = " select min(updtime) from o_order_detail " +
* " where unit_price > ? and updtime is not null ";
*
* OffsetDateTime minCreated = DB.sqlQuery(sql)
* .setParameter(42)
* .mapToScalar(OffsetDateTime.class)
* .findOne();
*
* }</pre>
*
* @param attributeType The type the result is returned as
* @return The query to execute via findOne() findList() etc
*/
<T> TypeQuery<T> mapToScalar(Class<T> attributeType);
/**
* Use a RowMapper to map the result to beans.
*
* @param mapper Maps rows to beans
* @param <T> The type of beans mapped to
* @return The query to execute by findOne() findList() etc
*/
<T> TypeQuery<T> mapTo(RowMapper<T> mapper);
/**
* Query mapping to single scalar values.
*
* @param <T> The type of the scalar values
*/
interface TypeQuery<T> {
/**
* Return the single value.
*/
T findOne();
/**
* Return the single value that is optional.
*/
Optional<T> findOneOrEmpty();
/**
* Return the list of values.
*/
List<T> findList();
}
}
@@ -5,18 +5,16 @@ package io.ebean;
* <p>
* Provides a simple way to execute raw SQL insert update or delete statements
* without having to resort to JDBC.
* </p>
* <p>
* Supports the use of positioned or named parameters and can automatically
* notify Ebean of the table modified so that Ebean can maintain its cache.
* </p>
* <p>
* Note that {@link #setAutoTableMod(boolean)} and
* Ebean#externalModification(String, boolean, boolean, boolean)} can be to
* notify Ebean of external changes and enable Ebean to maintain it's "L2"
* server cache.
* </p>
*
* <h2>Positioned parameter example</h2>
* <pre>{@code
*
* // example using 'positioned' parameters
@@ -30,6 +28,7 @@ package io.ebean;
*
* }</pre>
*
* <h2>Named parameter example</h2>
* <pre>{@code
*
* // example using 'named' parameters
@@ -45,8 +44,31 @@ package io.ebean;
* String msg = "There were " + rows + " rows updated";
*
* }</pre>
*
* <h2>Index parameter examples (e.g. ?1, ?2, ?3 ...)</h2>
* <p>
* <h3>Example: Using setNextParameter()</h3>
* We can use index parameters like ?1, ?2, ?3 etc when binding arrays/collections
* of values into an IN expression.
* </p>
* <pre>{@code
*
* // Binding a list of 3 values (9991, 9992, 9993) into an IN expression
*
* DB.sqlUpdate("delete from o_customer where name = ? and id in (?2)")
* .setParameter(1, "Foo")
* .setParameter(2, asList(9991, 9992, 9993))
* .execute();
*
* // note this effectively is the same as
*
* DB.sqlUpdate("delete from o_customer where name = ? and id in (?2)")
* .setParameter("Foo")
* .setParameter(asList(9991, 9992, 9993))
* .execute();
*
* }</pre>
*
* <h3>Example: Using setParameter()</h3>
* <pre>{@code
*
* String sql = "insert into audit_log (id, description, modified_description) values (?,?,?)";
@@ -56,19 +78,19 @@ package io.ebean;
* try (Transaction txn = DB.beginTransaction()) {
* txn.setBatchMode(true);
*
* insert.setNextParameter(10000);
* insert.setNextParameter("hello");
* insert.setNextParameter("rob");
* insert.setParameter(10000);
* insert.setParameter("hello");
* insert.setParameter("rob");
* insert.execute();
*
* insert.setNextParameter(10001);
* insert.setNextParameter("goodbye");
* insert.setNextParameter("rob");
* insert.setParameter(10001);
* insert.setParameter("goodbye");
* insert.setParameter("rob");
* insert.execute();
*
* insert.setNextParameter(10002);
* insert.setNextParameter("chow");
* insert.setNextParameter("bob");
* insert.setParameter(10002);
* insert.setParameter("chow");
* insert.setParameter("bob");
* insert.execute();
*
* txn.commit();
@@ -81,19 +103,19 @@ package io.ebean;
*
* try (Transaction txn = DB.beginTransaction()) {
*
* insert.setNextParameter(10000);
* insert.setNextParameter("hello");
* insert.setNextParameter("rob");
* insert.setParameter(10000);
* insert.setParameter("hello");
* insert.setParameter("rob");
* insert.addBatch();
*
* insert.setNextParameter(10001);
* insert.setNextParameter("goodbye");
* insert.setNextParameter("rob");
* insert.setParameter(10001);
* insert.setParameter("goodbye");
* insert.setParameter("rob");
* insert.addBatch();
*
* insert.setNextParameter(10002);
* insert.setNextParameter("chow");
* insert.setNextParameter("bob");
* insert.setParameter(10002);
* insert.setParameter("chow");
* insert.setParameter("bob");
* insert.addBatch();
*
* int[] rows = insert.executeBatch();
@@ -126,8 +148,6 @@ public interface SqlUpdate {
* {@link Transaction#setBatchMode(boolean)} and
* {@link Transaction#setBatchSize(int)}.
* </p>
*
* @see Ebean#execute(SqlUpdate)
*/
int execute();
@@ -241,28 +261,47 @@ public interface SqlUpdate {
* String sql = "insert into audit_log (id, name, version) values (?,?,?)";
*
* DB.sqlUpdate(sql)
* .setParams(UUID.randomUUID(), "Hello", 1)
* .setParameters(UUID.randomUUID(), "Hello", 1)
* .executeNow();
*
*
* // is the same as ...
*
* DB.sqlUpdate(sql)
* .setParameter(UUID.randomUUID())
* .setParameter("Hello")
* .setParameter(1)
* .executeNow();
*
* // which is the same as ...
*
* DB.sqlUpdate(sql)
* .setParameter(1, UUID.randomUUID())
* .setParameter(2, "Hello")
* .setParameter(3, 1)
* .executeNow();
*
* }</pre>
*
*/
SqlUpdate setParameters(Object... values);
/**
* Deprecated migrate to setParameters(Object... values).
*/
@Deprecated
SqlUpdate setParams(Object... values);
/**
* Set the next positioned parameter.
* Set the next bind parameter by position.
*
* @param value The value to bind
*/
SqlUpdate setParameter(Object value);
/**
* Deprecated migrate to setParameter(value).
*/
@Deprecated
SqlUpdate setNextParameter(Object value);
/**
@@ -3,7 +3,7 @@ package io.ebean;
import io.ebean.annotation.DocStoreMode;
import io.ebean.annotation.PersistBatch;
import io.ebean.config.DocStoreConfig;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import javax.persistence.PersistenceException;
import java.sql.Connection;
@@ -27,7 +27,7 @@ public interface Transaction extends AutoCloseable {
* @see Database#currentTransaction()
*/
static Transaction current() {
return Ebean.currentTransaction();
return DB.currentTransaction();
}
/**
@@ -226,7 +226,7 @@ public interface Transaction extends AutoCloseable {
/**
* Set if the L2 cache should be skipped for "find by id" and "find by natural key" queries.
* <p>
* By default {@link ServerConfig#isSkipCacheAfterWrite()} is true and that means that for
* By default {@link DatabaseConfig#isSkipCacheAfterWrite()} is true and that means that for
* "find by id" and "find by natural key" queries which normally hit L2 bean cache automatically
* - will not do so after a persist/write on the transaction.
* </p>
@@ -235,7 +235,7 @@ public interface Transaction extends AutoCloseable {
* will skip the L2 bean cache or not (regardless of whether the transaction is considered "read only").
* </p>
* <p>
* Refer to {@link ServerConfig#setSkipCacheAfterWrite(boolean)} for configuring the default behavior
* Refer to {@link DatabaseConfig#setSkipCacheAfterWrite(boolean)} for configuring the default behavior
* for using the L2 bean cache in transactions spanning multiple query/persist requests.
* </p>
*
@@ -276,7 +276,7 @@ public interface Transaction extends AutoCloseable {
*
* }</pre>
*
* @see ServerConfig#isSkipCacheAfterWrite()
* @see DatabaseConfig#isSkipCacheAfterWrite()
*/
void setSkipCache(boolean skipCache);
@@ -295,7 +295,7 @@ public interface Transaction extends AutoCloseable {
*
* <pre>{@code
*
* try (Transaction transaction = server.beginTransaction()) {
* try (Transaction transaction = database.beginTransaction()) {
*
* // turn on JDBC batch
* transaction.setBatchMode(true);
@@ -313,12 +313,12 @@ public interface Transaction extends AutoCloseable {
* <h3>getGeneratedKeys</h3>
* <p>
* Often with large batch inserts we want to turn off getGeneratedKeys. We do
* this via {@link #setBatchGetGeneratedKeys(boolean)}.
* this via {@link #setGetGeneratedKeys(boolean)}.
* Also note that some JDBC drivers do not support getGeneratedKeys in JDBC batch mode.
* </p>
* <pre>{@code
*
* try (Transaction transaction = server.beginTransaction()) {
* try (Transaction transaction = database.beginTransaction()) {
*
* transaction.setBatchMode(true);
* transaction.setBatchSize(100);
@@ -342,7 +342,7 @@ public interface Transaction extends AutoCloseable {
* </p>
* <p>
* We use {@link #flush()} to explicitly flush the batch and we can use
* {@link #setBatchFlushOnQuery(boolean)} and {@link #setBatchFlushOnMixed(boolean)}
* {@link #setFlushOnQuery(boolean)} and {@link #setFlushOnMixed(boolean)}
* to control the automatic flushing behaviour.
* </p>
* <p>
@@ -402,7 +402,7 @@ public interface Transaction extends AutoCloseable {
* </p>
*
* @param batchMode the batch mode to use per save(), insert(), update() or delete()
* @see io.ebean.config.ServerConfig#setPersistBatchOnCascade(PersistBatch)
* @see io.ebean.config.DatabaseConfig#setPersistBatchOnCascade(PersistBatch)
*/
void setBatchOnCascade(boolean batchMode);
@@ -432,7 +432,15 @@ public interface Transaction extends AutoCloseable {
* number of objects and you don't care about getting back the ids.
* </p>
*/
void setBatchGetGeneratedKeys(boolean getGeneratedKeys);
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
@@ -449,7 +457,15 @@ public interface Transaction extends AutoCloseable {
* have a 2 step process (delayed binding).
* </p>
*/
void setBatchFlushOnMixed(boolean batchFlushOnMixed);
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
@@ -459,7 +475,15 @@ public interface Transaction extends AutoCloseable {
* execute a query and the batch will not be automatically flushed.
* </p>
*/
void setBatchFlushOnQuery(boolean batchFlushOnQuery);
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)
@@ -468,7 +492,15 @@ public interface Transaction extends AutoCloseable {
* The default is for this to be true.
* </p>
*/
boolean isBatchFlushOnQuery();
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
@@ -12,16 +12,16 @@ import java.util.concurrent.Callable;
* <p>
* This information matches the features of the Transactional annotation. You
* can use it directly with Runnable or Callable via
* {@link Ebean#execute(TxScope, Runnable)} or
* {@link Ebean#executeCall(TxScope, Callable)}.
* {@link DB#execute(TxScope, Runnable)} or
* {@link DB#executeCall(TxScope, Callable)}.
* </p>
* <p>
* This object is used internally with the enhancement of a method with
* Transactional annotation.
* </p>
*
* @see Ebean#execute(TxScope, Runnable)
* @see Ebean#executeCall(TxScope, Callable)
* @see DB#execute(TxScope, Runnable)
* @see DB#executeCall(TxScope, Callable)
*/
public final class TxScope {
@@ -12,26 +12,27 @@ package io.ebean;
* The following is an example of named updates on an entity bean.
* </p>
* <pre>{@code
* ...
* @NamedUpdates(value = {
* @NamedUpdate(
* name = "setTitle",
* notifyCache = false,
* update = "update topic set title = :title, postCount = :count where id = :id"),
* @NamedUpdate(
* name = "setPostCount",
* notifyCache = false,
* update = "update f_topic set post_count = :postCount where id = :id"),
* @NamedUpdate(
* name = "incrementPostCount",
* notifyCache = false,
* update = "update Topic set postCount = postCount + 1 where id = :id")
* //update = "update f_topic set post_count = post_count + 1 where id = :id")
* })
* @Entity
* @Table(name = "f_topic")
* public class Topic {
* ...
* ...
* NamedUpdates(value = {
* NamedUpdate(
* name = "setTitle",
* notifyCache = false,
* update = "update topic set title = :title, postCount = :count where id = :id"),
* NamedUpdate(
* name = "setPostCount",
* notifyCache = false,
* update = "update f_topic set post_count = :postCount where id = :id"),
* NamedUpdate(
* name = "incrementPostCount",
* notifyCache = false,
* update = "update Topic set postCount = postCount + 1 where id = :id")
* //update = "update f_topic set post_count = post_count + 1 where id = :id")
* })
* Entity
* Table(name = "f_topic")
* public class Topic {
* ...
* }
* }</pre>
*
* <p>
@@ -20,29 +20,23 @@ class XServiceProvider {
private static SpiFetchGroupService fetchGroupService = initSpiFetchGroupService();
private static SpiFetchGroupService initSpiFetchGroupService() {
Iterator<SpiFetchGroupService> loader = ServiceLoader.load(SpiFetchGroupService.class).iterator();
if (loader.hasNext()) {
return loader.next();
}
throw new IllegalStateException("No service implementation found for SpiFetchGroupService?");
return loadFirstService(SpiFetchGroupService.class);
}
private static SpiRawSqlService initRawSql() {
Iterator<SpiRawSqlService> loader = ServiceLoader.load(SpiRawSqlService.class).iterator();
if (loader.hasNext()) {
return loader.next();
}
throw new IllegalStateException("No service implementation found for SpiRawSqlService?");
return loadFirstService(SpiRawSqlService.class);
}
private static SpiProfileLocationFactory initProfileLocation() {
return loadFirstService(SpiProfileLocationFactory.class);
}
Iterator<SpiProfileLocationFactory> loader = ServiceLoader.load(SpiProfileLocationFactory.class).iterator();
private static <T> T loadFirstService(Class<T> cls) {
Iterator<T> loader = ServiceLoader.load(cls).iterator();
if (loader.hasNext()) {
return loader.next();
}
throw new IllegalStateException("No service implementation found for SpiProfileLocationFactory?");
throw new IllegalStateException("No service implementation found for " + cls);
}
/**
@@ -1,5 +1,7 @@
package io.ebean.bean;
import java.util.concurrent.locks.Lock;
/**
* Loads a entity bean.
* <p>
@@ -18,4 +20,9 @@ public interface BeanLoader {
*/
void loadBean(EntityBeanIntercept ebi);
/**
* Obtain a lock on the loader.
*/
Lock lock();
}
@@ -1,6 +1,7 @@
package io.ebean.bean;
import io.ebean.Ebean;
import io.ebean.DB;
import io.ebean.Database;
import io.ebean.ValuePair;
import javax.persistence.EntityNotFoundException;
@@ -13,6 +14,8 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* This is the object added to every entity bean using byte code enhancement.
@@ -29,6 +32,8 @@ public final class EntityBeanIntercept implements Serializable {
private static final int STATE_REFERENCE = 1;
private static final int STATE_LOADED = 2;
private transient final ReentrantLock lock = new ReentrantLock(false);
private transient NodeUsageCollector nodeUsageCollector;
private transient PersistenceContext persistenceContext;
@@ -39,6 +44,8 @@ public final class EntityBeanIntercept implements Serializable {
private String ebeanServerName;
private boolean deletedFromCollection;
/**
* The actual entity bean that 'owns' this intercept.
*/
@@ -79,14 +86,14 @@ public final class EntityBeanIntercept implements Serializable {
private static final byte FLAG_CHANGED_PROP = 2;
/**
* Flags indicating if a property is a dirty embedded bean. Used to distingush
* Flags indicating if a property is a dirty embedded bean. Used to distinguish
* between an embedded bean being completely overwritten and one of its
* embedded properties being made dirty.
*/
private static final byte FLAG_EMBEDDED_DIRTY = 4;
/**
* Flags indicating if a property is a dirty embedded bean. Used to distingush
* Flags indicating if a property is a dirty embedded bean. Used to distinguish
* between an embedded bean being completely overwritten and one of its
* embedded properties being made dirty.
*/
@@ -104,9 +111,6 @@ public final class EntityBeanIntercept implements Serializable {
/**
* Create a intercept with a given entity.
* <p>
* Refer to agent ProxyConstructor.
* </p>
*/
public EntityBeanIntercept(Object ownerBean) {
this.owner = (EntityBean) ownerBean;
@@ -371,13 +375,11 @@ public final class EntityBeanIntercept implements Serializable {
/**
* Set the loaded state to true.
* <p>
* Calls to setter methods after the bean is loaded can result in 'Old Values'
* being created to support ConcurrencyMode.ALL
* </p>
* Calls to setter methods after the bean is loaded can result in
* 'Old Values' being created.
* <p>
* Worth noting that this is also set after a insert/update. By doing so it
* 'resets' the bean for making further changes and saving again.
* </p>
*/
public void setLoaded() {
this.state = STATE_LOADED;
@@ -391,8 +393,7 @@ public final class EntityBeanIntercept implements Serializable {
}
/**
* When finished loading for lazy or refresh on an already partially populated
* bean.
* When finished loading for lazy or refresh on an already partially populated bean.
*/
public void setLoadedLazy() {
this.state = STATE_LOADED;
@@ -423,9 +424,6 @@ public final class EntityBeanIntercept implements Serializable {
/**
* Set true to turn off lazy loading.
* <p>
* Typically used to disable lazy loading on SQL based report beans.
* </p>
*/
public void setDisableLazyLoad(boolean disableLazyLoad) {
this.disableLazyLoad = disableLazyLoad;
@@ -445,7 +443,6 @@ public final class EntityBeanIntercept implements Serializable {
* Return true if the embedded bean is new or dirty and hence needs saving.
*/
public boolean isEmbeddedNewOrDirty(Object embeddedBean) {
if (embeddedBean == null) {
// if it was previously set then the owning bean would
// have oldValues containing the previous embedded bean
@@ -453,7 +450,6 @@ public final class EntityBeanIntercept implements Serializable {
}
if (embeddedBean instanceof EntityBean) {
return ((EntityBean) embeddedBean)._ebean_getIntercept().isNewOrDirty();
} else {
// non-enhanced so must assume it is new and needs to be saved
return true;
@@ -471,8 +467,8 @@ public final class EntityBeanIntercept implements Serializable {
}
/**
* Finds the index position of a given property. Returns -1 if the property
* can not be found.
* Finds the index position of a given property. Returns -1 if the
* property can not be found.
*/
public int findProperty(String propertyName) {
String[] names = owner._ebean_getPropertyNames();
@@ -495,7 +491,7 @@ public final class EntityBeanIntercept implements Serializable {
}
/**
* Return the number of properties.s
* Return the number of properties.
*/
public int getPropertyLength() {
return owner._ebean_getPropertyNames().length;
@@ -517,8 +513,7 @@ public final class EntityBeanIntercept implements Serializable {
}
/**
* Set the property to be treated as unloaded. Used for properties initialised in default
* constructor.
* Set the property to be treated as unloaded. Used for properties initialised in default constructor.
*/
public void setPropertyUnloaded(int propertyIndex) {
flags[propertyIndex] &= ~FLAG_LOADED_PROP;
@@ -605,7 +600,6 @@ public final class EntityBeanIntercept implements Serializable {
* For forced update on a 'New' bean set all the loaded properties to changed.
*/
public void setNewBeanForUpdate() {
for (int i = 0; i < flags.length; i++) {
if ((flags[i] & FLAG_LOADED_PROP) != 0) {
flags[i] |= FLAG_CHANGED_PROP;
@@ -660,8 +654,7 @@ public final class EntityBeanIntercept implements Serializable {
for (int i = 0; i < len; i++) {
if ((flags[i] & FLAG_CHANGED_PROP) != 0) {
// the property has been changed on this bean
String propName = (prefix == null ? getProperty(i) : prefix + getProperty(i));
props.add(propName);
props.add((prefix == null ? getProperty(i) : prefix + getProperty(i)));
} else if ((flags[i] & FLAG_EMBEDDED_DIRTY) != 0) {
// an embedded property has been changed - recurse
EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i);
@@ -674,12 +667,10 @@ public final class EntityBeanIntercept implements Serializable {
* Return true if any of the given property names are dirty.
*/
public boolean hasDirtyProperty(Set<String> propertyNames) {
String[] names = owner._ebean_getPropertyNames();
int len = getPropertyLength();
for (int i = 0; i < len; i++) {
if ((flags[i] & FLAG_CHANGED_PROP) != 0) {
// the property has been changed on this bean
if (propertyNames.contains(names[i])) {
return true;
}
@@ -712,10 +703,9 @@ public final class EntityBeanIntercept implements Serializable {
String propName = (prefix == null ? getProperty(i) : prefix + getProperty(i));
Object newVal = owner._ebean_getField(i);
Object oldVal = getOrigValue(i);
if (!areEqual(oldVal, newVal)) {
if (notEqual(oldVal, newVal)) {
dirtyValues.put(propName, new ValuePair(newVal, oldVal));
}
} else if ((flags[i] & FLAG_EMBEDDED_DIRTY) != 0) {
// an embedded property has been changed - recurse
EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i);
@@ -734,10 +724,9 @@ public final class EntityBeanIntercept implements Serializable {
// the property has been changed on this bean
Object newVal = owner._ebean_getField(i);
Object oldVal = getOrigValue(i);
if (!areEqual(oldVal, newVal)) {
if (notEqual(oldVal, newVal)) {
visitor.visit(i, newVal, oldVal);
}
} else if ((flags[i] & FLAG_EMBEDDED_DIRTY) != 0) {
// an embedded property has been changed - recurse
EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i);
@@ -758,7 +747,7 @@ public final class EntityBeanIntercept implements Serializable {
}
/**
* Add and return a dirty property hash recursing into embedded beans.
* Add and return a dirty property hash.
*/
private void addDirtyPropertyKey(StringBuilder sb) {
if (sortOrder > 0) {
@@ -818,25 +807,28 @@ public final class EntityBeanIntercept implements Serializable {
* Load the bean when it is a reference.
*/
protected void loadBean(int loadProperty) {
synchronized (this) {
lock.lock();
try {
if (beanLoader == null) {
BeanLoader serverLoader = (BeanLoader) Ebean.getServer(ebeanServerName);
if (serverLoader == null) {
throw new PersistenceException("Server [" + ebeanServerName + "] was not found?");
final Database database = DB.byName(ebeanServerName);
if (database == null) {
throw new PersistenceException("Database [" + ebeanServerName + "] was not found?");
}
// For stand alone reference bean or after deserialisation lazy load
// using the ebeanServer. Synchronise only on the bean.
loadBeanInternal(loadProperty, serverLoader);
loadBeanInternal(loadProperty, database.getPluginApi().beanLoader());
return;
}
} finally {
lock.unlock();
}
synchronized (beanLoader) {
final Lock lock = beanLoader.lock();
try {
// Lazy loading using LoadBeanContext which supports batch loading
// Synchronise on the beanLoader (a 'node' of the LoadBeanContext 'tree')
loadBeanInternal(loadProperty, beanLoader);
} finally {
lock.unlock();
}
}
@@ -844,32 +836,24 @@ public final class EntityBeanIntercept implements Serializable {
* Invoke the lazy loading. This method is synchronised externally.
*/
private void loadBeanInternal(int loadProperty, BeanLoader loader) {
if ((flags[loadProperty] & FLAG_LOADED_PROP) != 0) {
// race condition where multiple threads calling preGetter concurrently
return;
}
if (lazyLoadFailure) {
// failed when batch lazy loaded by another bean in the batch
throw new EntityNotFoundException("(Lazy) loading failed on type:" + owner.getClass().getName() + " id:" + ownerId + " - Bean has been deleted");
}
if (lazyLoadProperty == -1) {
lazyLoadProperty = loadProperty;
if (nodeUsageCollector != null) {
nodeUsageCollector.setLoadProperty(getProperty(lazyLoadProperty));
}
loader.loadBean(this);
if (lazyLoadFailure) {
// failed when lazy loading this bean
throw new EntityNotFoundException("Lazy loading failed on type:" + owner.getClass().getName() + " id:" + ownerId + " - Bean has been deleted.");
}
// bean should be loaded and intercepting now. setLoaded() has
// been called by the lazy loading mechanism
}
@@ -879,32 +863,31 @@ public final class EntityBeanIntercept implements Serializable {
* Helper method to check if two objects are equal.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
protected boolean areEqual(Object obj1, Object obj2) {
protected static boolean notEqual(Object obj1, Object obj2) {
if (obj1 == null) {
return (obj2 == null);
return (obj2 != null);
}
if (obj2 == null) {
return false;
return true;
}
if (obj1 == obj2) {
return true;
return false;
}
if (obj1 instanceof BigDecimal) {
// Use comparable for BigDecimal as equals
// uses scale in comparison...
if (obj2 instanceof BigDecimal) {
Comparable com1 = (Comparable) obj1;
return (com1.compareTo(obj2) == 0);
return (com1.compareTo(obj2) != 0);
} else {
return false;
return true;
}
}
if (obj1 instanceof URL) {
// use the string format to determine if dirty
return obj1.toString().equals(obj2.toString());
return !obj1.toString().equals(obj2.toString());
}
return obj1.equals(obj2);
return !obj1.equals(obj2);
}
/**
@@ -915,6 +898,7 @@ public final class EntityBeanIntercept implements Serializable {
}
private void preGetterCallback(int propertyIndex) {
PreGetterCallback preGetterCallback = this.preGetterCallback;
if (preGetterCallback != null) {
preGetterCallback.preGetterTrigger(propertyIndex);
}
@@ -944,25 +928,20 @@ public final class EntityBeanIntercept implements Serializable {
}
/**
* OneToMany and ManyToMany don't have any interception so just check for
* PropertyChangeSupport.
* OneToMany and ManyToMany only set loaded state.
*/
public void preSetterMany(boolean interceptField, int propertyIndex, Object oldValue, Object newValue) {
if (readOnly) {
throw new IllegalStateException("This bean is readOnly");
}
setLoadedProperty(propertyIndex);
}
private void setChangedPropertyValue(int propertyIndex, boolean setDirtyState, Object origValue) {
if (readOnly) {
throw new IllegalStateException("This bean is readOnly");
}
setChangedProperty(propertyIndex);
if (setDirtyState) {
setOriginalValue(propertyIndex, origValue);
setDirtyStatus();
@@ -987,10 +966,9 @@ public final class EntityBeanIntercept implements Serializable {
* the old values for use with ConcurrencyMode.ALL.
*/
public void preSetter(boolean intercept, int propertyIndex, Object oldValue, Object newValue) {
if (state == STATE_NEW) {
setLoadedProperty(propertyIndex);
} else if (!areEqual(oldValue, newValue)) {
} else if (notEqual(oldValue, newValue)) {
setChangedPropertyValue(propertyIndex, intercept, oldValue);
}
}
@@ -1000,7 +978,6 @@ public final class EntityBeanIntercept implements Serializable {
* Check for primitive boolean.
*/
public void preSetter(boolean intercept, int propertyIndex, boolean oldValue, boolean newValue) {
if (state == STATE_NEW) {
setLoadedProperty(propertyIndex);
} else if (oldValue != newValue) {
@@ -1012,7 +989,6 @@ public final class EntityBeanIntercept implements Serializable {
* Check for primitive int.
*/
public void preSetter(boolean intercept, int propertyIndex, int oldValue, int newValue) {
if (state == STATE_NEW) {
setLoadedProperty(propertyIndex);
} else if (oldValue != newValue) {
@@ -1024,7 +1000,6 @@ public final class EntityBeanIntercept implements Serializable {
* long.
*/
public void preSetter(boolean intercept, int propertyIndex, long oldValue, long newValue) {
if (state == STATE_NEW) {
setLoadedProperty(propertyIndex);
} else if (oldValue != newValue) {
@@ -1036,7 +1011,6 @@ public final class EntityBeanIntercept implements Serializable {
* double.
*/
public void preSetter(boolean intercept, int propertyIndex, double oldValue, double newValue) {
if (state == STATE_NEW) {
setLoadedProperty(propertyIndex);
} else if (Double.compare(oldValue, newValue) != 0) {
@@ -1048,7 +1022,6 @@ public final class EntityBeanIntercept implements Serializable {
* float.
*/
public void preSetter(boolean intercept, int propertyIndex, float oldValue, float newValue) {
if (state == STATE_NEW) {
setLoadedProperty(propertyIndex);
} else if (Float.compare(oldValue, newValue) != 0) {
@@ -1060,7 +1033,6 @@ public final class EntityBeanIntercept implements Serializable {
* short.
*/
public void preSetter(boolean intercept, int propertyIndex, short oldValue, short newValue) {
if (state == STATE_NEW) {
setLoadedProperty(propertyIndex);
} else if (oldValue != newValue) {
@@ -1072,7 +1044,6 @@ public final class EntityBeanIntercept implements Serializable {
* char.
*/
public void preSetter(boolean intercept, int propertyIndex, char oldValue, char newValue) {
if (state == STATE_NEW) {
setLoadedProperty(propertyIndex);
} else if (oldValue != newValue) {
@@ -1084,7 +1055,6 @@ public final class EntityBeanIntercept implements Serializable {
* byte.
*/
public void preSetter(boolean intercept, int propertyIndex, byte oldValue, byte newValue) {
if (state == STATE_NEW) {
setLoadedProperty(propertyIndex);
} else if (oldValue != newValue) {
@@ -1096,7 +1066,6 @@ public final class EntityBeanIntercept implements Serializable {
* char[].
*/
public void preSetter(boolean intercept, int propertyIndex, char[] oldValue, char[] newValue) {
if (state == STATE_NEW) {
setLoadedProperty(propertyIndex);
} else if (!Arrays.equals(oldValue, newValue)) {
@@ -1108,7 +1077,6 @@ public final class EntityBeanIntercept implements Serializable {
* byte[].
*/
public void preSetter(boolean intercept, int propertyIndex, byte[] oldValue, byte[] newValue) {
if (state == STATE_NEW) {
setLoadedProperty(propertyIndex);
} else if (!Arrays.equals(oldValue, newValue)) {
@@ -1139,6 +1107,17 @@ public final class EntityBeanIntercept implements Serializable {
this.sortOrder = sortOrder;
}
/**
* Set if the entity was deleted from a BeanCollection.
*/
public void setDeletedFromCollection(final boolean deletedFromCollection) {
this.deletedFromCollection = deletedFromCollection;
}
public boolean isOrphanDelete() {
return deletedFromCollection && !isNew();
}
/**
* Set the load error that happened on this property.
*/
@@ -61,6 +61,22 @@ public interface PersistenceContext {
*/
int size(Class<?> rootType);
/**
* Return a copy of the Persistence context to use for large query iteration.
*/
PersistenceContext forIterate();
/**
* Return a new Persistence context during iteration of large query result.
*/
PersistenceContext forIterateReset();
/**
* Return true if the persistence context has grown and hit the 'reset limit'
* during large query iteration.
*/
boolean resetLimit();
/**
* Wrapper on a bean to also indicate if a bean has been deleted.
* <p>
@@ -0,0 +1,73 @@
package io.ebean.bean;
import io.ebean.Database;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* BeanLoader used when single beans are loaded (which is usually not ideal / N+1).
*/
public abstract class SingleBeanLoader implements BeanLoader {
private final ReentrantLock lock = new ReentrantLock(false);
protected final Database database;
SingleBeanLoader(Database database) {
this.database = database;
}
@Override
public String getName() {
return database.getName();
}
@Override
public Lock lock() {
lock.lock();
return lock;
}
/**
* Single bean lazy loaded when bean from L2 cache.
*/
public static class L2 extends SingleBeanLoader {
public L2(Database database) {
super(database);
}
@Override
public void loadBean(EntityBeanIntercept ebi) {
database.getPluginApi().loadBeanL2(ebi);
}
}
/**
* Single bean lazy loaded when a reference bean.
*/
public static class Ref extends SingleBeanLoader {
public Ref(Database database) {
super(database);
}
@Override
public void loadBean(EntityBeanIntercept ebi) {
database.getPluginApi().loadBeanRef(ebi);
}
}
/**
* Single bean lazy loaded when a reference bean.
*/
public static class Dflt extends SingleBeanLoader {
public Dflt(Database database) {
super(database);
}
@Override
public void loadBean(EntityBeanIntercept ebi) {
database.getPluginApi().loadBean(ebi);
}
}
}

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