Compare commits

...
Author SHA1 Message Date
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 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
rob bygrave 5785124a2b [maven-release-plugin] prepare release ebean-12.1.2 2019-10-17 15:25:18 +13:00
rob bygrave 4d1c0bfaa8 Change parent to java8-oss 2.1 2019-10-17 15:23:35 +13:00
rob bygrave 9a29c988cd #1845 - Refactor for Persisting ElementCollection to limit max JDBC batch size 2019-10-17 15:18:43 +13:00
rob bygrave 80309f844e #1844 - Persisting an update of ElementCollection with JDBC batch, ensure delete, insert batch order 2019-10-17 12:32:13 +13:00
rob bygrave 56ddc49ab4 Element collection persist - initial 2019-10-17 10:17:03 +13:00
rob bygrave 1e7de83019 Element collection persist - initial 2019-10-17 10:15:58 +13:00
rob bygrave 1db1f0312a No effective change - bump provided jaxb-runtime dependency to 2.3.2 2019-10-14 16:03:56 +13:00
rob bygrave d27bf14887 touch readme 2019-10-14 09:21:41 +13:00
rob bygrave d4e7d4eebc [maven-release-plugin] prepare for next development iteration 2019-10-13 12:22:55 +13:00
rob bygrave 30c44d0928 [maven-release-plugin] prepare release ebean-12.1.1 2019-10-13 12:22:44 +13:00
rob bygrave 443c5dba58 Bump ebean-migration version 2019-10-13 12:20:59 +13:00
rob bygrave f24b4dba71 #1837 (#1740 and #1744) - Inheritance on both sides of @ManyToOne
This change also relates back to #1740 and #1744 and changes the way that issue was fixed (by SqlTreeNodeBean on partially populated non-id inheritance bean).
2019-10-13 11:46:11 +13:00
Rob BygraveandGitHub a474880735 #1837 - Inheritance on both sides of @ManyToOne confuses columns (#1843)
* #1837 - Inheritance on both sides of @ManyToOne confuses columns

* #1837 - Inheritance on both sides of @ManyToOne confuses columns

Tidy up whitespace in SQL
2019-10-12 00:25:53 +13:00
rob bygrave 4cfab3a2de #1842 - Refactor persisting to delay the setting of generated Id value (sequences and deferred imported ids) 2019-10-11 20:50:47 +13:00
rob bygrave 4807070147 #1841 - SqlServer findCount with @Aggregation gives SQLException:No column name was specified for column 2 of 'c' 2019-10-11 20:26:35 +13:00
rob bygrave e00aa479ae #1841 - SqlServer findCount with @Aggregation gives SQLException:No column name was specified for column 2 of 'c' 2019-10-11 20:18:18 +13:00
rob bygrave b665d8375c #1831 - Update query with maxRows does not include the limit in the generated SQL 2019-10-11 17:01:30 +13:00
Rob BygraveandGitHub 4e74c68603 Merge pull request #1840 from FOCONIS/exists-use-query-copy
exists() limits the max rows on the query, this should be done on a copy
2019-10-10 23:28:48 +13:00
Manuel Danisch 2694aa3fe1 Fixed test 2019-10-10 11:28:24 +02:00
rob bygrave f7a28aa904 Javadoc fixes 2019-10-10 22:07:14 +13:00
rob bygrave 4bc2559e8e Refactor tidy PersistRequestBean 2019-10-10 21:51:31 +13:00
rob bygrave c2faf0e0a7 No effective change - tidy tests 2019-10-10 21:42:34 +13:00
Manuel Danisch 895b331e8f exists() limits the max rows on the query, this should be done on a copy 2019-10-10 10:42:04 +02:00
rob bygrave 8890079b80 #1839 - Fix JSON marshalling of @ElementCollection maps and scalar 2019-10-10 21:32:44 +13:00
rob bygrave 20dd33ebca Fix DbMigration test for MySql without I__create_procs.sql 2019-10-10 19:07:36 +13:00
rob bygrave e2a1489743 Fix DbMigration test for MySql without I__create_procs.sql 2019-10-10 15:26:50 +13:00
rob bygrave d6bab46ac3 #1838 - Fix for Joda LocalTime timezone handling for MySql 2019-10-10 15:16:12 +13:00
rob bygrave 573673ef2b Fix for tests, make MySql like escape consistent with others 2019-10-10 15:14:38 +13:00
rob bygrave eb69499ca3 #1835 Fix with Refactor batch escalation for deferred imported Id 2019-10-10 15:13:21 +13:00
rob bygrave d9323b8ab6 Fix DbMigration test for MySql without I__create_procs.sql 2019-10-10 15:11:25 +13:00
rob bygrave a01ba128e5 Fix test for TestDbArray_basic.nullItems() for DB's that don't support ARRAY type 2019-10-10 15:10:44 +13:00
rob bygrave fdc67b3ce5 #1823 - ENH: Add query.findStream() and query.findLargeStream() 2019-10-10 13:44:29 +13:00
rob bygrave 5d433ff603 Make it easier for people building using JDK11
Note that our javadoc doclet isn't JDK11 compatible yet
2019-10-10 12:04:09 +13:00
rob bygrave a3f9c4c889 #1836 - NPE with findCount() on bean with @Aggregation, Regression in 11.45.1 2019-10-10 08:55:01 +13:00
Rob BygraveandGitHub 769fc485ec Merge pull request #1835 from ebean-orm/feature/persistCascadeEscalate
Refactor JDBC batch escalation and detection of deferred persist relationship (circular imported ids)
2019-10-09 17:08:09 +13:00
rob bygrave 61ef4fa420 #1835 Refactor JDBC batch escalation 2019-10-09 00:37:06 +13:00
rob bygrave 8cf37e2f0a #1835 Refactor JDBC batch escalation 2019-10-09 00:18:15 +13:00
rob bygrave 80a764a448 #1835 Refactor JDBC batch escalation 2019-10-09 00:17:34 +13:00
rob bygrave 6621c5dfbb Refactor detection of deferred persist relationship (circular imported ids) 2019-10-08 21:49:22 +13:00
rob bygrave 5e7dda1ec8 #1834 - DDL for ElementCollection that is referenced multiple times includes foreign key constraint 2019-10-08 15:53:29 +13:00
rob bygrave 7bc6368f69 #1833 - When cascade persisting twice to ElementCollection ... we get do extra delete and inserts 2019-10-08 13:25:33 +13:00
rob bygrave fb5a69adea #1833 - When cascade persisting twice to ElementCollection ... we get do extra delete and inserts 2019-10-08 13:25:18 +13:00
rob bygrave 0e7607bb27 Log warning when initSql or seedSql is not found as a resource 2019-10-08 09:15:20 +13:00
rob bygrave 1098b572fe #1832 - Cascade insert @ElementCollection when marshalled from JSON 2019-10-07 15:48:31 +13:00
rob bygrave 7a6662a2dc #1830 - Bump ebean-migration dependency to 11.22.1 2019-10-07 13:49:20 +13:00
rob bygrave 1c6c812d4d Update tests change AssertJ StrictAssertions to Assertions 2019-10-06 16:34:44 +13:00
rob bygrave e58a85f0af #1356 - allQuotedIdentifiers must be respected by DDL 2019-10-06 16:32:06 +13:00
rob bygrave e3551152bb #1829 - Bump Jackson core dependency from 2.9.9 to 2.10.0 2019-10-05 23:41:16 +13:00
rob bygrave 5138d1723f Merge branch 'feature/1656' 2019-10-05 23:20:26 +13:00
rob bygrave 9b5ab542d7 #1827 - @UniqueConstraint columnNames should be respecting ebean.allQuotedIdentifiers 2019-10-05 22:37:06 +13:00
rob bygrave f0bc4c786c #1826 - Remove PrivateOwned, migrate to orphanRemoval=true attribute on OneToMany 2019-09-24 22:36:17 +12:00
rob bygrave b98739bb49 #1656 #1824 Stateless updates - Remove update deleteMissingChildren option, instead always use orphanRemoval
Adjust test that doesn't have orphanRemoval (so missing children are not removed here now)
2019-09-20 17:18:07 +12:00
rob bygrave fcadc63338 #1656 #1824 Stateless updates - Remove update deleteMissingChildren option, instead always use orphanRemoval 2019-09-20 17:12:32 +12:00
rob bygrave 3574479627 #1821 - Remove serverConfig updateChangesOnly mode ... as always true 2019-09-15 21:29:25 +12:00
rob bygrave cecf2fc650 [maven-release-plugin] prepare for next development iteration 2019-09-12 23:09:28 +12:00
rob bygrave a1dab24414 [maven-release-plugin] prepare release ebean-11.45.1 2019-09-12 23:09:17 +12:00
rob bygrave c12ea28ea9 #1818 - Cannot auto-generate UUID 2019-09-12 22:02:22 +12:00
rob bygrave a2b418df8b #1820 - ENH: For DB Migration add setLockTimeout(10); ... to add Postgres set lock_timeout = to generated migrations 2019-09-12 20:59:52 +12:00
rob bygrave 2fb533a606 #1819 - ENH: For DB Migration support dbMigration.setAddForeignKeySkipCheck(true); 2019-09-12 20:34:37 +12:00
rob bygrave 5d89897bbd #1817 - Rename @DbHstore to @DbMap 2019-09-12 17:02:53 +12:00
rob bygrave 9640e02b6a #1817 - Rename @DbHstore to @DbMap 2019-09-12 16:58:15 +12:00
rob bygrave 8a0ef33f79 git push origin masterMerge branch 'Ryszard-Trojnacki-master' 2019-09-12 14:55:50 +12:00
rob bygrave d2ece76ca8 #1816 Fix for OneToMany relation to non-cached target bean. 2019-09-12 14:55:37 +12:00
rob bygrave 3495d03706 Merge branch 'master' of https://github.com/Ryszard-Trojnacki/avaje-ebeanorm into Ryszard-Trojnacki-master 2019-09-12 13:58:50 +12:00
Rob BygraveandGitHub bc90fa50d7 #1802 - Completely remove MySQL init stored procedures for drop column with foreign key (#1815) 2019-09-12 09:34:14 +12:00
Ryszard Trojnacki 777fc0ff30 Merge branch 'ebean-orm-master' 2019-09-11 14:24:04 +02:00
Ryszard Trojnacki 9413f72939 Merge from origin. 2019-09-11 14:22:47 +02:00
Ryszard Trojnacki 1416647d04 Test case for changing OneToMany collection in a cached bean, by editing target bean that is not cached (annotated with @Cache). 2019-09-11 14:05:31 +02:00
rob bygrave 63bddb4d54 #1810 - Whan paging over query with @Aggregation ( grouping by) wrong total count is calculated 2019-09-11 23:38:12 +12:00
rob bygrave 6fddd418a1 #1811 Fix for Entity with EmbeddedId not found in cache 2019-09-11 22:28:22 +12:00
RienandRob Bygrave faba55d772 Fix EmbeddedId not found cache (#1811) 2019-09-11 22:06:05 +12:00
rob bygrave ac6db11e3d #1802 - Change MySQL DDL to not use helper stored procedures by default - was auto-generated script containing create procedures fails 2019-09-11 22:04:30 +12:00
rob bygrave ca7d8ecfc1 #1814 - Support older MySQL 5.5 2019-09-11 21:38:16 +12:00
rob bygrave 46eeee68c9 #1814 - Support older MySQL 5.5 2019-09-11 21:37:52 +12:00
rob bygrave c1487daea8 #1812 No effective change - Format code only 2019-09-11 15:33:21 +12:00
Ryszard TrojnackiandRob Bygrave b329ae42db Allow for null items in @DbArray lists. (#1812)
* Added code to allow for null items in @DbArray lists.

* Test case for changing OneToMany collection by editing target bean.
2019-09-11 15:30:32 +12:00
Ryszard Trojnacki 13429daddc Test case for changing OneToMany collection by editing target bean. 2019-09-10 20:43:31 +02:00
Ryszard Trojnacki 98a80295fe Added code to allow for null items in @DbArray lists. 2019-09-10 20:07:33 +02:00
Ryszard TrojnackiandGitHub f8587368ee Merge pull request #2 from ebean-orm/master
Update to master
2019-09-10 19:39:27 +02:00
rob bygrave 8ae2ae7f8b [maven-release-plugin] prepare for next development iteration 2019-08-31 00:16:48 +12:00
rob bygrave 46f3b74b38 [maven-release-plugin] prepare release ebean-11.44.1 2019-08-31 00:16:37 +12:00
rob bygrave df51ccd2c4 Bump to 11.44.1-SNAPSHOT 2019-08-31 00:15:03 +12:00
rob bygrave 730d43c008 #1807 - ENH: Add SerializableConflictException 2019-08-30 23:43:00 +12:00
rob bygrave 81c2c804a6 #1806 - SQLException:Data conversion error converting "c5866ffb-2e1c-457e-bdad-61ba4466f86e" [22018-197] Bind values:[1, ] Query was: 2019-08-26 21:12:07 +12:00
rob bygrave 533be356f2 [maven-release-plugin] prepare for next development iteration 2019-08-25 17:02:57 +12:00
rob bygrave 589191f3f4 [maven-release-plugin] prepare release ebean-11.43.3 2019-08-25 17:02:47 +12:00
rob bygrave 0e65efea57 #1804 - Kotlin: Generating collection with wildcard type - Get error BeanNotRegisteredException: Error with association to [null] from [...Foo.manyProperty]. Is null registered? 2019-08-25 15:58:46 +12:00
rob bygrave be66872249 #1800 Adjust to allow for null schema and table names 2019-08-25 11:32:08 +12:00
rob bygrave 85a0354d42 #1800 No effective change, test only, static imports and organise imports 2019-08-25 11:19:07 +12:00
rob bygrave 0b8613fd4c #1800 - Additional test exercising RawSqlBuilder.sqlRow(resultSet, ...); 2019-08-25 11:16:07 +12:00
Manuel DanischandRob Bygrave e734c0010c If the map already contains the column name, add schema and table names before the key to make it unique again (#1800) 2019-08-25 11:09:32 +12:00
rob bygrave e08333ef26 Improve error message when trying to use predicates etc when creating FetchGroup 2019-08-20 22:47:14 +12:00
rob bygrave 4a3eabbd6b [maven-release-plugin] prepare for next development iteration 2019-08-20 22:01:16 +12:00
rob bygrave ae68d41519 [maven-release-plugin] prepare release ebean-11.43.2 2019-08-20 22:01:04 +12:00
rob bygrave 722692d934 reduce logging for testing 2019-08-20 10:29:31 +12:00
rob bygrave 21a3f322e1 #1798 - Fix automatic query label set on nested secondary query when using profileLocation 2019-08-19 23:15:27 +12:00
rob bygrave 0d175557b0 No effective change - update test clearing data 2019-08-19 21:50:17 +12:00
rob bygrave 57ccd19fe6 #1797 - Bump ebean-migration to 11.20.1 ... which inserts a <init> row into db_migration table 2019-08-19 21:37:01 +12:00
rob bygrave 9674711516 #1796 - ENH: add query.fetchCache(path) ... for explicitly building part of graph from L2 cache 2019-08-19 21:36:19 +12:00
rob bygrave 9155716752 #1795 - Refactor bind padding for Id IN expressions (based on internal multiValueSupport and simple id) 2019-08-18 16:33:36 +12:00
rob bygrave d7d8c3e651 Refactor tidy on Load context 2019-08-18 12:17:36 +12:00
rob bygrave 16f6f2ee7f [maven-release-plugin] prepare for next development iteration 2019-08-16 00:00:42 +12:00
rob bygrave fea6dfd62b [maven-release-plugin] prepare release ebean-11.43.1 2019-08-16 00:00:31 +12:00
rob bygrave 464ed4322e #1794 - Also support "inRange" camelcase version of "inrange" in EQL 2019-08-15 23:58:58 +12:00
rob bygrave c3f556f0dc #1794 - Extend EQL to support inOrEmpty, eqOrNull, gtOrNull, ltOrNull 2019-08-15 23:40:19 +12:00
rob bygrave ba6810891e Bump to 11.43.1-SNAPSHOT 2019-08-15 22:20:09 +12:00
rob bygrave c530883e5e #1793 - ENH: Add filterMany() that takes expressions ... as a simpler option 2019-08-15 22:05:46 +12:00
rob bygrave 06542b031e Initial refactor to extract EqlWhereListener 2019-08-15 20:21:01 +12:00
rob bygrave 4b5365e708 #1792 - ENH: Support using Query beans for building FetchGroup (in a type safe manor) 2019-08-14 22:52:18 +12:00
Rob BygraveandGitHub 1d471fee92 #1768 - Initial refactor extracting CallOrigin interface (#1791) 2019-08-14 17:02:57 +12:00
rob bygrave 3825dea00a [maven-release-plugin] prepare for next development iteration 2019-08-12 21:12:45 +12:00
rob bygrave 3fd130ac4c [maven-release-plugin] prepare release ebean-11.42.3 2019-08-12 21:12:34 +12:00
rob bygrave 196645e7a2 #1789 - Add default constructor to EntityBeanIntercept for serialisation framework use only 2019-08-12 21:09:31 +12:00
rob bygrave f5459920e9 #1785 - Bean gets replaced on json deserialization with primitive 'null' id 2019-08-12 21:05:32 +12:00
rob bygrave ee6452cfb0 #1788 - ENH: Add support for NuoDB database platform 2019-08-12 20:41:45 +12:00
rob bygrave ad7e18561b #1788 - ENH: Add support for NuoDB database platform
Remove the extra truncate
2019-08-11 16:43:24 +12:00
rob bygrave c640524bfc #1788 - ENH: Add support for NuoDB database platform 2019-08-11 16:24:37 +12:00
rob bygrave fea840c859 #1782 - ENH: Add truncate(Class<?>... types) and truncate(String... tables)
Remove truncateTableBefore and truncateTableAfter for now
2019-08-10 21:44:48 +12:00
rob bygrave bb7df71391 #1782 - ENH: Add truncate(Class<?>... types) and truncate(String... tables) 2019-08-10 21:40:23 +12:00
rob bygrave cb6f0335b1 #1787 - Update CockroachDB support for DDL generation with autocommit and no history support 2019-08-08 23:22:58 +12:00
rob bygrave 762899ef10 [maven-release-plugin] prepare for next development iteration 2019-08-07 22:43:12 +12:00
rob bygrave 848d4f031e [maven-release-plugin] prepare release ebean-11.42.2 2019-08-07 22:42:59 +12:00
rob bygrave 481f828507 Bump provided scope jackson-databind version to 2.9.9.2 for security warning
This should have no effect as the dependency is scope provided.
2019-08-07 22:40:57 +12:00
rob bygrave b3d0c21a80 #1783 - Save bean with only *ToMany relations with user generated ID 2019-08-07 22:28:51 +12:00
rob bygrave a115cdf095 #1784 - Tests related to NPE with IDEA plugin and mockito 3.0.0 2019-08-07 21:38:52 +12:00
rob bygrave 410e9d475b [maven-release-plugin] prepare for next development iteration 2019-07-31 23:27:53 +12:00
rob bygrave 462385c7d0 [maven-release-plugin] prepare release ebean-11.42.1 2019-07-31 23:27:42 +12:00
rob bygrave 3655e2c6f8 #1778 - Bump jackson-core.version from 2.9.8 to 2.9.9 2019-07-31 23:25:30 +12:00
rob bygrave 318f6ae3f5 Bump to 11.42.1-SNAPSHOT 2019-07-31 23:21:01 +12:00
rob bygrave c63acad7e0 No effective change - updated review ddl 2019-07-29 23:45:20 +12:00
rob bygrave 6dba4a3d28 #1763 - Change such that db-create-all.sql and db-drop-all.sql generated files go into target (maven) or build (gradle) directories 2019-07-29 23:26:45 +12:00
rob bygrave ecf1e53616 [maven-release-plugin] prepare for next development iteration 2019-07-29 22:49:48 +12:00
rob bygrave 0ff9a00427 [maven-release-plugin] prepare release ebean-11.41.4 2019-07-29 22:49:36 +12:00
rob bygrave 725ff8dc58 git push origin masterMerge branch 'FOCONIS-bug-refresh-one-to-many' 2019-07-29 22:46:55 +12:00
rob bygrave a780dc133e #1776 Fix for - refresh does not work on oneToMany if property was not yet accessed 2019-07-29 22:46:39 +12:00
Roland Praml b111fcfecc refresh does not work on oneToMany if property was not yet accessed
(cherry picked from commit 446103e6e06d7583f8b2bb847907d7fc77a8be9f)
2019-07-26 12:14:30 +02:00
rob bygrave 114693b7cd #1774 - Change built in SQL Server I___create_procs DDL script to use GO (and not $$ delimiters)
Bump ebean-migration with handling for stored procedures delimited with GO and $$ etc
2019-07-25 21:46:35 +12:00
rob bygrave 5a39dcb39c #1775 - MySql 8 by default wants JDBC Date set and read with JVM Calendar (timezone) 2019-07-25 21:25:38 +12:00
rob bygrave b04f887bc3 Test only update generated resource - no effective change 2019-07-25 21:19:08 +12:00
rob bygrave 5c38561049 #1774 - Change built in SQL Server I___create_procs DDL script to use GO (and not $$ delimiters) 2019-07-24 23:36:36 +12:00
rob bygrave f40eb011c3 #1773 - Wrong link to timerbee.de in README.md 2019-07-24 21:57:47 +12:00
rob bygrave a08cf548e7 #1770 - Support use of Savepoints with MySql and MariaDB (that barf on savepoint.getSavepointId()) 2019-07-21 22:57:56 +12:00
rob bygrave f12f0d7f7a [maven-release-plugin] prepare for next development iteration 2019-07-21 16:50:02 +12:00
rob bygrave 0c53efcbbc [maven-release-plugin] prepare release ebean-11.41.3 2019-07-21 16:49:51 +12:00
rob bygrave 1aeed8ad12 Merge branch 'master' of github.com:ebean-orm/ebean 2019-07-19 10:44:07 +12:00
rob bygrave bcb136b692 #1765 - Wrong SQL generated on m2m and OrderBy (Regression of #1746) 2019-07-19 10:43:07 +12:00
rob bygrave 8b670fd615 Fix tests for sql server which doesn't support order by nulls last 2019-07-19 10:35:26 +12:00
rob bygrave 970bc8e973 Fix tests for sql server 2019-07-19 10:28:13 +12:00
Roland PramlandRob Bygrave 007b06e9db use local lookup instead of public lookup (#1764)
(cherry picked from commit dc0441aaea126efc23a9c2abc30a4dd67bac6752)
2019-07-19 09:12:07 +12:00
rob bygrave 4513dbf29d No effective change - whitespace change only to SqlTreeBuilder 2019-07-19 00:22:41 +12:00
rob bygrave 53bcc62a0c No effective change - whitespace change to test generated migration ddl 2019-07-19 00:21:04 +12:00
rob bygrave 858c55c978 No effective change - format only test code 2019-07-19 00:20:22 +12:00
rob bygrave cedba089e1 Merge branch 'cannot-access-referenced-prop' of https://github.com/FOCONIS/ebean into FOCONIS-cannot-access-referenced-prop 2019-07-18 23:48:47 +12:00
rob bygrave cbf7811f7c #1762 - Bump ebean-migration to 11.17.1 2019-07-18 23:37:25 +12:00
rob bygrave ea13b322ca Bump agent to 11.41.3 2019-07-18 23:34:28 +12:00
Alexander Wagner 486a8cf1c0 whitespaces 2019-07-18 12:15:44 +02:00
Alexander Wagner bfe46432da delete views from ddl 2019-07-18 12:14:38 +02:00
Alexander Wagner 272eae5f22 Do not use @View for Test 2019-07-18 11:19:43 +02:00
rob bygrave 502104eba8 [maven-release-plugin] prepare for next development iteration 2019-07-17 21:53:14 +12:00
rob bygrave fa45c79bd2 [maven-release-plugin] prepare release ebean-11.41.2 2019-07-17 21:53:01 +12:00
rob bygrave ee4d1bf866 #1760 #1759 - move make available via ebean-test-config 2019-07-17 15:48:11 +12:00
rob bygrave dcf7b60d37 #1760 #1759 - ENH: Add ForTests.rollbackAll(closure) and ForTests.createRollbackAll() 2019-07-17 14:44:52 +12:00
rob bygrave 0663a97941 No effective change - update test for TestTransientMap 2019-07-17 13:48:12 +12:00
rob bygrave f31ab4d6a8 #1758 - Error when using ebean 11.41.1 and ebean-spring-txn 11.10.4
Fix method visibility restoring those methods as public
2019-07-17 10:27:07 +12:00
André CamiloandRob Bygrave f77388738b ENH: backdoor to disable @Transactional during unit testing (#1756) 2019-07-16 23:09:04 +12:00
Roland PramlandRob Bygrave 945175c533 Throwing NotEnhancedException on _ebean_* method instead of enforce to implement them (#1755) 2019-07-16 23:07:40 +12:00
rob bygrave 7d37c6cfd8 #1753 - use selectId() for findCount() with Formula properties 2019-07-15 19:04:43 +12:00
rob bygrave 496672b394 #1753 - Tidy for Issue with using the Formula-Properties 2019-07-14 16:03:07 +12:00
rob bygrave 1ffe359573 Merge branch 'Tests-for-Queries-With-Formula-Properties' of https://github.com/FOCONIS/ebean into FOCONIS-Tests-for-Queries-With-Formula-Properties 2019-07-14 15:23:16 +12:00
rob bygrave 23cd9b6a93 Remove use of agent-loader
Enhancement always done via maven plugin or Ebean IDE plugin (javaagent)
2019-07-14 15:21:55 +12:00
rob bygrave 333ac8edd9 Bump agent to 11.41.2 2019-07-14 15:17:34 +12:00
Roland Praml 081cb20260 always add main ID property, if no foreign key (=noConstraint) is present
(cherry picked from commit ea562151a8e3043df13381abd0d076d592618340)
2019-07-12 14:23:50 +02:00
Roland Praml 53f1da32be Add testcase for @DbForeignKey(noconstraint = true) 2019-07-12 14:21:45 +02:00
Roland Praml 5544a2cc3e Possible fix 2019-07-12 12:59:19 +02:00
Thomas Fellner 84c3008db1 Add query tests for @Formula-Properties 2019-07-09 17:35:27 +02:00
rob bygrave d949d4d6a2 [maven-release-plugin] prepare for next development iteration 2019-07-03 00:12:09 +12:00
878 changed files with 27088 additions and 7952 deletions
+1 -2
View File
@@ -21,7 +21,7 @@
</a>
</td>
<td align="center" valign="middle">
<a href="https://timerbe.de" target="_blank">
<a href="https://timerbee.de" target="_blank">
<img width="222px" src="https://ebean.io/images/logo-timerbee.png">
</a>
</td>
@@ -44,4 +44,3 @@ Goto [https://ebean.io/docs/](https://ebean.io/docs/)
## Other versions
* [![Maven Central : ebean-agent](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-agent/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-agent) - ebean-agent
* [![Maven Central : ebean-maven-plugin](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-maven-plugin/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-maven-plugin) - ebean-maven-plugin
+43 -91
View File
@@ -3,56 +3,30 @@
<parent>
<groupId>org.avaje</groupId>
<artifactId>java8-parent</artifactId>
<version>1.3</version>
<artifactId>java8-oss</artifactId>
<version>2.1</version>
</parent>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>11.41.1</version>
<version>12.1.13</version>
<packaging>jar</packaging>
<name>ebean</name>
<url>http://ebean-orm.github.io/</url>
<properties>
<jackson-core.version>2.9.8</jackson-core.version>
<jackson-core.version>2.10.0</jackson-core.version>
<jackson-databind.version>2.10.0</jackson-databind.version>
<snakeyaml.version>1.21</snakeyaml.version>
</properties>
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-11.41.1</tag>
<tag>ebean-12.1.13</tag>
</scm>
<profiles>
<profile>
<!-- Note: to use this profile, you need credentials for the oracle repository in your
settings.xml as described here:
http://docs.oracle.com/middleware/1213/core/MAVEN/config_maven_repo.htm#MAVEN9010 -->
<id>oracle</id>
<dependencies>
<dependency>
<groupId>com.oracle.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>12.2.0.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>maven.oracle.com</id>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
<url>https://maven.oracle.com</url>
<layout>default</layout>
</repository>
</repositories>
</profile>
<profile>
<!-- Note: to use this profile, you need to download manually the db2jcc4 driver.
After that, install it into your local maven repository:
@@ -117,31 +91,25 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-annotation</artifactId>
<version>4.11</version>
<version>6.4</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-types</artifactId>
<version>1.3</version>
<version>2.1</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.avaje</groupId>
<artifactId>avaje-classpath-scanner</artifactId>
<version>3.1.1</version>
<version>4.7.3</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>11.16.2</version>
<version>12.1.4</version>
</dependency>
<dependency>
@@ -161,7 +129,7 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-core.version}</version>
<version>${jackson-databind.version}</version>
<scope>provided</scope>
</dependency>
@@ -198,7 +166,7 @@
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.4.0-b180830.0438</version>
<version>2.3.2</version>
<scope>provided</scope>
</dependency>
@@ -219,17 +187,24 @@
<!-- Test scope -->
<!--<dependency>-->
<!--<groupId>oracle</groupId>-->
<!--<artifactId>oracle-jdbc</artifactId>-->
<!--<version>7.0</version>-->
<!--<scope>test</scope>-->
<!--</dependency>-->
<dependency>
<groupId>com.nuodb.jdbc</groupId>
<artifactId>nuodb-jdbc</artifactId>
<version>20.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.oracle.ojdbc</groupId>
<artifactId>ojdbc10</artifactId>
<version>19.3.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean.test</groupId>
<artifactId>ebean-test-docker</artifactId>
<version>2.5.1</version>
<version>3.1.2</version>
<scope>test</scope>
</dependency>
@@ -240,20 +215,6 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.avaje</groupId>
<artifactId>avaje-agentloader</artifactId>
<version>3.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-agent</artifactId>
<version>11.41.1</version>
<scope>test</scope>
</dependency>
<!-- Provided scope so that the H2HistoryTrigger can live in Ebean core
and not require a separate module for it -->
<dependency>
@@ -287,8 +248,7 @@
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!-- Do not upgrade to 6.0.6: https://bugs.mysql.com/bug.php?id=82896 -->
<version>5.1.43</version>
<version>8.0.17</version>
<scope>test</scope>
</dependency>
@@ -299,12 +259,18 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.avaje.composite</groupId>
<artifactId>avaje-composite-testing</artifactId>
<artifactId>junit</artifactId>
<version>1.1</version>
<scope>test</scope>
<type>pom</type>
</dependency>
<dependency>
@@ -315,9 +281,9 @@
</dependency>
<dependency>
<groupId>org.avaje.moduuid</groupId>
<artifactId>avaje-moduuid</artifactId>
<version>2.1</version>
<groupId>io.avaje</groupId>
<artifactId>mod-uuid</artifactId>
<version>1.1</version>
<scope>test</scope>
</dependency>
@@ -330,13 +296,13 @@
<plugin>
<groupId>io.ebean</groupId>
<artifactId>ebean-maven-plugin</artifactId>
<version>11.41.1</version>
<version>12.1.12</version>
<executions>
<execution>
<id>test</id>
<phase>process-test-classes</phase>
<configuration>
<transformArgs>debug=1</transformArgs>
<transformArgs>debug=0</transformArgs>
</configuration>
<goals>
<goal>testEnhance</goal>
@@ -387,25 +353,11 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<version>3.1.1</version>
<configuration>
<doctitle>Ebean 11</doctitle>
<doctitle>Ebean 12</doctitle>
<overview>src/main/java/io/ebean/overview.html</overview>
<source>1.8</source>
<doclet>org.avaje.doclet.PygmentsDoclet</doclet>
<excludePackageNames>io.ebeaninternal.*:io.ebeanservice:io.ebean.common:io.ebean.bean:io.ebean.service:io.ebean.metric:io.ebean.util:io.ebean.config.properties:io.ebean.config.dbplatform*</excludePackageNames>
<docletArtifact>
<groupId>org.avaje</groupId>
<artifactId>pygments-doclet</artifactId>
<version>1.0.0</version>
</docletArtifact>
<additionalparam>
-Xdoclint:none
-include-basedir ${project.basedir}
-attributes "idseparator=-; project_name=${project.name}; \
project_version=${project.version}; \
project_desc=${project.description}"
</additionalparam>
<excludePackageNames>io.ebeaninternal.*:io.ebeanservice:io.ebean.common:io.ebean.bean:io.ebean.service:io.ebean.metric:io.ebean.util:io.ebean.config.properties:io.ebean.config.dbplatform</excludePackageNames>
<linksource>true</linksource>
<overview>src/main/java/com/avaje/ebean/overview.html</overview>
</configuration>
+49 -16
View File
@@ -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;
@@ -87,14 +86,14 @@ public class DB {
// /**
// * Register the server with this Ebean singleton. Specify if the registered
// * server is the primary/default server.
// * server is the primary/default database.
// */
// public static void register(EbeanServer server, boolean defaultServer) {
// serverMgr.register(server, defaultServer);
// }
//
// /**
// * Backdoor for registering a mock implementation of EbeanServer as the default server.
// * Backdoor for registering a mock implementation of EbeanServer as the default database.
// */
// protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
// EbeanServer originalPrimaryServer = serverMgr.defaultServer;
@@ -177,6 +176,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.
*
@@ -396,15 +407,6 @@ public class DB {
* called then no optimistic locking is performed (internally ConcurrencyMode.NONE is used).
* </p>
* <p>
* <b>{@link DatabaseConfig#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 DatabaseConfig#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
@@ -414,9 +416,6 @@ public class DB {
* database.update(customer);
*
* }</pre>
*
* @see DatabaseConfig#setUpdatesDeleteMissingChildren(boolean)
* @see DatabaseConfig#setUpdateChangesOnly(boolean)
*/
public static void update(Object bean) throws OptimisticLockException {
getDefault().update(bean);
@@ -455,6 +454,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
@@ -663,7 +669,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
@@ -749,8 +755,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);
}
@@ -773,8 +782,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);
}
@@ -1215,6 +1227,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).
*/
@@ -1237,4 +1256,18 @@ public class DB {
return getDefault().json();
}
/**
* Truncate the base tables for the given bean types.
*/
public static void truncate(Class<?>... types) {
getDefault().truncate(types);
}
/**
* Truncate the given tables.
*/
public static void truncate(String... tables) {
getDefault().truncate(tables);
}
}
+27 -31
View File
@@ -3,7 +3,6 @@ package io.ebean;
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;
@@ -123,7 +122,7 @@ public interface Database {
String getName();
/**
* Return the ExpressionFactory for this server.
* Return the ExpressionFactory for this database.
*/
ExpressionFactory getExpressionFactory();
@@ -376,7 +375,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 +464,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 +487,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 +861,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 +881,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 +1061,6 @@ public interface Database {
* Integer returnValue = (Integer) cs.getObject(3);
*
* }</pre>
*
*/
int execute(CallableSql callableSql);
@@ -1196,17 +1205,6 @@ public interface Database {
* <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>
* <p>
* <pre>{@code
*
* // A 'stateless update' example
@@ -1216,9 +1214,6 @@ public interface Database {
* database.update(customer);
*
* }</pre>
*
* @see ServerConfig#setUpdatesDeleteMissingChildren(boolean)
* @see ServerConfig#setUpdateChangesOnly(boolean)
*/
void update(Object bean) throws OptimisticLockException;
@@ -1227,16 +1222,6 @@ public interface Database {
*/
void update(Object bean, Transaction transaction) throws OptimisticLockException;
/**
* Update a bean additionally specifying a transaction and the deleteMissingChildren setting.
*
* @param bean the bean to update
* @param transaction the transaction to use (can be null).
* @param deleteMissingChildren specify false if you do not want 'missing children' of a OneToMany
* or ManyToMany to be automatically deleted.
*/
void update(Object bean, Transaction transaction, boolean deleteMissingChildren) throws OptimisticLockException;
/**
* Update a collection of beans. If there is no current transaction one is created and used to
* update all the beans in the collection.
@@ -1323,7 +1308,7 @@ public interface Database {
* public void run() {
* User u1 = database.find(User.class, 1);
* ...
* }
* }
* });
*
* }</pre>
@@ -1372,7 +1357,7 @@ public interface Database {
* User u1 = database.find(User.class, 1);
* ...
* return u1.getEmail();
* }
* }
* });
*
* }</pre>
@@ -1580,4 +1565,15 @@ public interface Database {
* </p>
*/
<T> Set<String> validateQuery(Query<T> query);
/**
* Truncate all the given tables.
*/
void truncate(String... tables);
/**
* Truncate the base tables for the given bean types.
*/
void truncate(Class<?>... tables);
}
+2 -2
View File
@@ -34,14 +34,14 @@ public class DatabaseFactory {
}
/**
* Create using ebean.properties to configure the server.
* Create using ebean.properties to configure the database.
*/
public static synchronized Database create(String name) {
return EbeanServerFactory.create(name);
}
/**
* Create using the ServerConfig object to configure the server.
* Create using the ServerConfig object to configure the database.
*/
public static synchronized Database create(DatabaseConfig config) {
return EbeanServerFactory.create(config);
+8 -8
View File
@@ -61,7 +61,7 @@ public interface DocumentStore {
* <pre>{@code
*
* Customer customer =
* server.find(Customer.class)
* database.find(Customer.class)
* .setUseDocStore(true)
* .setId(42)
* .findOne();
@@ -79,7 +79,7 @@ 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();
@@ -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)
@@ -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) -> {
@@ -145,7 +145,7 @@ public interface DocumentStore {
* </p>
* <pre>{@code
*
* server.find(Order.class)
* database.find(Order.class)
* .setUseDocStore(true)
* .where()... // perhaps add predicates
* .findEachWhile(new Predicate<Order>() {
@@ -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")
+23 -2
View File
@@ -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);
}
+18 -15
View File
@@ -24,6 +24,8 @@ import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
/**
* Ebean will be Deprecated - please migrate to use DB.
* <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.
@@ -80,7 +82,7 @@ public final class Ebean {
} 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." +
" 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);
@@ -185,7 +187,7 @@ public final class Ebean {
}
/**
* Return the ExpressionFactory from the default server.
* 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
@@ -207,14 +209,14 @@ public final class Ebean {
/**
* Register the server with this Ebean singleton. Specify if the registered
* server is the primary/default server.
* server is the primary/default database.
*/
public static void register(EbeanServer server, boolean defaultServer) {
serverMgr.register(server, defaultServer);
}
/**
* Backdoor for registering a mock implementation of EbeanServer as the default server.
* Backdoor for registering a mock implementation of EbeanServer as the default database.
*/
protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
EbeanServer originalPrimaryServer = serverMgr.defaultServer;
@@ -462,7 +464,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;
* ...
* }
@@ -548,9 +550,6 @@ public final class Ebean {
* DB.update(customer);
*
* }</pre>
*
* @see ServerConfig#setUpdatesDeleteMissingChildren(boolean)
* @see ServerConfig#setUpdateChangesOnly(boolean)
*/
public static void update(Object bean) throws OptimisticLockException {
serverMgr.getDefaultServer().update(bean);
@@ -797,7 +796,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
@@ -868,6 +867,8 @@ public final class Ebean {
}
/**
* Deprecated - migrate to DB.sqlQuery().
* <p>
* Create a SqlQuery for executing native sql
* query statements.
* <p>
@@ -875,22 +876,24 @@ public final class Ebean {
* annotation for examples.
* </p>
*/
@Deprecated
public static SqlQuery createSqlQuery(String sql) {
return serverMgr.getDefaultServer().createSqlQuery(sql);
return serverMgr.getDefaultServer().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 serverMgr.getDefaultServer().sqlUpdate(sql);
}
/**
@@ -1196,7 +1199,7 @@ public final class Ebean {
* public void run() {
* User u1 = Ebean.find(User.class, 1);
* ...
* }
* }
* });
*
* }</pre>
@@ -1248,7 +1251,7 @@ public final class Ebean {
* User u1 = Ebean.find(User.class, 1);
* ...
* return u1.getEmail();
* }
* }
* });
*
* }</pre>
@@ -48,7 +48,7 @@ public class EbeanServerFactory {
}
/**
* Create using ebean.properties to configure the server.
* Create using ebean.properties to configure the database.
*/
public static synchronized EbeanServer create(String name) {
@@ -59,7 +59,7 @@ public class EbeanServerFactory {
}
/**
* Create using the ServerConfig object to configure the server.
* Create using the ServerConfig object to configure the database.
*/
public static synchronized EbeanServer create(ServerConfig config) {
+1 -1
View File
@@ -21,7 +21,7 @@ public class EbeanVersion {
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();
@@ -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 "";
}
}
+39 -39
View File
@@ -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,7 +49,7 @@ 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);
}
/**
@@ -59,28 +59,28 @@ public class Expr {
* </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);
}
}
@@ -536,4 +536,12 @@ public interface ExpressionFactory {
*/
<T> Junction<T> junction(Junction.Type type, Query<T> query, ExpressionList<T> parent);
/**
* Add the expressions to the given expression list.
*
* @param where The expression list to add the expressions to
* @param expressions The expressions that are parsed
* @param params Bind parameters to match ? or ?1 bind positions.
*/
<T> void where(ExpressionList<T> where, String expressions, Object[] params);
}
+54 -29
View File
@@ -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,10 +67,6 @@ 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);
@@ -77,27 +81,21 @@ public interface ExpressionList<T> {
OrderBy<T> order();
/**
* Return the OrderBy so that you can append an ascending or descending
* property to the order by clause.
* <p>
* This will never return a null. If no order by clause exists then an 'empty'
* OrderBy object is returned.
* </p>
* Deprecated migrate to order().
*/
@Deprecated
OrderBy<T> orderBy();
/**
* Add an orderBy clause to the query.
*
* @see Query#orderBy(String)
* Deprecated migrate to {@link #order(String)}
*/
@Deprecated
Query<T> orderBy(String orderBy);
/**
* Add an orderBy clause to the query.
*
* @see Query#orderBy(String)
* Deprecated migrate to {@link #order(String)}
*/
@Deprecated
Query<T> setOrderBy(String orderBy);
/**
@@ -334,7 +332,7 @@ public interface ExpressionList<T> {
* List<String> names =
* DB.find(Customer.class)
* .select("name")
* .orderBy().asc("name")
* .order().asc("name")
* .findSingleAttributeList();
*
* }</pre>
@@ -347,7 +345,7 @@ public interface ExpressionList<T> {
* .setDistinct(true)
* .select("name")
* .where().eq("status", Customer.Status.NEW)
* .orderBy().asc("name")
* .order().asc("name")
* .setMaxRows(100)
* .findSingleAttributeList();
*
@@ -489,7 +487,26 @@ public interface ExpressionList<T> {
* Add some filter predicate expressions to the many property.
*/
@Nonnull
ExpressionList<T> filterMany(String prop);
ExpressionList<T> filterMany(String manyProperty);
/**
* Add filter expressions to the many property.
*
* <pre>{@code
*
* DB.find(Customer.class)
* .where()
* .eq("name", "Rob")
* .filterMany("orders", "status = ?", Status.NEW)
* .findList();
*
* }</pre>
*
* @param manyProperty The many property
* @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);
/**
* Specify specific properties to fetch on the main/root bean (aka partial
@@ -663,6 +680,14 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> where();
/**
* Add the expressions to this expression list.
*
* @param expressions The expressions that are parsed and added to this expression list
* @param params Bind parameters to match ? or ?1 bind positions.
*/
ExpressionList<T> where(String expressions, Object... params);
/**
* Path exists - for the given path in a JSON document.
* <pre>{@code
@@ -831,9 +856,9 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> inRange(String propertyName, Object value1, Object value2);
/**
* Between - property between the two given values.
*/
/**
* Between - property between the two given values.
*/
ExpressionList<T> between(String propertyName, Object value1, Object value2);
/**
@@ -1327,7 +1352,7 @@ public interface ExpressionList<T> {
*
* }</pre>
* <p>
* Note that we need to cast the Postgres array for UUID types like:
* Note that we need to cast the Postgres array for UUID types like:
* </p>
* <pre>{@code
*
@@ -1335,7 +1360,7 @@ public interface ExpressionList<T> {
*
* }</pre>
*
* @param raw The raw expression that is typically a subquery
* @param raw The raw expression that is typically a subquery
* @param values The values which is typically a list or set of id values.
*/
ExpressionList<T> rawOrEmpty(String raw, Collection<?> values);
@@ -1424,7 +1449,7 @@ public interface ExpressionList<T> {
* .eq("status", Customer.Status.ACTIVE)
* .gt("id", 0)
* .endAnd()
* .orderBy().asc("name")
* .order().asc("name")
* .findList();
* }</pre>
*/
@@ -1445,7 +1470,7 @@ public interface ExpressionList<T> {
* .or()
* .eq("status", Customer.Status.ACTIVE)
* .isNull("anniversary")
* .orderBy().asc("name")
* .order().asc("name")
* .findList();
*
* }</pre>
@@ -1465,7 +1490,7 @@ public interface ExpressionList<T> {
* .eq("status", Customer.Status.ACTIVE)
* .gt("id", 0)
* .endAnd()
* .orderBy().asc("name")
* .order().asc("name")
* .findList();
*
* }</pre>
@@ -1499,7 +1524,7 @@ public interface ExpressionList<T> {
* .gt("id", 1)
* .eq("anniversary", onAfter)
* .endNot()
* .orderBy()
* .order()
* .asc("name")
* .findList();
*
+22 -6
View File
@@ -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;
@@ -13,6 +10,7 @@ import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* The extended API for Database.
@@ -69,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.
@@ -107,6 +105,24 @@ public interface ExtendedServer {
@Nonnull
<T> QueryIterator<T> findIterate(Query<T> query, Transaction transaction);
/**
* Return the query result as a Stream using a single persistence context.
* <p>
* Note that the stream needs to be closed so use with try with resources.
* </p>
*/
@Nonnull
<T> Stream<T> findStream(Query<T> query, Transaction transaction);
/**
* Return the query result as a Stream (with multiple persistence contexts).
* <p>
* Note that the stream needs to be closed so use with try with resources.
* </p>
*/
@Nonnull
<T> Stream<T> findLargeStream(Query<T> query, Transaction transaction);
/**
* Execute the query visiting the each bean one at a time.
* <p>
@@ -341,7 +357,7 @@ public interface ExtendedServer {
* List<String> names =
* DB.find(Customer.class)
* .select("name")
* .orderBy().asc("name")
* .order().asc("name")
* .findSingleAttributeList();
*
* }</pre>
@@ -353,7 +369,7 @@ public interface ExtendedServer {
* .setDistinct(true)
* .select("name")
* .where().eq("status", Customer.Status.NEW)
* .orderBy().asc("name")
* .order().asc("name")
* .setMaxRows(100)
* .findSingleAttributeList();
*
+22
View File
@@ -148,6 +148,8 @@ public class FetchConfig implements Serializable {
private boolean queryAll;
private boolean cache;
/**
* Construct the fetch configuration object.
*/
@@ -188,6 +190,17 @@ public class FetchConfig implements Serializable {
return this;
}
/**
* Eagerly fetch the beans fetching the beans from the L2 bean cache
* and using the DB for beans not in the cache.
*/
public FetchConfig cache() {
this.cache = true;
this.queryBatchSize = 0;
this.queryAll = true;
return this;
}
/**
* Eagerly fetch the beans in this path as a separate query (rather than as
* part of the main query).
@@ -247,6 +260,13 @@ public class FetchConfig implements Serializable {
return queryAll;
}
/**
* Return true if this uses L2 bean cache.
*/
public boolean isCache() {
return cache;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -255,6 +275,7 @@ public class FetchConfig implements Serializable {
FetchConfig that = (FetchConfig) o;
if (lazyBatchSize != that.lazyBatchSize) return false;
if (queryBatchSize != that.queryBatchSize) return false;
if (cache != that.cache) return false;
return queryAll == that.queryAll;
}
@@ -263,6 +284,7 @@ public class FetchConfig implements Serializable {
int result = lazyBatchSize;
result = 92821 * result + queryBatchSize;
result = 92821 * result + (queryAll ? 1 : 0);
result = 92821 * result + (cache ? 1 : 0);
return result;
}
}
+9
View File
@@ -1,5 +1,7 @@
package io.ebean;
import io.ebean.service.SpiFetchGroupQuery;
import javax.annotation.Nonnull;
/**
@@ -111,4 +113,11 @@ public interface FetchGroup<T> {
return XServiceProvider.fetchGroupOf(cls);
}
/**
* Return a query to be used by query beans for constructing FetchGroup.
*/
static <T> SpiFetchGroupQuery<T> queryFor(Class<T> beanType) {
return XServiceProvider.fetchGroupQueryFor(beanType);
}
}
@@ -67,12 +67,26 @@ public interface FetchGroupBuilder<T> {
@Nonnull
FetchGroupBuilder<T> fetchQuery(String path);
/**
* Fetch the path including all its properties using L2 cache.
* Cache misses fallback to fetchQuery().
*/
@Nonnull
FetchGroupBuilder<T> fetchCache(String path);
/**
* Fetch the path including specified properties using a query join.
*/
@Nonnull
FetchGroupBuilder<T> fetchQuery(String path, String properties);
/**
* Fetch the path including specified properties using L2 cache.
* Cache misses fallback to fetchQuery().
*/
@Nonnull
FetchGroupBuilder<T> fetchCache(String path, String properties);
/**
* Fetch the path including all its properties lazily.
*/
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -32,7 +32,7 @@ import java.util.List;
* public List<Customer> findNew() {
* return query().where()
* .eq("status", Customer.Status.NEW)
* .orderBy("name")
* .order("name")
* .findList()
* }
* }
+35
View File
@@ -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 -1
View File
@@ -412,7 +412,7 @@ public final class OrderBy<T> implements Serializable {
* Support use in select clause if no collation or nulls ordering.
*/
boolean supportsSelect() {
return nulls == null && collation == null;
return nulls == null;
}
}
+7
View File
@@ -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
+1 -1
View File
@@ -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
+5 -5
View File
@@ -5,9 +5,9 @@ import io.ebean.config.properties.PropertiesLoader;
import java.util.Properties;
/**
* Provides singleton state for the default server.
* Provides singleton state for the default database.
* <p/>
* Intended for internal use as part of bootup, construction, registration of the default server.
* Intended for internal use as part of bootup, construction, registration of the default database.
*/
class PrimaryServer {
@@ -18,21 +18,21 @@ class PrimaryServer {
private static boolean skip;
/**
* Set whether to skip automatically creating the primary server.
* Set whether to skip automatically creating the primary database.
*/
static synchronized void setSkip(boolean skip) {
PrimaryServer.skip = skip;
}
/**
* Return true to skip automatically creating the primary server.
* Return true to skip automatically creating the primary database.
*/
static synchronized boolean isSkip() {
return skip;
}
/**
* Return the default server name.
* Return the default database name.
*/
static synchronized String getDefaultServerName() {
getProperties();
+18 -3
View File
@@ -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);
}
+95 -48
View File
@@ -11,6 +11,7 @@ import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* Object relational query for finding a List, Set, Map or single entity bean.
@@ -24,7 +25,7 @@ import java.util.function.Predicate;
* .where()
* .like("customer.name","rob%")
* .gt("orderDate",lastWeek)
* .orderBy("customer.id, id desc")
* .order("customer.id, id desc")
* .setMaxRows(50)
* .findList();
*
@@ -501,6 +502,14 @@ public interface Query<T> {
*/
Query<T> fetchQuery(String path, String fetchProperties);
/**
* Fetch the path and properties using L2 bean cache.
*
* @param path The path of the beans we are fetching from L2 cache.
* @param fetchProperties The properties that should be loaded.
*/
Query<T> fetchCache(String path, String fetchProperties);
/**
* Fetch the path and properties lazily (via batch lazy loading).
* <p>
@@ -587,6 +596,11 @@ public interface Query<T> {
*/
Query<T> fetchQuery(String path);
/**
* Fetch the path eagerly using L2 cache.
*/
Query<T> fetchCache(String path);
/**
* Fetch the path lazily (via batch lazy loading).
* <p>
@@ -642,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>
@@ -689,6 +708,49 @@ public interface Query<T> {
@Nonnull
QueryIterator<T> findIterate();
/**
* 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.
* </p>
* <pre>{@code
*
* // use try with resources to ensure Stream is closed
*
* try (Stream<Customer> stream = query.findStream()) {
* stream
* .map(...)
* .collect(...);
* }
*
* }</pre>
*/
@Nonnull
Stream<T> findStream();
/**
* Execute the query returning the result as a Stream.
* <p>
* Note that this uses multiple persistence contexts such that we can use
* it with a large number of results.
* </p>
* <pre>{@code
*
* // use try with resources to ensure Stream is closed
*
* try (Stream<Customer> stream = query.findLargeStream()) {
* stream
* .map(...)
* .collect(...);
* }
*
* }</pre>
*/
@Nonnull
Stream<T> findLargeStream();
/**
* Execute the query processing the beans one at a time.
* <p>
@@ -828,7 +890,7 @@ public interface Query<T> {
* List<String> names =
* DB.find(Customer.class)
* .select("name")
* .orderBy().asc("name")
* .order().asc("name")
* .findSingleAttributeList();
*
* }</pre>
@@ -841,7 +903,7 @@ public interface Query<T> {
* .setDistinct(true)
* .select("name")
* .where().eq("status", Customer.Status.NEW)
* .orderBy().asc("name")
* .order().asc("name")
* .setMaxRows(100)
* .findSingleAttributeList();
*
@@ -1126,6 +1188,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>
@@ -1266,17 +1352,9 @@ public interface Query<T> {
Query<T> having(Expression addExpressionToHaving);
/**
* 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.
* </p>
* <p>
* This is EXACTLY the same as {@link #order(String)}.
* </p>
* Deprecated migrate to {@link #order(String)}
*/
@Deprecated
Query<T> orderBy(String orderByClause);
/**
@@ -1286,10 +1364,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);
@@ -1299,40 +1373,24 @@ 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>
*/
OrderBy<T> order();
/**
* Return the OrderBy so that you can append an ascending or descending
* property to the order by clause.
* <p>
* This will never return a null. If no order by clause exists then an 'empty'
* OrderBy object is returned.
* </p>
* <p>
* This is EXACTLY the same as {@link #order()}.
* </p>
* Deprecated migrate to order().
*/
@Deprecated
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>
* Deprecated migrate to {@link #setOrder(OrderBy)}
*/
@Deprecated
Query<T> setOrderBy(OrderBy<T> orderBy);
/**
@@ -1467,17 +1525,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.
+2 -2
View File
@@ -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();
+9
View File
@@ -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);
}
@@ -0,0 +1,18 @@
package io.ebean;
import javax.persistence.OptimisticLockException;
/**
* Thrown at SERIALIZABLE isolation level for non-recoverable concurrent conflict.
*/
public class SerializableConflictException extends OptimisticLockException {
private static final long serialVersionUID = 1L;
/**
* Create with a message and cause.
*/
public SerializableConflictException(String message, Throwable cause) {
super(message, cause);
}
}
+49 -16
View File
@@ -131,7 +131,7 @@ public interface SqlQuery extends Serializable {
* String sql = "select max(unit_price) from o_order_detail where order_qty > ?";
*
* BigDecimal maxPrice = DB.sqlQuery(sql)
* .setParameter(1, 2)
* .setParameter(42)
* .findSingleAttribute(BigDecimal.class);
*
* }</pre>
@@ -171,31 +171,24 @@ public interface SqlQuery extends Serializable {
* " where unit_price > ? " +
* " order by (unit_price * order_qty) desc";
*
* //
* List<BigDecimal> lineAmounts =
* DB.sqlQuery(sql)
* .setParameter(1, 3)
* .setParameter(42)
* .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
*/
<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 +196,67 @@ 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>
*
* @param value The value to bind
*/
SqlQuery setParameter(Object value);
/**
* Bind the parameter by its index position (1 based like JDBC).
*/
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.
*/
+22 -5
View File
@@ -126,8 +126,6 @@ public interface SqlUpdate {
* {@link Transaction#setBatchMode(boolean)} and
* {@link Transaction#setBatchSize(int)}.
* </p>
*
* @see Ebean#execute(SqlUpdate)
*/
int execute();
@@ -241,28 +239,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 -3
View File
@@ -27,7 +27,7 @@ public interface Transaction extends AutoCloseable {
* @see Database#currentTransaction()
*/
static Transaction current() {
return Ebean.currentTransaction();
return DB.currentTransaction();
}
/**
@@ -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);
@@ -318,7 +318,7 @@ public interface Transaction extends AutoCloseable {
* </p>
* <pre>{@code
*
* try (Transaction transaction = server.beginTransaction()) {
* try (Transaction transaction = database.beginTransaction()) {
*
* transaction.setBatchMode(true);
* transaction.setBatchSize(100);
+4 -4
View File
@@ -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 {
+15 -13
View File
@@ -1,5 +1,6 @@
package io.ebean;
import io.ebean.service.SpiFetchGroupQuery;
import io.ebean.service.SpiFetchGroupService;
import io.ebean.service.SpiProfileLocationFactory;
import io.ebean.service.SpiRawSqlService;
@@ -19,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);
}
/**
@@ -71,4 +66,11 @@ class XServiceProvider {
static <T> FetchGroupBuilder<T> fetchGroupOf(Class<T> cls) {
return fetchGroupService.of(cls);
}
/**
* Return the FetchGroup Query for building fetch groups via query beans.
*/
static <T> SpiFetchGroupQuery<T> fetchGroupQueryFor(Class<T> cls) {
return fetchGroupService.queryFor(cls);
}
}
@@ -0,0 +1,22 @@
package io.ebean.bean;
/**
* A call origin for query execution profiling to collect graph use (for query tuning).
*/
public interface CallOrigin {
/**
* Return the top element. Typically the top stack element with class and line.
*/
String getTopElement();
/**
* Return the full description of the call origin.
*/
String getFullDescription();
/**
* Compute and return an origin key based on the query hash.
*/
String getOriginKey(int queryHash);
}
+22 -59
View File
@@ -3,6 +3,8 @@ package io.ebean.bean;
import java.io.Serializable;
import java.util.Arrays;
import static io.ebean.util.EncodeB64.enc;
/**
* Represent the call stack (stack trace elements).
* <p>
@@ -17,15 +19,15 @@ import java.util.Arrays;
* Note the call stack is trimmed to remove the common ebean internal elements.
* </p>
*/
public final class CallStack implements Serializable {
public final class CallStack implements Serializable, CallOrigin {
private static final long serialVersionUID = -8590644046907438579L;
private static final String NEWLINE = "\n";
private final String zeroHash;
private final String pathHash;
private final StackTraceElement[] callStack;
private final int hc;
public CallStack(StackTraceElement[] callStack, int zeroHash, int pathHash) {
@@ -37,12 +39,17 @@ public final class CallStack implements Serializable {
private int computeHashCode() {
int hc = 0;
for (StackTraceElement aCallStack : callStack) {
hc = 92821 * hc + aCallStack.hashCode();
for (StackTraceElement element : callStack) {
hc = 92821 * hc + element.hashCode();
}
return hc;
}
@Override
public String toString() {
return zeroHash + ":" + pathHash + ":" + callStack[0];
}
@Override
public int hashCode() {
return hc;
@@ -63,73 +70,29 @@ public final class CallStack implements Serializable {
/**
* Return the first element of the call stack.
*/
public StackTraceElement getFirstStackTraceElement() {
return callStack[0];
}
/**
* Return the call stack.
*/
public StackTraceElement[] getCallStack() {
return callStack;
}
/**
* Return the hash for the first stack element.
*/
public String getZeroHash() {
return zeroHash;
}
/**
* Return the hash for the stack elements (excluding first stack element).
*/
public String getPathHash() {
return pathHash;
}
@Override
public String toString() {
return zeroHash + ":" + pathHash + ":" + callStack[0];
public String getTopElement() {
return callStack[0].toString();
}
/**
* Return the call stack lines appended with the given newLine string.
*/
public String description(String newLine) {
@Override
public String getFullDescription() {
StringBuilder sb = new StringBuilder(400);
for (StackTraceElement aCallStack : callStack) {
sb.append(aCallStack.toString()).append(newLine);
for (int i = 0; i < callStack.length; i++) {
if (i > 0) {
sb.append(NEWLINE);
}
sb.append(callStack[i].toString());
}
return sb.toString();
}
@Override
public String getOriginKey(int queryHash) {
return enc(queryHash) + "." + zeroHash + "." + pathHash;
}
private static final int radix = 1 << 6;
private static final int mask = radix - 1;
/**
* Convert the integer to unsigned base 64.
*/
public static String enc(int i) {
char[] buf = new char[32];
int charPos = 32;
do {
buf[--charPos] = intToBase64[i & mask];
i >>>= 6;
} while (i != 0);
return new String(buf, charPos, (32 - charPos));
}
private static final char intToBase64[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
};
}
+36 -12
View File
@@ -16,12 +16,16 @@ public interface EntityBean extends Serializable {
/**
* Return all the property names in defined order.
*/
String[] _ebean_getPropertyNames();
default String[] _ebean_getPropertyNames() {
throw new NotEnhancedException();
}
/**
* Return the property name at the given position.
*/
String _ebean_getPropertyName(int pos);
default String _ebean_getPropertyName(int pos) {
throw new NotEnhancedException();
}
/**
* Return the enhancement marker value.
@@ -30,28 +34,38 @@ public interface EntityBean extends Serializable {
* entity classes are enhanced (specifically not just a super class).
* </p>
*/
String _ebean_getMarker();
default String _ebean_getMarker() {
throw new NotEnhancedException();
}
/**
* Create and return a new entity bean instance.
*/
Object _ebean_newInstance();
default Object _ebean_newInstance() {
throw new NotEnhancedException();
}
/**
* Generated method that sets the loaded state on all the embedded beans on
* this entity bean by using EntityBeanIntercept.setEmbeddedLoaded(Object o);
*/
void _ebean_setEmbeddedLoaded();
default void _ebean_setEmbeddedLoaded() {
throw new NotEnhancedException();
}
/**
* Return true if any embedded beans are new or dirty.
*/
boolean _ebean_isEmbeddedNewOrDirty();
default boolean _ebean_isEmbeddedNewOrDirty() {
throw new NotEnhancedException();
}
/**
* Return the intercept for this object.
*/
EntityBeanIntercept _ebean_getIntercept();
default EntityBeanIntercept _ebean_getIntercept() {
throw new NotEnhancedException();
}
/**
* Similar to _ebean_getIntercept() except it checks to see if the intercept
@@ -66,7 +80,9 @@ public interface EntityBean extends Serializable {
* frameworks that can't take into account our ebean fields.
* </p>
*/
EntityBeanIntercept _ebean_intercept();
default EntityBeanIntercept _ebean_intercept() {
throw new NotEnhancedException();
}
/**
* Set the value of a field of an entity bean of this type.
@@ -75,12 +91,16 @@ public interface EntityBean extends Serializable {
* on entity beans. That means lazy loading and oldValues creation.
* </p>
*/
void _ebean_setField(int fieldIndex, Object value);
default void _ebean_setField(int fieldIndex, Object value) {
throw new NotEnhancedException();
}
/**
* Set the field value with interception.
*/
void _ebean_setFieldIntercept(int fieldIndex, Object value);
default void _ebean_setFieldIntercept(int fieldIndex, Object value) {
throw new NotEnhancedException();
}
/**
* Return the value of a field from an entity bean of this type.
@@ -89,11 +109,15 @@ public interface EntityBean extends Serializable {
* on entity beans. That means lazy loading.
* </p>
*/
Object _ebean_getField(int fieldIndex);
default Object _ebean_getField(int fieldIndex) {
throw new NotEnhancedException();
}
/**
* Return the field value with interception.
*/
Object _ebean_getFieldIntercept(int fieldIndex);
default Object _ebean_getFieldIntercept(int fieldIndex) {
throw new NotEnhancedException();
}
}
@@ -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;
@@ -95,27 +96,29 @@ public final class EntityBeanIntercept implements Serializable {
private final byte[] flags;
private boolean fullyLoadedBean;
private boolean loadedFromCache;
private Object[] origValues;
private Exception[] loadErrors;
private int lazyLoadProperty = -1;
private Object ownerId;
private int sortOrder;
/**
* Create a intercept with a given entity.
* <p>
* Refer to agent ProxyConstructor.
* </p>
*/
public EntityBeanIntercept(Object ownerBean) {
this.owner = (EntityBean) ownerBean;
this.flags = new byte[owner._ebean_getPropertyNames().length];
}
/**
* EXPERIMENTAL - Constructor only for use by serialization frameworks.
*/
public EntityBeanIntercept() {
this.owner = null;
this.flags = null;
}
/**
* Return the 'owning' entity bean.
*/
@@ -303,6 +306,22 @@ public final class EntityBeanIntercept implements Serializable {
}
}
/**
* Set true when the bean has been loaded from L2 bean cache.
* The effect of this is that we should skip the cache if there
* is subsequent lazy loading (bean cache partially populated).
*/
public void setLoadedFromCache(boolean loadedFromCache) {
this.loadedFromCache = loadedFromCache;
}
/**
* Return true if this bean was loaded from L2 bean cache.
*/
public boolean isLoadedFromCache() {
return loadedFromCache;
}
/**
* Return true if the bean should be treated as readOnly. If a setter method
* is called when it is readOnly an Exception is thrown.
@@ -772,7 +791,7 @@ public final class EntityBeanIntercept implements Serializable {
}
public boolean[] getLoaded() {
boolean[] ret= new boolean[flags.length];
boolean[] ret = new boolean[flags.length];
for (int i = 0; i < ret.length; i++) {
ret[i] = (flags[i] & FLAG_LOADED_PROP) != 0;
}
@@ -800,14 +819,14 @@ public final class EntityBeanIntercept implements Serializable {
synchronized (this) {
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());
return;
}
}
@@ -0,0 +1,12 @@
package io.ebean.bean;
/**
* This exception is thrown, when the default implementation of EntityBean is not or not properly overwritten by enhancer.
*
* @author Roland Praml, FOCONIS AG
*
*/
public class NotEnhancedException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
@@ -16,7 +16,7 @@ public final class ObjectGraphOrigin implements Serializable {
private static final long serialVersionUID = 410937765287968708L;
private final CallStack callStack;
private final CallOrigin callOrigin;
private final String beanType;
@@ -24,11 +24,11 @@ public final class ObjectGraphOrigin implements Serializable {
private final String key;
public ObjectGraphOrigin(int queryHash, CallStack callStack, String beanType) {
this.callStack = callStack;
public ObjectGraphOrigin(int queryHash, CallOrigin callOrigin, String beanType) {
this.callOrigin = callOrigin;
this.beanType = beanType;
this.queryHash = queryHash;
this.key = callStack.getOriginKey(queryHash);
this.key = callOrigin.getOriginKey(queryHash);
}
/**
@@ -49,22 +49,22 @@ public final class ObjectGraphOrigin implements Serializable {
/**
* The call stack involved.
*/
public CallStack getCallStack() {
return callStack;
public CallOrigin getCallOrigin() {
return callOrigin;
}
public String getFirstStackElement() {
return callStack.getFirstStackTraceElement().toString();
public String getTopElement() {
return callOrigin.getTopElement();
}
@Override
public String toString() {
return "key[" + key + "] type[" + beanType + "] " + callStack.getFirstStackTraceElement() + " ";
return "key[" + key + "] type[" + beanType + "] " + callOrigin.getTopElement();
}
@Override
public int hashCode() {
int hc = 92821 * callStack.hashCode();
int hc = 92821 * callOrigin.hashCode();
hc = 92821 * hc + beanType.hashCode();
hc = 92821 * hc + queryHash;
return hc;
@@ -82,6 +82,6 @@ public final class ObjectGraphOrigin implements Serializable {
ObjectGraphOrigin e = (ObjectGraphOrigin) obj;
return e.queryHash == queryHash
&& e.beanType.equals(beanType)
&& e.callStack.equals(callStack);
&& e.callOrigin.equals(callOrigin);
}
}
@@ -0,0 +1,48 @@
package io.ebean.bean;
import io.ebean.Database;
/**
* BeanLoader used when single beans are loaded (which is usually not ideal / N+1).
*/
public abstract class SingleBeanLoader implements BeanLoader {
protected final Database database;
SingleBeanLoader(Database database) {
this.database = database;
}
@Override
public String getName() {
return database.getName();
}
/**
* 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);
}
}
}
@@ -1,6 +1,6 @@
package io.ebean.common;
import io.ebean.Ebean;
import io.ebean.DB;
import io.ebean.ExpressionList;
import io.ebean.bean.BeanCollection;
import io.ebean.bean.BeanCollectionLoader;
@@ -93,7 +93,7 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
void lazyLoadCollection(boolean onlyIds) {
if (loader == null) {
loader = (BeanCollectionLoader) Ebean.getServer(ebeanServerName);
loader = (BeanCollectionLoader) DB.byName(ebeanServerName);
}
loader.loadMany(this, onlyIds);
checkEmptyLazyLoad();
@@ -83,10 +83,13 @@ public abstract class AbstractNamingConvention implements NamingConvention {
}
@Override
public String getSequenceName(String tableName, String pkColumn) {
String s = TABLE_REPLACE.matcher(sequenceFormat).replaceAll(Matcher.quoteReplacement(tableName));
public String getSequenceName(String rawTableName, String pkColumn) {
final String tableNameUnquoted = databasePlatform.unQuote(rawTableName);
String s = TABLE_REPLACE.matcher(sequenceFormat).replaceAll(Matcher.quoteReplacement(tableNameUnquoted));
if (pkColumn == null) {
pkColumn = "";
} else {
pkColumn = databasePlatform.unQuote(pkColumn);
}
return COLUMN_REPLACE.matcher(s).replaceAll(Matcher.quoteReplacement(pkColumn));
}
@@ -88,7 +88,6 @@ public class DbConstraintNaming {
* Return the primary key constraint name.
*/
public String primaryKeyName(String tableName) {
return pkPrefix + normaliseTable(tableName) + pkSuffix;
}
@@ -103,7 +102,6 @@ public class DbConstraintNaming {
* Return the index name associated with a foreign key constraint given multiple columns.
*/
public String foreignKeyIndexName(String tableName, String[] columns) {
String colPart = joinColumnNames(columns);
return fkIndexPrefix + normaliseTable(tableName) + fkIndexMiddle + colPart + fkIndexSuffix;
}
@@ -112,7 +110,6 @@ public class DbConstraintNaming {
* Return the index name associated with a foreign key constraint given a single column foreign key.
*/
public String foreignKeyIndexName(String tableName, String column) {
String colPart = normaliseTable(column);
return fkIndexPrefix + normaliseTable(tableName) + fkIndexMiddle + colPart + fkIndexSuffix;
}
@@ -121,7 +118,6 @@ public class DbConstraintNaming {
* Return the index name for a general index (not associated with a foreign key).
*/
public String indexName(String tableName, String column) {
String colPart = normaliseTable(column);
return indexPrefix + normaliseTable(tableName) + indexMiddle + colPart + indexSuffix;
}
@@ -130,7 +126,6 @@ public class DbConstraintNaming {
* Return the index name for a general index (not associated with a foreign key).
*/
public String indexName(String tableName, String[] columns) {
String colPart = joinColumnNames(columns);
return indexPrefix + normaliseTable(tableName) + indexMiddle + colPart + indexSuffix;
}
@@ -139,7 +134,6 @@ public class DbConstraintNaming {
* Join the column names together with underscores.
*/
protected String joinColumnNames(String[] columns) {
if (columns.length == 1) {
return normaliseColumn(columns[0]);
}
@@ -157,7 +151,6 @@ public class DbConstraintNaming {
* Return the unique constraint name.
*/
public String uniqueConstraintName(String tableName, String columnName) {
return uqPrefix + normaliseTable(tableName) + "_" + normaliseColumn(columnName) + uqSuffix;
}
@@ -165,7 +158,6 @@ public class DbConstraintNaming {
* Return the unique constraint name.
*/
public String uniqueConstraintName(String tableName, String[] columns) {
String colPart = joinColumnNames(columns);
return uqPrefix + normaliseTable(tableName) + "_" + colPart + uqSuffix;
}
@@ -174,7 +166,6 @@ public class DbConstraintNaming {
* Return the check constraint name.
*/
public String checkConstraintName(String tableName, String columnName) {
return ckPrefix + normaliseTable(tableName) + "_" + normaliseColumn(columnName) + ckSuffix;
}
@@ -41,17 +41,20 @@ public class DbConstraintNormalise {
}
/**
* Normalise the column name by removing any quoted identifier characters.
* Normalise the column name by removing any quoted identifier characters and formula brackets.
*/
public String normaliseColumn(String columnName) {
columnName = trimQuotes(columnName);
columnName = trimBrackets(trimQuotes(columnName));
if (lowerCaseColumns) {
columnName = columnName.toLowerCase();
}
return columnName;
}
private String trimBrackets(String value) {
return value.replace("(","").replace(")","");
}
/**
* Lower case the table name checking for quoted identifiers.
*/
@@ -29,7 +29,7 @@ public class DocStoreConfig {
protected boolean create;
/**
* The URL of the Document store server. For example: http://localhost:9200.
* The URL of the Document store. For example: http://localhost:9200.
*/
protected String url;
@@ -131,7 +131,7 @@ public class DocStoreConfig {
}
/**
* Set the URL to the Document store server.
* Set the URL to the Document store.
* <p>
* For a local ElasticSearch server this would be: http://localhost:9200
*/
@@ -36,8 +36,7 @@ public class MatchingNamingConvention extends AbstractNamingConvention {
@Override
public TableName getTableNameByConvention(Class<?> beanClass) {
return new TableName(getCatalog(), getSchema(), beanClass.getSimpleName());
return new TableName(quoteIdentifiers(getCatalog()), quoteIdentifiers(getSchema()), quoteIdentifiers(beanClass.getSimpleName()));
}
@Override
@@ -0,0 +1,21 @@
package io.ebean.config;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used by generated code to hold entity classes to register with Ebean.
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ModuleInfo {
/**
* Returns the entity classes with db name prefix.
* <p>
* The db name prefix is added to entity classes for non default databases.
*/
String[] entities() default {};
}
@@ -0,0 +1,19 @@
package io.ebean.config;
import java.util.List;
/**
* Loads and returns entity classes to register with Ebean databases.
*/
public interface ModuleInfoLoader {
/**
* Return the entity classes to register with the default DB.
*/
List<Class<?>> entityClasses();
/**
* Return entity classes to register for a named DB (not default DB).
*/
List<Class<?>> entityClassesFor(String dbName);
}
@@ -17,6 +17,13 @@ public class PlatformConfig {
private boolean allQuotedIdentifiers;
private DbConstraintNaming constraintNaming;
/**
* Flag set when a supplied constraintNaming is used.
*/
private boolean customConstraintNaming;
/**
* The database boolean true value (typically either 1, T, or Y).
*/
@@ -63,7 +70,7 @@ public class PlatformConfig {
* Construct with defaults.
*/
public PlatformConfig() {
this.constraintNaming = new DbConstraintNaming();
}
/**
@@ -80,6 +87,19 @@ public class PlatformConfig {
this.allQuotedIdentifiers = platformConfig.allQuotedIdentifiers;
this.databaseInetAddressVarchar = platformConfig.databaseInetAddressVarchar;
this.customDbTypeMappings = platformConfig.customDbTypeMappings;
this.constraintNaming = new DbConstraintNaming(!allQuotedIdentifiers);
}
public DbConstraintNaming getConstraintNaming() {
return constraintNaming;
}
/**
* Set a custom database constraint naming convention.
*/
public void setConstraintNaming(DbConstraintNaming constraintNaming) {
this.customConstraintNaming = true;
this.constraintNaming = constraintNaming;
}
/**
@@ -94,6 +114,9 @@ public class PlatformConfig {
*/
public void setAllQuotedIdentifiers(boolean allQuotedIdentifiers) {
this.allQuotedIdentifiers = allQuotedIdentifiers;
if (!customConstraintNaming) {
this.constraintNaming = new DbConstraintNaming(!allQuotedIdentifiers);
}
}
/**
+60 -118
View File
@@ -28,7 +28,6 @@ import io.ebean.event.changelog.ChangeLogPrepare;
import io.ebean.event.changelog.ChangeLogRegister;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
import io.ebean.meta.MetaInfoManager;
import io.ebean.migration.MigrationRunner;
import io.ebean.util.StringHelper;
@@ -133,6 +132,15 @@ public class ServerConfig {
private TenantCatalogProvider tenantCatalogProvider;
/**
* When true will load entity classes via ModuleInfoLoader.
* <p>
* NB: ModuleInfoLoader implementations are generated by querybean generator.
* Having this on and registering entity classes means we don't need to manually
* write that code or use classpath scanning to find entity classes.
*/
private boolean loadModuleInfo;
/**
* List of interesting classes such as entities, embedded, ScalarTypes,
* Listeners, Finders, Controllers etc.
@@ -345,26 +353,11 @@ public class ServerConfig {
*/
private NamingConvention namingConvention = new UnderscoreNamingConvention();
/**
* Naming convention used in DDL generation for primary keys, foreign keys etc.
*/
private DbConstraintNaming constraintNaming = new DbConstraintNaming();
/**
* Behaviour of update to include on the change properties.
*/
private boolean updateChangesOnly = true;
/**
* Behaviour of updates in JDBC batch to by default include all properties.
*/
private boolean updateAllPropertiesInBatch;
/**
* Default behaviour for updates when cascade save on a O2M or M2M to delete any missing children.
*/
private boolean updatesDeleteMissingChildren = true;
/**
* Database platform configuration.
*/
@@ -425,10 +418,6 @@ public class ServerConfig {
private ServerCachePlugin serverCachePlugin;
private boolean collectQueryStatsByNode = true;
private boolean collectQueryOrigins = true;
/**
* The default PersistenceContextScope used if one is not explicitly set on a query.
*/
@@ -503,6 +492,11 @@ public class ServerConfig {
*/
private boolean collectQueryPlans;
/**
* The default threshold in micros for collecting query plans.
*/
private long collectQueryPlanThresholdMicros = Long.MAX_VALUE;
/**
* The time in millis used to determine when a query is alerted for being slow.
*/
@@ -1615,14 +1609,14 @@ public class ServerConfig {
* Return the constraint naming convention used in DDL generation.
*/
public DbConstraintNaming getConstraintNaming() {
return constraintNaming;
return platformConfig.getConstraintNaming();
}
/**
* Set the constraint naming convention used in DDL generation.
*/
public void setConstraintNaming(DbConstraintNaming constraintNaming) {
this.constraintNaming = constraintNaming;
platformConfig.setConstraintNaming(constraintNaming);
}
/**
@@ -1892,7 +1886,7 @@ public class ServerConfig {
}
/**
* Return the database platform to use for this server.
* Return the database platform to use for this database.
*/
public DatabasePlatform getDatabasePlatform() {
return databasePlatform;
@@ -2288,15 +2282,21 @@ public class ServerConfig {
* </p>
*
* @param cls the entity type (or other type) that should be registered by this
* server.
* database.
*/
public void addClass(Class<?> cls) {
if (classes == null) {
classes = new ArrayList<>();
}
classes.add(cls);
}
/**
* Register all the classes (typically entity classes).
*/
public void addAll(List<Class<?>> classList) {
if (classList != null && !classList.isEmpty()) {
classes.addAll(classList);
}
}
/**
* Add a package to search for entities via class path search.
* <p>
@@ -2304,9 +2304,6 @@ public class ServerConfig {
* </p>
*/
public void addPackage(String packageName) {
if (packages == null) {
packages = new ArrayList<>();
}
packages.add(packageName);
}
@@ -2332,7 +2329,7 @@ public class ServerConfig {
/**
* Set the list of classes (entities, listeners, scalarTypes etc) that should
* be used for this server.
* be used for this database.
* <p>
* If no classes are specified then the classes are found automatically via
* searching the class path.
@@ -2346,7 +2343,7 @@ public class ServerConfig {
}
/**
* Return the classes registered for this server. Typically this includes
* Return the classes registered for this database. Typically this includes
* entities and perhaps listeners.
*/
public List<Class<?>> getClasses() {
@@ -2409,20 +2406,6 @@ public class ServerConfig {
this.skipCacheAfterWrite = skipCacheAfterWrite;
}
/**
* Return true to only update changed properties.
*/
public boolean isUpdateChangesOnly() {
return updateChangesOnly;
}
/**
* Set to true to only update changed properties.
*/
public void setUpdateChangesOnly(boolean updateChangesOnly) {
this.updateChangesOnly = updateChangesOnly;
}
/**
* Returns true if updates in JDBC batch default to include all properties by default.
*/
@@ -2442,68 +2425,6 @@ public class ServerConfig {
this.updateAllPropertiesInBatch = updateAllPropertiesInBatch;
}
/**
* Return true if updates by default delete missing children when cascading save to a OneToMany or
* ManyToMany. When not set this defaults to true.
*/
public boolean isUpdatesDeleteMissingChildren() {
return updatesDeleteMissingChildren;
}
/**
* Set if updates by default delete missing children when cascading save to a OneToMany or
* ManyToMany. When not set this defaults to true.
*/
public void setUpdatesDeleteMissingChildren(boolean updatesDeleteMissingChildren) {
this.updatesDeleteMissingChildren = updatesDeleteMissingChildren;
}
/**
* Return true if query statistics should be collected by ObjectGraphNode.
*/
public boolean isCollectQueryStatsByNode() {
return collectQueryStatsByNode;
}
/**
* Set to true to collection query execution statistics by ObjectGraphNode.
* <p>
* These statistics can be used to highlight code/query 'origin points' that result in lots of lazy loading.
* </p>
* <p>
* It is considered safe/fine to have this set to true for production.
* </p>
* <p>
* This information can be later retrieved via {@link MetaInfoManager}.
* </p>
*
* @see MetaInfoManager
*/
public void setCollectQueryStatsByNode(boolean collectQueryStatsByNode) {
this.collectQueryStatsByNode = collectQueryStatsByNode;
}
/**
* Return true if query plans should also collect their 'origins'. This means for a given query plan you
* can identify the code/origin points where this query resulted from including lazy loading origins.
*/
public boolean isCollectQueryOrigins() {
return collectQueryOrigins;
}
/**
* Set to true if query plans should collect their 'origin' points. This means for a given query plan you
* can identify the code/origin points where this query resulted from including lazy loading origins.
* <p>
* This information can be later retrieved via {@link MetaInfoManager}.
* </p>
*
* @see MetaInfoManager
*/
public void setCollectQueryOrigins(boolean collectQueryOrigins) {
this.collectQueryOrigins = collectQueryOrigins;
}
/**
* Returns the resource directory.
*/
@@ -2929,11 +2850,14 @@ public class ServerConfig {
}
loadDocStoreSettings(p);
loadModuleInfo = p.getBoolean("loadModuleInfo", loadModuleInfo);
maxCallStack = p.getInt("maxCallStack", maxCallStack);
dumpMetricsOnShutdown = p.getBoolean("dumpMetricsOnShutdown", dumpMetricsOnShutdown);
dumpMetricsOptions = p.get("dumpMetricsOptions", dumpMetricsOptions);
queryPlanTTLSeconds = p.getInt("queryPlanTTLSeconds", queryPlanTTLSeconds);
slowQueryMillis = p.getLong("slowQueryMillis", slowQueryMillis);
collectQueryPlans = p.getBoolean("collectQueryPlans", collectQueryPlans);
collectQueryPlanThresholdMicros = p.getLong("collectQueryPlanThresholdMicros", collectQueryPlanThresholdMicros);
docStoreOnly = p.getBoolean("docStoreOnly", docStoreOnly);
disableL2Cache = p.getBoolean("disableL2Cache", disableL2Cache);
enabledL2Regions = p.get("enabledL2Regions", enabledL2Regions);
@@ -2960,15 +2884,8 @@ public class ServerConfig {
String packagesProp = p.get("search.packages", p.get("packages", null));
packages = getSearchList(packagesProp, packages);
collectQueryStatsByNode = p.getBoolean("collectQueryStatsByNode", collectQueryStatsByNode);
collectQueryOrigins = p.getBoolean("collectQueryOrigins", collectQueryOrigins);
skipCacheAfterWrite = p.getBoolean("skipCacheAfterWrite", skipCacheAfterWrite);
updateAllPropertiesInBatch = p.getBoolean("updateAllPropertiesInBatch", updateAllPropertiesInBatch);
updateChangesOnly = p.getBoolean("updateChangesOnly", updateChangesOnly);
boolean defaultDeleteMissingChildren = p.getBoolean("defaultDeleteMissingChildren", updatesDeleteMissingChildren);
updatesDeleteMissingChildren = p.getBoolean("updatesDeleteMissingChildren", defaultDeleteMissingChildren);
if (p.get("batch.mode") != null || p.get("persistBatching") != null) {
throw new IllegalArgumentException("Property 'batch.mode' or 'persistBatching' is being set but no longer used. Please change to use 'persistBatchMode'");
@@ -3059,20 +2976,20 @@ public class ServerConfig {
return classes;
}
List<Class<?>> classes = new ArrayList<>();
List<Class<?>> classList = new ArrayList<>();
String[] split = StringHelper.splitNames(classNames);
for (String cn : split) {
if (!"class".equalsIgnoreCase(cn)) {
try {
classes.add(Class.forName(cn));
classList.add(Class.forName(cn));
} catch (ClassNotFoundException e) {
String msg = "Error registering class [" + cn + "] from [" + classNames + "]";
throw new RuntimeException(msg, e);
}
}
}
return classes;
return classList;
}
private List<String> getSearchList(String searchNames, List<String> defaultValue) {
@@ -3326,6 +3243,20 @@ public class ServerConfig {
this.collectQueryPlans = collectQueryPlans;
}
/**
* Return the query plan collection threshold in microseconds.
*/
public long getCollectQueryPlanThresholdMicros() {
return collectQueryPlanThresholdMicros;
}
/**
* Set the query plan collection threshold in microseconds.
*/
public void setCollectQueryPlanThresholdMicros(long collectQueryPlanThresholdMicros) {
this.collectQueryPlanThresholdMicros = collectQueryPlanThresholdMicros;
}
/**
* Return true if metrics should be dumped when the server is shutdown.
*/
@@ -3356,6 +3287,17 @@ public class ServerConfig {
this.dumpMetricsOptions = dumpMetricsOptions;
}
/**
* Return true if entity classes should be loaded and registered via ModuleInfoLoader.
* <p>
* When false we either register entity classes via application code or use classpath
* scanning to find and register entity classes.
* </p>
*/
public boolean isAutoLoadModuleInfo() {
return loadModuleInfo && classes.isEmpty();
}
public enum UuidVersion {
VERSION4,
VERSION1,
@@ -18,5 +18,10 @@ public enum DataErrorType {
/**
* Data integrity error like an invalid foreign key.
*/
DataIntegrity
DataIntegrity,
/**
* Non recoverable concurrency conflict.
*/
SerializableConflict
}
@@ -51,6 +51,8 @@ public class DatabasePlatform {
protected boolean supportsDeleteTableAlias;
protected boolean supportsSavepointId = true;
/**
* The behaviour used when ending a read only transaction at read committed isolation level.
*/
@@ -73,6 +75,11 @@ public class DatabasePlatform {
protected boolean caseSensitiveCollation = true;
/**
* Set true if the Database support LIMIT clause on sql update.
*/
protected boolean inlineSqlUpdateLimit;
/**
* For limit/offset, row_number etc limiting of SQL queries.
*/
@@ -137,9 +144,9 @@ public class DatabasePlatform {
*/
protected Platform platform = Platform.GENERIC;
protected String columnAliasPrefix = "c";
protected String truncateTable = "truncate table %s";
protected String tableAliasPlaceHolder = "${ta}";
protected String columnAliasPrefix = "c";
/**
* Use a BackTick ` at the beginning and end of table or column names that you
@@ -167,13 +174,14 @@ public class DatabasePlatform {
/**
* Characters escaped for startsWith, endsWith and contains.
*/
protected char[] likeSpecialCharacters = { '%', '_', '|' };
protected char[] likeSpecialCharacters = {'%', '_', '|'};
protected DbEncrypt dbEncrypt;
protected boolean idInExpandedForm;
protected boolean selectCountWithAlias;
protected boolean selectCountWithColumnAlias;
/**
* If set then use the FORWARD ONLY hint when creating ResultSets for
@@ -183,7 +191,7 @@ public class DatabasePlatform {
/**
* If set then use the CONCUR_UPDATABLE hint when creating ResultSets.
*
* <p>
* This is {@code false} for HANA
*/
protected boolean supportsResultSetConcurrencyModeUpdatable = true;
@@ -328,6 +336,20 @@ public class DatabasePlatform {
return caseSensitiveCollation;
}
/**
* Return true if the platform supports SavepointId values.
*/
public boolean isSupportsSavepointId() {
return supportsSavepointId;
}
/**
* Return true if the platform supports LIMIT with sql update.
*/
public boolean isInlineSqlUpdateLimit() {
return inlineSqlUpdateLimit;
}
/**
* Return the maximum table name length.
* <p>
@@ -359,11 +381,11 @@ public class DatabasePlatform {
/**
* Return a DB Sequence based IdGenerator.
*
* @param be the BackgroundExecutor that can be used to load the sequence if
* desired
* @param ds the DataSource
* @param stepSize the sequence allocation size as defined by mapping (defaults to 50)
* @param seqName the name of the sequence
* @param be the BackgroundExecutor that can be used to load the sequence if
* desired
* @param ds the DataSource
* @param stepSize the sequence allocation size as defined by mapping (defaults to 50)
* @param seqName the name of the sequence
*/
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int stepSize, String seqName) {
return null;
@@ -455,20 +477,6 @@ public class DatabasePlatform {
this.columnAliasPrefix = columnAliasPrefix;
}
/**
* Return the table alias placeholder.
*/
public String getTableAliasPlaceHolder() {
return tableAliasPlaceHolder;
}
/**
* Set the table alias placeholder.
*/
public void setTableAliasPlaceHolder(String tableAliasPlaceHolder) {
this.tableAliasPlaceHolder = tableAliasPlaceHolder;
}
/**
* Return the close quote for quoted identifiers.
*/
@@ -568,7 +576,7 @@ public class DatabasePlatform {
/**
* Normally not needed - overridden in CockroachPlatform.
*/
public boolean isDdlCommitOnCreateIndex() {
public boolean isDdlAutoCommit() {
return false;
}
@@ -648,7 +656,7 @@ public class DatabasePlatform {
if (dbName != null && !dbName.isEmpty()) {
if (dbName.startsWith(openQuote)) {
// trim off the open and close quotes
return dbName.substring(1, dbName.length()-1);
return dbName.substring(1, dbName.length() - 1);
}
}
return dbName;
@@ -661,6 +669,14 @@ public class DatabasePlatform {
return selectCountWithAlias;
}
/**
* Return true if select count with subquery needs column alias (SQL Server).
*/
public boolean isSelectCountWithColumnAlias() {
return selectCountWithColumnAlias;
}
public String completeSql(String sql, Query<?> query) {
if (query.isForUpdate()) {
sql = withForUpdate(sql, query.getForUpdateMode());
@@ -699,6 +715,13 @@ public class DatabasePlatform {
return persistBatchOnCascade;
}
/**
* Return a statement to truncate a table.
*/
public String truncateStatement(String table) {
return String.format(truncateTable, table);
}
/**
* Create the DB schema if it does not exist.
*/
@@ -768,7 +791,7 @@ public class DatabasePlatform {
for (int i = 0; i < value.length(); i++) {
char ch = value.charAt(i);
boolean escaped = false;
for (char escapeChar: likeSpecialCharacters) {
for (char escapeChar : likeSpecialCharacters) {
if (ch == escapeChar) {
if (sb == null) {
sb = new StringBuilder(value.substring(0, i));
@@ -29,6 +29,8 @@ public class DbPlatformTypeMapping {
private static final DbPlatformType INET_NATIVE = new DbPlatformType("inet", false);
private static final DbPlatformType INET_VARCHAR = new DbPlatformType("varchar", 50);
private static final DbPlatformType CIDR_NATIVE = new DbPlatformType("cidr", false);
private static final DbPlatformType CIDR_VARCHAR = new DbPlatformType("varchar", 50);
private static final DbPlatformType UUID_NATIVE = new DbPlatformType("uuid", false);
@SuppressWarnings("unused")
@@ -110,6 +112,7 @@ public class DbPlatformTypeMapping {
put(DbType.JSONVARCHAR, new DbPlatformType("jsonvarchar", 1000));
put(DbType.UUID, UUID_NATIVE);
put(DbType.INET, INET_NATIVE);
put(DbType.CIDR, CIDR_NATIVE);
} else {
put(DbType.VARCHAR, new DbPlatformType("varchar", 255));
@@ -126,6 +129,7 @@ public class DbPlatformTypeMapping {
// default to native UUID and override on platform configure()
put(DbType.UUID, UUID_NATIVE);
put(DbType.INET, INET_VARCHAR);
put(DbType.CIDR, CIDR_VARCHAR);
}
}
@@ -36,7 +36,7 @@ public enum DbType {
UUID(ExtraDbTypes.UUID),
INET(ExtraDbTypes.INET),
CDIR(ExtraDbTypes.CDIR),
CIDR(ExtraDbTypes.CIDR),
POINT(ExtraDbTypes.POINT),
POLYGON(ExtraDbTypes.POLYGON),
@@ -41,7 +41,7 @@ public interface ExtraDbTypes {
int JSONBlob = 5005;
int INET = 5020;
int CDIR = 5021;
int CIDR = 5021;
/**
* Geo Point
@@ -12,9 +12,10 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.NavigableSet;
import java.util.TreeSet;
/**
* Database sequence based IdGenerator.
@@ -42,7 +43,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
protected final BackgroundExecutor backgroundExecutor;
protected final ArrayList<Long> idList = new ArrayList<>(50);
protected final NavigableSet<Long> idList = new TreeSet<>();
protected final int allocationSize;
@@ -97,15 +98,13 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
@Override
public Object nextId(Transaction t) {
synchronized (monitor) {
int size = idList.size();
if (size > 0) {
maybeLoadMoreInBackground(size);
} else {
loadMore(allocationSize);
}
return idList.remove(0);
return idList.pollFirst();
}
}
@@ -3,6 +3,7 @@ package io.ebean.config.dbplatform;
import io.ebean.AcquireLockException;
import io.ebean.DataIntegrityException;
import io.ebean.DuplicateKeyException;
import io.ebean.SerializableConflictException;
import javax.persistence.PersistenceException;
import java.sql.SQLException;
@@ -14,12 +15,12 @@ import java.util.Map;
*/
public class SqlCodeTranslator implements SqlExceptionTranslator {
private final Map<String,DataErrorType> map;
private final Map<String, DataErrorType> map;
/**
* Create given the map of SQLState codes to error types.
*/
public SqlCodeTranslator(Map<String,DataErrorType> map) {
public SqlCodeTranslator(Map<String, DataErrorType> map) {
this.map = map;
}
@@ -46,6 +47,8 @@ public class SqlCodeTranslator implements SqlExceptionTranslator {
return new DuplicateKeyException(message, e);
case DataIntegrity:
return new DataIntegrityException(message, e);
case SerializableConflict:
return new SerializableConflictException(message, e);
}
}
// return a generic exception
@@ -8,7 +8,7 @@ import java.util.Map;
*/
public class SqlErrorCodes {
private final Map<String,DataErrorType> map = new HashMap<>();
private final Map<String, DataErrorType> map = new HashMap<>();
/**
* Map the codes to AcquireLockException.
@@ -31,6 +31,13 @@ public class SqlErrorCodes {
return add(DataErrorType.DuplicateKey, codes);
}
/**
* Map the codes to SerializableConflictException.
*/
public SqlErrorCodes addSerializableConflict(String... codes) {
return add(DataErrorType.SerializableConflict, codes);
}
private SqlErrorCodes add(DataErrorType type, String... codes) {
for (String code : codes) {
map.put(code, type);
@@ -47,7 +47,7 @@ public class ClickHousePlatform extends DatabasePlatform {
dbTypeMap.put(DbType.UUID, new DbPlatformType("UUID", false));
dbTypeMap.put(DbType.INET, new DbPlatformType("String", false));
dbTypeMap.put(DbType.CDIR, new DbPlatformType("String", false));
dbTypeMap.put(DbType.CIDR, new DbPlatformType("String", false));
}
@Override
@@ -0,0 +1,4 @@
/**
* Clickhouse DB specific support.
*/
package io.ebean.config.dbplatform.clickhouse;
@@ -21,7 +21,7 @@ public class CockroachPlatform extends PostgresPlatform {
* Needs a commit after create index such that alter table add foreign key ... succeeds.
*/
@Override
public boolean isDdlCommitOnCreateIndex() {
public boolean isDdlAutoCommit() {
return true;
}
@@ -0,0 +1,4 @@
/**
* Cockroach DB specific support.
*/
package io.ebean.config.dbplatform.cockroach;
@@ -22,6 +22,7 @@ public class DB2Platform extends DatabasePlatform {
this.platform = Platform.DB2;
this.maxTableNameLength = 18;
this.maxConstraintNameLength = 18;
this.truncateTable = "truncate table %s reuse storage ignore delete triggers immediate";
this.sqlLimiter = new Db2SqlLimiter();
this.dbIdentity.setSupportsGetGeneratedKeys(true);
@@ -24,9 +24,9 @@ public class H2Platform extends DatabasePlatform {
this.historySupport = new H2HistorySupport();
this.nativeUuidType = true;
this.supportsDeleteTableAlias = true;
this.inlineSqlUpdateLimit = true;
this.dbDefaultValue.setNow("now()");
this.columnAliasPrefix = null;
this.exceptionTranslator =
new SqlErrorCodes()
.addAcquireLock("50200","HYT00")
@@ -18,7 +18,6 @@ public class HanaPlatform extends DatabasePlatform {
this.persistBatchOnCascade = PersistBatch.NONE;
this.supportsResultSetConcurrencyModeUpdatable = false;
this.columnAliasPrefix = null;
this.historySupport = new HanaHistorySupport();
this.basicSqlLimiter = new HanaBasicSqlLimiter();
@@ -21,7 +21,7 @@ public class HsqldbPlatform extends DatabasePlatform {
super();
this.platform = Platform.HSQLDB;
this.dbEncrypt = new H2DbEncrypt();
this.truncateTable = "delete from %s";
this.dbIdentity.setIdType(IdType.IDENTITY);
this.dbIdentity.setSupportsGetGeneratedKeys(true);
this.dbIdentity.setSupportsSequence(true);
@@ -0,0 +1,14 @@
package io.ebean.config.dbplatform.mysql;
import io.ebean.annotation.Platform;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.config.dbplatform.DbType;
public class MySql55Platform extends MySqlPlatform {
public MySql55Platform() {
super();
this.platform = Platform.MYSQL55;
dbTypeMap.put(DbType.TIMESTAMP, new DbPlatformType("datetime"));
}
}
@@ -27,10 +27,11 @@ public class MySqlPlatform extends DatabasePlatform {
this.platform = Platform.MYSQL;
this.useExtraTransactionOnIterateSecondaryQueries = true;
this.selectCountWithAlias = true;
this.supportsSavepointId = false;
this.inlineSqlUpdateLimit = true;
this.dbEncrypt = new MySqlDbEncrypt();
this.historySupport = new MySqlHistorySupport();
this.columnAliasPrefix = null;
this.dbIdentity.setIdType(IdType.IDENTITY);
this.dbIdentity.setSupportsGetGeneratedKeys(true);
this.dbIdentity.setSupportsIdentity(true);
@@ -51,8 +52,8 @@ public class MySqlPlatform extends DatabasePlatform {
this.openQuote = "`";
this.closeQuote = "`";
// use pipe for escaping as it depends if mysql runs in no_backslash_escapes or not.
this.likeClauseRaw = "like ? escape ''";
this.likeClauseEscaped = "like ? escape '|'";
this.likeClauseRaw = "like ? escape''";
this.likeClauseEscaped = "like ? escape'|'";
this.forwardOnlyHintOnFindIterate = true;
this.booleanDbType = Types.BIT;
@@ -64,6 +65,8 @@ public class MySqlPlatform extends DatabasePlatform {
dbTypeMap.put(DbType.BLOB, new MySqlBlob());
dbTypeMap.put(DbType.BINARY, new DbPlatformType("binary", 255));
dbTypeMap.put(DbType.VARBINARY, new DbPlatformType("varbinary", 255));
dbTypeMap.put(DbType.JSON, new DbPlatformType("json", false));
dbTypeMap.put(DbType.JSONB, new DbPlatformType("json", false));
}
@Override
@@ -0,0 +1,10 @@
package io.ebean.config.dbplatform.nuodb;
import io.ebean.config.dbplatform.DbViewHistorySupport;
/**
* Runtime support for @History with NuoDB.
*/
public class NuoDbHistorySupport extends DbViewHistorySupport {
}
@@ -0,0 +1,62 @@
package io.ebean.config.dbplatform.nuodb;
import io.ebean.BackgroundExecutor;
import io.ebean.Query;
import io.ebean.annotation.Platform;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebean.config.dbplatform.DbType;
import io.ebean.config.dbplatform.IdType;
import io.ebean.config.dbplatform.PlatformIdGenerator;
import io.ebean.config.dbplatform.SqlErrorCodes;
import javax.sql.DataSource;
/**
* NuoDb specific platform.
*/
public class NuoDbPlatform extends DatabasePlatform {
public NuoDbPlatform() {
super();
this.platform = Platform.NUODB;
this.idInExpandedForm = true;
this.supportsResultSetConcurrencyModeUpdatable = false;
this.supportsDeleteTableAlias = true;
this.columnAliasPrefix = null;
this.likeClauseRaw = "like ?";
this.historySupport = new NuoDbHistorySupport();
//this.dbEncrypt = ...
dbIdentity.setIdType(IdType.IDENTITY);
dbIdentity.setSupportsIdentity(true);
dbIdentity.setSupportsSequence(true);
dbIdentity.setSupportsGetGeneratedKeys(true);
// No referential integrity exception to map
this.exceptionTranslator =
new SqlErrorCodes()
//.addAcquireLock("")
.addDuplicateKey("23000")
.addSerializableConflict("40002")
.build();
dbTypeMap.put(DbType.INTEGER, new DbPlatformType("integer", false));
}
@Override
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, int stepSize, String seqName) {
return new NuoDbSequence(be, ds, seqName, stepSize);
}
@Override
protected String withForUpdate(String sql, Query.ForUpdate forUpdateMode) {
switch (forUpdateMode) {
case NOWAIT:
return sql + " for update nowait";
case SKIPLOCKED:
default:
return sql + " for update";
}
}
}
@@ -0,0 +1,24 @@
package io.ebean.config.dbplatform.nuodb;
import io.ebean.BackgroundExecutor;
import io.ebean.config.dbplatform.SequenceStepIdGenerator;
import javax.sql.DataSource;
public class NuoDbSequence extends SequenceStepIdGenerator {
private final String nextSql;
/**
* Construct where batchSize is the sequence step size.
*/
public NuoDbSequence(BackgroundExecutor be, DataSource ds, String seqName, int stepSize) {
super(be, ds, seqName, stepSize);
this.nextSql = "select next value for " + seqName + " from dual";
}
@Override
public String getSql(int batchSize) {
return nextSql;
}
}
@@ -0,0 +1,4 @@
/**
* NuoDB specific support.
*/
package io.ebean.config.dbplatform.nuodb;
@@ -30,7 +30,7 @@ public class OraclePlatform extends DatabasePlatform {
this.sqlLimiter = new RownumSqlLimiter();
this.basicSqlLimiter = new BasicSqlAnsiLimiter();
this.historySupport = new OracleDbHistorySupport();
this.truncateTable = "truncate table %s cascade";
dbIdentity.setIdType(IdType.SEQUENCE);
dbIdentity.setSupportsSequence(true);
dbIdentity.setSupportsIdentity(true);
@@ -48,6 +48,7 @@ public class OraclePlatform extends DatabasePlatform {
//.addAcquireLock("")
.addDuplicateKey("1")
.addDataIntegrity("2291")
.addSerializableConflict("72000")
.build();
this.openQuote = "\"";
@@ -14,8 +14,6 @@ public class Postgres8Platform extends PostgresPlatform {
super();
this.dbIdentity.setSupportsGetGeneratedKeys(false);
this.dbIdentity.setIdType(IdType.SEQUENCE);
this.dbIdentity.setSupportsSequence(true);
this.dbIdentity.setSupportsIdentity(true);
this.columnAliasPrefix = "as c";
}
@@ -36,7 +36,7 @@ public class PostgresPlatform extends DatabasePlatform {
this.clobDbType = Types.VARCHAR;
this.nativeUuidType = true;
this.columnAliasPrefix = null;
this.truncateTable = "truncate table %s cascade";
this.dbEncrypt = new PostgresDbEncrypt();
this.historySupport = new PostgresHistorySupport();
@@ -44,6 +44,7 @@ public class PostgresPlatform extends DatabasePlatform {
this.dbIdentity.setIdType(IdType.IDENTITY);
this.dbIdentity.setSupportsGetGeneratedKeys(true);
this.dbIdentity.setSupportsSequence(true);
this.dbIdentity.setSupportsIdentity(true);
this.dbDefaultValue.setNow("current_timestamp");
@@ -51,7 +52,8 @@ public class PostgresPlatform extends DatabasePlatform {
new SqlErrorCodes()
.addAcquireLock("55P03")
.addDuplicateKey("23505")
.addDataIntegrity("23000","23502","23503","23514")
.addDataIntegrity("23000", "23502", "23503", "23514")
.addSerializableConflict("40001")
.build();
this.openQuote = "\"";
@@ -62,6 +64,7 @@ public class PostgresPlatform extends DatabasePlatform {
dbTypeMap.put(DbType.UUID, new DbPlatformType("uuid", false));
dbTypeMap.put(DbType.INET, new DbPlatformType("inet", false));
dbTypeMap.put(DbType.CIDR, new DbPlatformType("cidr", false));
dbTypeMap.put(DbType.HSTORE, new DbPlatformType("hstore", false));
dbTypeMap.put(DbType.JSON, new DbPlatformType("json", false));
dbTypeMap.put(DbType.JSONB, new DbPlatformType("jsonb", false));
@@ -126,7 +129,6 @@ public class PostgresPlatform extends DatabasePlatform {
@Override
public boolean tablePartitionsExist(Connection connection, String table) throws SQLException {
try (PreparedStatement statement = connection.prepareStatement("select count(*) from pg_inherits i WHERE i.inhparent = ?::regclass")) {
statement.setString(1, table);
try (ResultSet resultSet = statement.executeQuery()) {
@@ -137,18 +139,15 @@ public class PostgresPlatform extends DatabasePlatform {
/**
* Return SQL using built in partition helper functions to create some initial partitions.
*
* <p>
* Only use this if extra-ddl doesn't have some initial partitions defined (which it should).
*/
@Override
public String tablePartitionInit(String tableName, PartitionMode mode, String property, String pkey) {
if (property == null) {
property = "";
}
if (pkey == null) {
pkey = "";
}
return "select partition('" + mode.name().toLowerCase() + "','" + tableName + "','" + pkey + "','" + property + "',1);";
// default partition required pg11 but this is only used for testing but bumped test docker container to pg11 by default
return
"create table " + tableName + "_default" + " partition of " + tableName + " default;\n" +
"select partition('" + mode.name().toLowerCase() + "','" + tableName + "',1);";
}
}
@@ -17,7 +17,7 @@ public class SQLitePlatform extends DatabasePlatform {
this.dbIdentity.setSupportsGetGeneratedKeys(false);
this.dbIdentity.setSupportsSequence(false);
this.dbIdentity.setSelectLastInsertedIdTemplate("select last_insert_rowid()");
this.truncateTable = "delete from %s";
this.booleanDbType = Types.INTEGER;
this.likeClauseRaw = "like ?";
this.likeClauseEscaped = "like ?";
@@ -28,6 +28,7 @@ abstract class SqlServerBasePlatform extends DatabasePlatform {
this.persistBatchOnCascade = PersistBatch.NONE;
this.idInExpandedForm = true;
this.selectCountWithAlias = true;
this.selectCountWithColumnAlias = true;
this.sqlLimiter = new SqlServerSqlLimiter();
this.basicSqlLimiter = new SqlServerBasicSqlLimiter();
this.historySupport = new SqlServerHistorySupport();
@@ -1,6 +1,6 @@
package io.ebean.dbmigration;
import io.ebean.EbeanServer;
import io.ebean.Database;
import io.ebean.annotation.Platform;
import io.ebean.config.ServerConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
@@ -62,11 +62,28 @@ public interface DbMigration {
*/
void setPathToResources(String pathToResources);
/**
* Set the path where migrations are generated to (which defaults to "dbmigration").
* <p>
* Normally we only use this when we use Ebean to generate the database migrations
* and then use some other tool like FlywayDB to run the migrations.
* <p>
* Example: with <code>setMigrationPath("db/migration")</code> ... the migrations
* are generated into <code>src/resources/db/migration</code>.
* <p>
* Note that if Ebean migration runner is used we should not use this method but
* instead set the migrationPath via a property such that both the migration generator
* and migration runner both use the same path.
*
* @param migrationPath The path that migrations are generated into.
*/
void setMigrationPath(String migrationPath);
/**
* Set the server to use to determine the current model.
* Typically this is not called explicitly.
*/
void setServer(EbeanServer ebeanServer);
void setServer(Database database);
/**
* Set the serverConfig to use. Typically this is not called explicitly.
@@ -76,7 +93,7 @@ public interface DbMigration {
/**
* Set the specific platform to generate DDL for.
* <p>
* If not set this defaults to the platform of the default server.
* If not set this defaults to the platform of the default database.
* </p>
*/
void setPlatform(Platform platform);
@@ -84,7 +101,7 @@ public interface DbMigration {
/**
* Set the specific platform to generate DDL for.
* <p>
* If not set this defaults to the platform of the default server.
* If not set this defaults to the platform of the default database.
* </p>
*/
void setPlatform(DatabasePlatform databasePlatform);
@@ -136,6 +153,23 @@ public interface DbMigration {
*/
void setGeneratePendingDrop(String generatePendingDrop);
/**
* Set to true if ALTER TABLE ADD FOREIGN KEY should be generated with an option to skip validation.
* <p>
* Currently this is only useful for Postgres DDL adding the <code>NOT VALID</code> option.
* </p>
*/
void setAddForeignKeySkipCheck(boolean addForeignKeySkipCheck);
/**
* Set the lock timeout to be included with the DDL generation.
* <p>
* Currently this is only useful for Postgres migrations adding a <code>set lock_timeout</code>
* statement to the generated database migration.
* </p>
*/
void setLockTimeout(int seconds);
/**
* Add an additional platform to write the migration DDL.
* <p>
@@ -198,6 +232,7 @@ public interface DbMigration {
* An "init" migration can only be executed and used on a database that has had no
* prior migrations run on it.
* </p>
*
* @return the version of the generated migration
*/
String generateInitMigration() throws IOException;
@@ -15,8 +15,8 @@ package io.ebean.event;
*
* Object extaBeanToSave = ...;
* Transaction t = request.getTransaction();
* EbeanServer server = request.getEbeanServer();
* server.save(extraBeanToSave, t);
* Database server = request.getEbeanServer();
* database.save(extraBeanToSave, t);
*
* }</pre>
* <p>
@@ -41,6 +41,11 @@ public interface BeanPersistRequest<T> {
*/
Set<String> getUpdatedProperties();
/**
* Flags set for dirty properties (used by ElasticSearch integration).
*/
boolean[] getDirtyProperties();
/**
* Return true for an update request if at least one of dirty properties is contained
* in the given set of property names.
@@ -24,6 +24,11 @@ public interface BeanQueryRequest<T> {
*/
Query<T> getQuery();
/**
* Return true if an Id IN expression should have the bind parameters padded.
*/
boolean isPadInExpression();
/**
* Return true if multi-value binding using Array or Table Values is supported.
*/
@@ -1,6 +1,6 @@
package io.ebean.event;
import io.ebean.Ebean;
import io.ebean.DB;
import java.util.Set;
@@ -8,7 +8,7 @@ import java.util.Set;
* Listen for bulk table events that occur.
* <p>
* These events can be triggered via
* {@link Ebean#externalModification(String, boolean, boolean, boolean)} or
* {@link DB#externalModification(String, boolean, boolean, boolean)} or
* automatically determined from Ebean bulk update statements.
*/
public interface BulkTableEventListener {
@@ -9,9 +9,8 @@ import java.util.List;
public class BasicMetricVisitor extends AbstractMetricVisitor implements ServerMetrics {
private final List<MetaTimedMetric> timed = new ArrayList<>();
private final List<MetaQueryMetric> dtoQuery = new ArrayList<>();
private final List<MetaOrmQueryMetric> ormQuery = new ArrayList<>();
private final List<MetaCountMetric> countMetrics = new ArrayList<>();
private final List<MetaQueryMetric> query = new ArrayList<>();
private final List<MetaCountMetric> count = new ArrayList<>();
/**
* Construct to reset and collect everything.
@@ -27,33 +26,19 @@ public class BasicMetricVisitor extends AbstractMetricVisitor implements ServerM
super(reset, collectTransactionMetrics, collectQueryMetrics, collectL2Metrics);
}
/**
* Return timed metrics for Transactions, labelled SqlQuery, labelled SqlUpdate.
*/
@Override
public List<MetaTimedMetric> getTimedMetrics() {
return timed;
}
/**
* Return the DTO query metrics.
*/
@Override
public List<MetaQueryMetric> getDtoQueryMetrics() {
return dtoQuery;
}
/**
* Return the ORM query metrics.
*/
@Override
public List<MetaOrmQueryMetric> getOrmQueryMetrics() {
return ormQuery;
public List<MetaQueryMetric> getQueryMetrics() {
return query;
}
@Override
public List<MetaCountMetric> getCountMetrics() {
return countMetrics;
return count;
}
@Override
@@ -63,16 +48,11 @@ public class BasicMetricVisitor extends AbstractMetricVisitor implements ServerM
@Override
public void visitQuery(MetaQueryMetric metric) {
dtoQuery.add(metric);
}
@Override
public void visitOrmQuery(MetaOrmQueryMetric metric) {
ormQuery.add(metric);
query.add(metric);
}
@Override
public void visitCount(MetaCountMetric metric) {
countMetrics.add(metric);
count.add(metric);
}
}
@@ -1,19 +1,9 @@
package io.ebean.meta;
/**
* Count metrics.
* Count metrics. For example L2 cache hits.
*/
public interface MetaCountMetric {
/**
* Return the metric type.
*/
MetricType getMetricType();
/**
* Return the metric name.
*/
String getName();
public interface MetaCountMetric extends MetaMetric {
/**
* Return the total count.
@@ -17,9 +17,21 @@ public interface MetaInfoManager {
ServerMetrics collectMetrics();
/**
* Collect query plans.
* Collect the metrics in raw JSON form.
* <pre>{@code
*
* String metricsJson = database.getMetaInfoManager()
* .collectMetricsAsJson()
* .json();
*
* }</pre>
*/
List<MetaQueryPlan> collectQueryPlans(QueryPlanRequest request);
ServerMetricsAsJson collectMetricsAsJson();
/**
* Return the metrics as a list of MetricData.
*/
List<MetricData> collectMetricsAsData();
/**
* Visit the metrics resetting and collecting/reporting as desired.
@@ -38,15 +50,20 @@ public interface MetaInfoManager {
void resetAllMetrics();
/**
* Collect and return the ObjectGraphNode statistics.
* Initiate query plan collection by turning on "bind capture" on matching query plans.
* <p>
* These show query executions based on an origin point and relative path.
* This is used to look at the amount of lazy loading occurring for a given
* query origin point and highlight potential for tuning a query.
* </p>
* Also refer to ServerConfig collectQueryPlans that needs to be set to true
* and collectQueryPlanThresholdMicros which is a global defaults that can also
* initiate query plan capture.
*
* @param reset Set to true to reset the underlying statistics after collection.
* @return The query plans that have had bind capture turned on by this request.
*/
List<MetaOrmQueryNode> collectNodeStatistics(boolean reset);
List<MetaQueryPlan> queryPlanInit(QueryPlanInit initRequest);
/**
* Collect query plans in the foreground.
*/
List<MetaQueryPlan> queryPlanCollectNow(QueryPlanRequest request);
}
@@ -0,0 +1,18 @@
package io.ebean.meta;
/**
* Metrics collected by Ebean including timed metrics and counters.
*/
public interface MetaMetric {
/**
* Return the metric type.
*/
MetricType getMetricType();
/**
* Return the metric name.
*/
String getName();
}
@@ -1,35 +0,0 @@
package io.ebean.meta;
import java.util.List;
/**
* Query execution statistics for Orm queries.
*/
public interface MetaOrmQueryMetric extends MetaQueryMetric {
/**
* Return true if this query plan was tuned by AutoTune.
*/
boolean isAutoTuned();
/**
* Return the hash of the sql.
*/
String getSqlHash();
/**
* Return the time of the last query executed using this plan.
*/
long getLastQueryTime();
/**
* Return the 'origin' points and paths that resulted in the query being
* executed and the associated number of times the query was executed via that
* path.
* <p>
* This includes direct and lazy loading paths.
* </p>
*/
List<MetaOrmQueryOrigin> getOrigins();
}
@@ -1,39 +0,0 @@
package io.ebean.meta;
import io.ebean.bean.ObjectGraphNode;
/**
* Statistics for query execution based on object graph origin and paths.
* <p>
* These statistics can be used to identify origin queries that result in lots
* of lazy loading.
* </p>
*/
public interface MetaOrmQueryNode {
/**
* Return the ObjectGraphNode which has the origin point and relative path.
*/
ObjectGraphNode getNode();
/**
* Return the startTime of statistics collection.
*/
long getStartTime();
/**
* Return the total count of queries executed for this node.
*/
long getCount();
/**
* Return the total time of queries executed for this node.
*/
long getTotalTime();
/**
* Return the total beans loaded by queries for this node.
*/
long getTotalBeans();
}
@@ -1,30 +0,0 @@
package io.ebean.meta;
import io.ebean.bean.ObjectGraphNode;
/**
* Holds a query 'origin' point and count for the number of queries executed for
* this 'origin'.
* <p>
* This basically points to the bit of original code and query that results in
* this query directly or via lazy loading.
* </p>
*/
public interface MetaOrmQueryOrigin {
/**
* The 'origin' and path which this query belongs to.
* <p>
* For lazy loading queries this points to the original query and associated
* navigation path that resulted in this query being executed.
* </p>
*/
ObjectGraphNode getObjectGraphNode();
/**
* The number of times a query was fired for this node since the counter was
* last reset.
*/
long getCount();
}
@@ -1,7 +1,5 @@
package io.ebean.meta;
import io.ebean.ProfileLocation;
/**
* Query execution metrics.
*/
@@ -17,14 +15,14 @@ public interface MetaQueryMetric extends MetaTimedMetric {
*/
String getLabel();
/**
* Return the profile location.
*/
ProfileLocation getProfileLocation();
/**
* The actual SQL of the query.
*/
String getSql();
/**
* Return the hash of the plan.
*/
String getHash();
}
@@ -2,6 +2,9 @@ package io.ebean.meta;
import io.ebean.ProfileLocation;
/**
* Meta data for captured query plan.
*/
public interface MetaQueryPlan {
/**
@@ -25,9 +28,9 @@ public interface MetaQueryPlan {
String getSql();
/**
* Return the hash of the sql.
* Return the hash of the plan.
*/
String getSqlHash();
String getHash();
/**
* Return a description of the bind values.
@@ -4,28 +4,13 @@ package io.ebean.meta;
/**
* Timed execution statistics.
*/
public interface MetaTimedMetric {
/**
* Return the metric type.
*/
MetricType getMetricType();
/**
* Return the metric name.
*/
String getName();
public interface MetaTimedMetric extends MetaMetric {
/**
* Return the metric location if defined.
*/
String getLocation();
/**
* Return the time the counters started from.
*/
long getStartTime();
/**
* Return the total count.
*/
@@ -47,9 +32,11 @@ public interface MetaTimedMetric {
long getMean();
/**
* Return the total beans or rows processed or loaded.
*
* This will be 0 if the metric isn't a query plan (like transaction execution statistics).
* Return true if this is the first metrics collection for this query.
* <p>
* This can be used to suppress including the SQL and location from metrics
* content.
* </p>
*/
long getBeanCount();
boolean initialCollection();
}
@@ -0,0 +1,98 @@
package io.ebean.meta;
/**
* An individual metric.
*/
public class MetricData {
private String name;
private String type;
private String hash;
private String loc;
private String sql;
private Long count;
private Long mean;
private Long max;
private Long total;
public MetricData(String name, String type) {
this.name = name;
this.type = type;
}
public MetricData() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
public Long getCount() {
return count;
}
public void setCount(Long count) {
this.count = count;
}
public Long getMean() {
return mean;
}
public void setMean(Long mean) {
this.mean = mean;
}
public Long getMax() {
return max;
}
public void setMax(Long max) {
this.max = max;
}
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
}
@@ -10,6 +10,11 @@ public enum MetricType {
*/
TXN,
/**
* ORM Insert Update or Delete.
*/
IUD,
/**
* ORM queries.
*/
@@ -40,11 +40,6 @@ public interface MetricVisitor {
*/
void visitQuery(MetaQueryMetric metric);
/**
* Visit ORM query metrics.
*/
void visitOrmQuery(MetaOrmQueryMetric metric);
/**
* Visit a Counter metric.
*/
@@ -0,0 +1,67 @@
package io.ebean.meta;
import java.util.HashSet;
import java.util.Set;
/**
* Initiate query plan collection for plans by their hash or all query plans.
*/
public class QueryPlanInit {
private boolean all;
private Set<String> hashes = new HashSet<>();
private long thresholdMicros;
/**
* Return true if this initiates bind collection on all query plans.
*/
public boolean isAll() {
return all;
}
/**
* Set to true to initiate bind collection on all query plans.
*/
public void setAll(boolean all) {
this.all = all;
}
/**
* Return the query execution time threshold which must be exceeded to initiate
* query plan collection.
*/
public long getThresholdMicros() {
return thresholdMicros;
}
/**
* Set the query execution time threshold which must be exceeded to initiate
* query plan collection.
*/
public void setThresholdMicros(long thresholdMicros) {
this.thresholdMicros = thresholdMicros;
}
/**
* Return true if the query plan should be initiated based on it's hash.
*/
public boolean includeHash(String hash) {
return all || hashes.contains(hash);
}
/**
* Return the specific hashes that we want to collect query plans on.
*/
public Set<String> getHashes() {
return hashes;
}
/**
* Set the specific hashes that we want to collect query plans on.
*/
public void setHashes(Set<String> hashes) {
this.hashes = hashes;
}
}
@@ -1,97 +1,66 @@
package io.ebean.meta;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* Request used to capture query plans.
*/
public class QueryPlanRequest {
private final List<MetaQueryPlan> plans = new ArrayList<>();
private Connection connection;
private boolean store;
private long since;
private Set<Class<?>> includedBeanTypes;
private int maxCount;
private Set<String> includedLabels;
public List<MetaQueryPlan> getPlans() {
return plans;
}
private long maxTimeMillis;
/**
* Return the connection to use to capture the query plans.
*/
public Connection getConnection() {
return connection;
}
/**
* Set the connection to use to capture the query plans.
*/
public void setConnection(Connection connection) {
this.connection = connection;
}
/**
* Return true if the captured query plan is stored.
*/
public boolean isStore() {
return store;
}
/**
* Set to true to store the captured query plan.
*/
public void setStore(boolean store) {
this.store = store;
}
/**
* Return the epoch time after which the query plan was capture (to be included).
* Return the epoch time in millis for minimum bind capture time.
* <p>
* When set this ensures that the bind values used to get the query plan
* have been around for a while (e.g. 5 mins) and so reasonably represent
* bind values that match the slowest execution for this query plan.
*/
public long getSince() {
return since;
}
/**
* Set the epoch time after which the query plan was captured.
* <p>
* This is used to only capture plans that have changed since a given time (like the time of last capture).
* </p>
* Set the epoch time (e.g. 5 mins ago) such that the query bind values
* reasonably represent bind values that match the slowest execution for this query plan.
*
* @param since The time after which the query plan was captured to be included
* @param since The minimum age of the bind values capture.
*/
public void setSince(long since) {
this.since = since;
}
/**
* Process consume the query plan.
* Return the maximum number of plans to capture.
*/
public void process(MetaQueryPlan plan) {
plans.add(plan);
public int getMaxCount() {
return maxCount;
}
/**
* Return true if the bean type should be included in the query plan capture.
* Set the maximum number of plans to capture.
*/
public boolean includeType(Class<?> beanType) {
return includedBeanTypes == null || includedBeanTypes.isEmpty() || includedBeanTypes.contains(beanType);
public void setMaxCount(int maxCount) {
this.maxCount = maxCount;
}
/**
* Return true if the label should be included in the query plan capture.
* Return the maximum amount of time we want to use to capture plans.
* <p>
* Query plan collection will stop once this time is exceeded.
*/
public boolean includeLabel(String label) {
return includedLabels == null || includedLabels.isEmpty() || includedLabels.contains(label);
public long getMaxTimeMillis() {
return maxTimeMillis;
}
/**
* Set the maximum amount of time we want to use to capture plans.
* <p>
* Query plan collection will stop once this time is exceeded.
*/
public void setMaxTimeMillis(long maxTimeMillis) {
this.maxTimeMillis = maxTimeMillis;
}
}
@@ -13,14 +13,9 @@ public interface ServerMetrics {
List<MetaTimedMetric> getTimedMetrics();
/**
* Return the DTO query metrics.
* Return the query metrics.
*/
List<MetaQueryMetric> getDtoQueryMetrics();
/**
* Return the ORM query metrics.
*/
List<MetaOrmQueryMetric> getOrmQueryMetrics();
List<MetaQueryMetric> getQueryMetrics();
/**
* Return the Counter metrics.

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