Compare commits

...
Author SHA1 Message Date
Robin Bygrave 436988694d [maven-release-plugin] prepare release avaje-ebeanorm-7.2.2 2016-03-22 09:46:58 +13:00
Robin Bygrave 90f786babd #610 - ManyToOne returns wrong ID value (prior ManyToOne with inheritance and null value). Regression introduced in 7.2.1. 2016-03-22 09:46:12 +13:00
Robin Bygrave 0d8146d453 [maven-release-plugin] prepare for next development iteration 2016-03-21 12:20:17 +13:00
Robin Bygrave 0eca613b41 [maven-release-plugin] prepare release avaje-ebeanorm-7.2.1 2016-03-21 12:19:57 +13:00
Robin Bygrave dcde54fca4 #100 - SQLITE (365) : ADD CONSTRAINT DDL SQLite Incompatibility 2016-03-21 11:06:52 +13:00
Robin Bygrave 49b8efbc30 #609 - SQLite DDL - disable use of comments and alter table add foreign key (as these are not supported by SQLite) 2016-03-21 10:31:57 +13:00
Robin Bygrave fc70161909 No effective change - bump SQLite jdbc driver for testing 2016-03-21 10:31:42 +13:00
Rob Bygrave 44ba6d3bb2 Merge pull request #608 from btimo/fixSQLiteDdl
SQLite Ddl : autoincrement attribute
2016-03-21 10:14:05 +13:00
Robin Bygrave d56e071f53 No effective change - javadoc only 2016-03-21 09:20:11 +13:00
Robin Bygrave ce33c230c7 No effective change - javadoc only 2016-03-21 08:43:33 +13:00
btimo 2da6a6960e - fix SQLiteDdl : https://www.sqlite.org/autoinc.html 2016-03-18 17:55:29 +01:00
Robin Bygrave 62f88c9e4f #607 - bool conversion for and(), or() and not() 2016-03-18 16:19:41 +13:00
Robin Bygrave 42f65ead47 #607 - must(), should(), mustNot() always mark setUseDocStore(true); 2016-03-18 16:17:32 +13:00
Robin Bygrave 8e98e88e8a #607 - Tidy "text" extensions to criteria API - remove endMust(), endShould(), endMustNot() ... just use endJunction() 2016-03-18 14:24:07 +13:00
Robin Bygrave 5de67e1939 #606 - Add not() as a junction expression (like and() and or()) to the query criteria API 2016-03-18 14:11:51 +13:00
Robin Bygrave 3ddd7099b5 #605 - Add and() and or() ... as synonyms for conjunction() and disjunction() ... to the "Query Criteria API" 2016-03-18 13:06:10 +13:00
Robin Bygrave 5d889790c2 No effective change - move related methods together 2016-03-18 12:53:15 +13:00
Robin Bygrave 636acc61e5 #594 ElasticSearch - Add match / TextExpression support - move expressions onto ExpressionList (remove TextExpressionList) 2016-03-18 12:51:39 +13:00
Robin Bygrave cb347ff5fa #602 - Elastic - Add support for ebean.docstore.generateMapping 2016-03-15 17:10:03 +13:00
Robin Bygrave db9d39ef61 #583 - MSSQL Server - Delete query syntax error, mssql does not like the table alias in the delete statement 2016-03-15 01:03:08 +13:00
Robin Bygrave 5216014d50 #601 - Second Nested filterMany not executed but joined 2016-03-14 23:54:34 +13:00
Robin Bygrave c40715733e #600 - Unique index or primary key violation - double insert attempted on ManyToMany intersection 2016-03-14 22:32:03 +13:00
Robin Bygrave 9bcc8a77fe No effective change - imports 2016-03-14 21:28:14 +13:00
Robin Bygrave 7be3a01823 No effective change - tidy up tests 2016-03-14 21:06:48 +13:00
Robin Bygrave 0ca4f92b26 #592 - Fetched empty collection of null child of parent entity 2016-03-14 20:10:07 +13:00
Robin Bygrave b99f002968 #599 - ElasticSearch - add query join support for find, findList, findPagedList, findEach, findEachWhile 2016-03-14 17:40:26 +13:00
Robin Bygrave fa451078b7 No effective change - cleanup imports 2016-03-11 21:56:11 +13:00
Robin Bygrave 49121a9c1f #595 - Refactor - persistence context root type handling - fully expect root type 2016-03-11 20:54:57 +13:00
Robin Bygrave 33f69902dc #595 - Refactor - persistence context root type handling - contextGet() and contextRef() 2016-03-11 20:26:03 +13:00
Robin Bygrave cf783fbbb7 #595 - Refactor - persistence context root type handling - AssocOne split simple and inherit 2016-03-11 19:40:02 +13:00
Robin Bygrave cf62ea4c2f #595 - Refactor - persistence context root type handling 2016-03-11 17:34:45 +13:00
Robin Bygrave 049bf76cc4 #594 - ElasticSearch - Add support for TextSimple, TextQueryString and TextCommon full text search expressions 2016-03-11 14:52:27 +13:00
Robin Bygrave 75a84af3f8 #594 - ElasticSearch - Use AbstractTextExpression 2016-03-10 11:30:42 +13:00
Robin Bygrave 93680f5d19 Bump agent to 4.9.2 2016-03-10 11:29:51 +13:00
Robin Bygrave faf7df1c69 #594 - ElasticSearch - multi match support 2016-03-09 23:44:23 +13:00
Robin Bygrave 34dcc98908 #594 - ElasticSearch - Add match / TextExpression support (Full text search expression) 2016-03-09 21:48:22 +13:00
Robin Bygrave 3c63b79324 #589 - ElasticSearch - Improve update notification when not mapped but has nested invalidation 2016-03-08 22:14:23 +13:00
Robin Bygrave 2d93d592c1 #593 - Refactor SPI - Move methods from ElPropertyValue to ExpressionPath 2016-03-08 21:34:27 +13:00
Robin Bygrave 57836af5b5 #593 - Refactor SPI - Move methods from ElPropertyValue to ExpressionPath 2016-03-08 21:21:46 +13:00
Robin Bygrave ba871d6684 #593 - Refactor SPI - Move methods from ElPropertyValue to ExpressionPath 2016-03-08 21:09:49 +13:00
Robin Bygrave 583fc11945 #593 - Refactor SPI - Move methods from ElPropertyValue to ExpressionPath 2016-03-08 21:02:39 +13:00
Robin Bygrave 3ba4660bbb No effective change - format code 2016-03-08 18:33:32 +13:00
Robin Bygrave 37b86f2191 #589 - ElasticSearch - refactor to DocQueryContext 2016-03-08 00:00:02 +13:00
Robin Bygrave da8766533f #589 - ElasticSearch - extend mapping options 2016-03-07 22:00:41 +13:00
Robin Bygrave ae31117b8f #590 - Refactor internals - Remove duplicate isBatch() logic in JdbcTransaction 2016-03-07 19:23:50 +13:00
Robin Bygrave cf825f7ac4 #589 - ElasticSearch, Transaction - rename DocStoreMode and batch size methods 2016-03-07 19:15:08 +13:00
Robin Bygrave a0609b1726 #589 - ElasticSearch - DocStoreMode renamed from DocStoreEvent 2016-03-07 19:10:15 +13:00
Robin Bygrave 32bcd5e853 #589 - ElasticSearch - JsonReader given BeanType 2016-03-07 16:27:16 +13:00
Robin Bygrave f082fce1ff Bump pom to 7.2.1-SNAPSHOT 2016-03-07 16:26:18 +13:00
Robin Bygrave 7fc58a1842 #589 - ElasticSearch - DocStoreConfig ... mapping path, suffix, resources 2016-03-07 14:21:09 +13:00
Robin Bygrave f2ffbb2c5b #589 - ElasticSearch - Add copyIndex() via Query, Add findEachWhile() 2016-03-07 13:49:23 +13:00
Robin Bygrave 5c0fb7c8cd #584 - ElasticSearch: Internal changes - Enum and UUID tests 2016-03-04 00:04:58 +13:00
Robin Bygrave 04c9db1e42 #586 - Refactor the UUID ScalarTypes (Native, Varchar and Binary) to have a common base 2016-03-04 00:00:05 +13:00
Robin Bygrave 8f7de950e2 No effective change - reformat, early check for UUID type 2016-03-03 23:56:30 +13:00
Robin Bygrave 53dd810b9a #587 - Refactor - Change JsonContext.getScalar() to JsonContext.writeScalar() 2016-03-03 23:38:09 +13:00
Robin Bygrave 290ca6ba90 #586 - Refactor the UUID ScalarTypes (Native, Varchar and Binary) to have a common base 2016-03-03 22:10:28 +13:00
Robin Bygrave 992f5797a7 #586 - Refactor the UUID ScalarTypes (Native, Varchar and Binary) to have a common base 2016-03-03 22:10:04 +13:00
Robin Bygrave 798976fbd2 #585 - Refactor of ScalarType jsonWrite() method such that it only takes JsonGenerator - part 4, tidy up 2016-03-03 21:39:10 +13:00
Robin Bygrave c315067ff0 #585 - Refactor of ScalarType jsonWrite() method such that it only takes JsonGenerator - part 3, remove JsonToken from jsonRead() 2016-03-03 21:06:09 +13:00
Robin Bygrave a4f0e3936a #585 - Refactor of ScalarType jsonWrite() method such that it only takes JsonGenerator - part 2, use JsonGenerator 2016-03-03 20:27:13 +13:00
Robin Bygrave fc96685ed0 #585 - Refactor of ScalarType jsonWrite() method such that it only takes JsonGenerator - part 1, remove field name 2016-03-03 19:51:07 +13:00
Robin Bygrave 5b10d06348 #584 - ElasticSearch: Internal changes for config, expressions and JSON conversion 2016-03-03 17:46:32 +13:00
Robin Bygrave ca73eff519 #582 - ElasticSearch: Add setUseDocStore(true) on ExpressionList ... for fluid query style 2016-03-02 23:25:58 +13:00
Robin Bygrave 646de50ae8 #581 - ElasticSearch - DocStoreConfig, read dropCreate not read from properties file 2016-03-02 23:22:13 +13:00
Robin Bygrave e2558a1e24 #578 - Deprecated Joda Time API - LocalDate.toDateMidnight() usage causes exception to be thrown, change to LocalDate.toDateTimeAtStartOfDay() 2016-03-02 08:12:53 +13:00
Robin Bygrave ad596a2043 #580 - @Enumerated(EnumType.STRING) on Enum uses toString() rather than name() 2016-03-01 17:35:55 +13:00
Robin Bygrave 0a60cd4e58 [maven-release-plugin] prepare for next development iteration 2016-03-01 16:17:14 +13:00
Robin Bygrave ec38137e5c [maven-release-plugin] prepare release avaje-ebeanorm-7.1.1 2016-03-01 16:16:53 +13:00
Robin Bygrave bfcbd335c8 Reduce logging via logback-test.xml for CI etc 2016-03-01 16:14:31 +13:00
Robin Bygrave 2cafdf709d bump pom to 7.1.1-SNAPSHOT 2016-03-01 16:12:40 +13:00
Robin Bygrave ed2ea13deb #578 - Deprecated Joda Time API - LocalDate.toDateMidnight() usage causes exception to be thrown, change to LocalDate.toDateTimeAtStartOfDay() 2016-03-01 16:09:57 +13:00
Robin Bygrave 8d3b4a0407 #304 - ElasticSearch integration part 1 / doc store integration 2016-03-01 15:36:44 +13:00
Robin Bygrave cb1fe297d6 #579 - Postgres History DDL - Revert of #544 such that Postgres @History DB trigger uses current_timestamp (transaction start time) 2016-03-01 13:15:19 +13:00
Robin Bygrave 6561c118ec #575 - Refactor PathProperties, extract FetchPath interface, rename get(path) -> getProperties(path) 2016-02-29 10:22:59 +13:00
Robin Bygrave eda7fe24c1 #576 - DateTimeJsonParser error when date time has no millisecond precision -java.text.ParseException: Unparseable date: "2016-02-28T20:39:00Z" 2016-02-29 10:14:17 +13:00
Robin Bygrave 2353049c6f #574 - Refactor - rename .plugin objects; SpiBeanType -> BeanType and SpiServerPlugin -> Plugin 2016-02-29 09:19:44 +13:00
Robin Bygrave 6c49ac0857 [maven-release-plugin] prepare for next development iteration 2016-02-17 21:50:48 +13:00
Robin Bygrave 76033385dc [maven-release-plugin] prepare release avaje-ebeanorm-6.18.1 2016-02-17 21:50:22 +13:00
Robin Bygrave b61cd30e29 Bump pom to 6.18.1-SNAPSHOT 2016-02-17 21:49:07 +13:00
Robin Bygrave 18edaf877b #420 - Review JodaLocalTime (being stored and fetched using UTC) 2016-02-17 21:36:47 +13:00
Robin Bygrave f055a0d0cb #420 - Review JodaLocalTime (being stored and fetched using UTC) 2016-02-17 21:34:52 +13:00
Robin Bygrave a22574b0c9 #552 - wrong DDL generation with complex columnDefinition 2016-02-17 20:34:13 +13:00
Robin Bygrave 3130f751f5 Merge branch 'refactor-query-hash' 2016-02-17 19:45:01 +13:00
Robin Bygrave c83606c1da #566 - Refactor internals - SpiQuerySecondary and DLoadContext 2016-02-17 19:44:30 +13:00
Robin Bygrave 439858b259 #566 - Refactor internals -OrmQueryDetailProperties - remove hasProperties() 2016-02-17 16:53:32 +13:00
Robin Bygrave 3d3948aa8b #566 - Refactor internals - OrmQueryDetail, skip fetch path sort when empty 2016-02-17 16:47:38 +13:00
Robin Bygrave 27045baf44 #566 - Refactor internals - OrmQueryDetailProperties with final FetchConfig 2016-02-17 16:33:38 +13:00
Robin Bygrave 5c6d6608ef #566 - Refactor internals - Initial tidy on OrmQueryDetail and OrmQueryDetailProperties - internals for fetch paths etc 2016-02-17 13:59:48 +13:00
Robin Bygrave 2fcaab44c6 #566 - Refactor internals - Initial tidy on OrmQueryDetail and OrmQueryDetailProperties 2016-02-17 10:52:55 +13:00
Robin Bygrave 69bf1758bc #566 - Refactor internals - SpiExpression, add prepareExpression() to merge queryAutoTuneHash() and queryPlanHash() - tidy up OrmQueryRequest 2016-02-16 17:07:56 +13:00
Robin Bygrave af554410fd #566 - Refactor internals - SpiExpression, add prepareExpression() to merge queryAutoTuneHash() and queryPlanHash() - tidy up OrmQueryDetail 2016-02-16 16:10:39 +13:00
Robin Bygrave ae7827c483 #566 - Refactor internals - SpiExpression, add prepareExpression() to merge queryAutoTuneHash() and queryPlanHash() - tidy up createQueryRequest - part 2 2016-02-16 09:21:10 +13:00
Robin Bygrave 4df2d4020e #566 - Refactor internals - SpiExpression, add prepareExpression() to merge queryAutoTuneHash() and queryPlanHash() - tidy up createQueryRequest 2016-02-16 08:57:12 +13:00
Robin Bygrave 1aeffd31e0 #566 - Refactor internals - SpiExpression, add prepareExpression() to merge queryAutoTuneHash() and queryPlanHash() - no effective change, reorder methods 2016-02-16 01:46:12 +13:00
Robin Bygrave 5c59066ff8 #566 - Refactor internals - SpiExpression, add prepareExpression() to merge queryAutoTuneHash() and queryPlanHash() - rawSql key 2016-02-16 01:06:30 +13:00
Robin Bygrave a2bf8a0e46 [maven-release-plugin] prepare for next development iteration 2016-02-15 23:49:34 +13:00
Robin Bygrave 3ef77ea410 [maven-release-plugin] prepare release avaje-ebeanorm-6.17.3 2016-02-15 23:49:08 +13:00
Robin Bygrave fe2c2e5331 #566 - Refactor internals - SpiExpression, add prepareExpression() to merge queryAutoTuneHash() and queryPlanHash() - sameByPlan() & sameByBind() 2016-02-15 23:46:28 +13:00
Robin Bygrave 3d91a4f927 #566 - Refactor internals - SpiExpression, add prepareExpression() to merge queryAutoTuneHash() and queryPlanHash() - sameByPlan() & sameByBind() 2016-02-15 23:44:56 +13:00
Robin Bygrave 165d4aca92 #566 - Refactor internals - SpiExpression, add prepareExpression() to merge queryAutoTuneHash() and queryPlanHash() - remove unused 2016-02-15 10:21:22 +13:00
Robin Bygrave 076f8a03b9 #566 - Refactor internals - SpiExpression, add prepareExpression() to merge queryAutoTuneHash() and queryPlanHash() - move to protected calculateQueryPlanHash() 2016-02-13 21:22:52 +13:00
Robin Bygrave ca944eb756 #566 - Refactor internals - SpiExpression, add prepareExpression() to merge queryAutoTuneHash() and queryPlanHash() - refactor InQuery and Exists query 2016-02-13 20:52:41 +13:00
Robin Bygrave 769e4bb488 #566 - Refactor internals - SpiExpression, add prepareExpression() to merge queryAutoTuneHash() and queryPlanHash() - initial 2016-02-13 20:13:16 +13:00
Robin Bygrave 0d456b2ad6 Update TestOrderByFetch for running in Postgres ... by adding a 'name' property to the beans so that there is at least one property in the inserts 2016-02-13 13:09:41 +13:00
Robin Bygrave 39e913cbe2 #565 - Query plan hash collision on firstRow/maxRows combinations - change prime 2016-02-13 12:30:31 +13:00
Robin Bygrave ae38672e02 #565 - Query plan hash collision on firstRow/maxRows combinations - tests 2016-02-13 12:30:00 +13:00
Robin Bygrave 8a8b36ec1e #462 - When fetching, collections can get populated with too many entities - Fix 2016-02-13 00:43:47 +13:00
Robin Bygrave 62aca1e77b #462 - When fetching, collections can get populated with too many entities - Fix 2016-02-12 23:33:17 +13:00
Robin Bygrave f0b80068b6 #462 - No effective change, reformat code ... When fetching, collections can get populated with too many entities - 2016-02-12 23:32:43 +13:00
Rob Bygrave 5721fe3807 Merge pull request #560 from nedap/master
Add test for broken fetching issue #462
2016-02-12 21:58:35 +13:00
Robin Bygrave afffb88a29 [maven-release-plugin] prepare for next development iteration 2016-02-12 21:51:59 +13:00
Robin Bygrave 4c3a125192 [maven-release-plugin] prepare release avaje-ebeanorm-6.17.2 2016-02-12 21:51:37 +13:00
Robin Bygrave f8804f8d18 #564 - DDL DB Migration - migration generation on history table, pending drop columns missing in the history view and tigger 2016-02-12 21:28:19 +13:00
Robin Bygrave 4848c24a0a #563 - ENH: DDL DB Migration - add a suppressDropsForever="true" attribute such that drops we never want to run are not warned on and can't be selected for a migration. 2016-02-12 14:33:19 +13:00
Robin Bygrave 4c3d1d9edd #561 - DDL DB Migration - change "ddl.migration.pendingDrop" to "ddl.migration.pendingDropsFor" 2016-02-12 11:04:25 +13:00
Pieter Bos 42b112c3d7 Add test for broken fetching issue #462 2016-02-11 17:00:39 +01:00
Robin Bygrave 59996da07a [maven-release-plugin] prepare for next development iteration 2016-02-11 22:43:53 +13:00
Robin Bygrave 32d4b83a86 [maven-release-plugin] prepare release avaje-ebeanorm-6.17.1 2016-02-11 22:43:22 +13:00
Robin Bygrave ca824c5e0d Refactor / fix .gitignore of test resources 2016-02-11 22:33:25 +13:00
Robin Bygrave b2f7664316 Bump pom to 6.17.1-SNAPSHOT 2016-02-11 22:20:17 +13:00
Robin Bygrave 062f7a281f #559 - DDL - DB Migration refactor - remove rollback.ddl generation (ultimately not used by FlywayDb etc) 2016-02-11 22:17:35 +13:00
Robin Bygrave 019ce4e614 #558 - Internal refactor - MTable pending dropped columns 2016-02-11 20:43:45 +13:00
Robin Bygrave 6b490ed8b1 #557 - DDL - DB Migration refactor - remove drop.ddl and use pendingDrops. 2016-02-11 20:26:53 +13:00
Robin Bygrave 1bee6fcae5 #557 - DDL - DB Migration refactor - remove drop.ddl and use pendingDrops. 2016-02-11 20:15:49 +13:00
Robin Bygrave 097552b8d3 [maven-release-plugin] prepare for next development iteration 2016-02-10 20:53:52 +13:00
Robin Bygrave 9fbfca5f73 [maven-release-plugin] prepare release avaje-ebeanorm-6.16.5 2016-02-10 20:53:29 +13:00
Robin Bygrave 9e70ba915f #556 - DDL - DB Migration for History - change treatment of dropped columns such that they are still included in apply script 2016-02-10 16:05:59 +13:00
Robin Bygrave a1a5dcd035 #556 - DDL - DB Migration for History - change treatment of dropped columns such that they are still included in apply script 2016-02-10 16:04:46 +13:00
Robin Bygrave d2b048b0b4 No effective change - reformat code 2016-02-09 14:51:26 +13:00
Robin Bygrave 4272c17689 #555 - Use a common timestamp value for @WhenCreated and @WhenModified 2016-02-09 14:48:41 +13:00
Robin Bygrave 11723e3a32 #554 - DDL - DB Migration with @History and Postgres - views need to be dropped early to support migration changes 2016-02-05 11:54:52 +13:00
Robin Bygrave 237cdcdd3d #554 - DDL - DB Migration with @History and Postgres - views need to be dropped early to support migration changes 2016-02-05 11:52:06 +13:00
Robin Bygrave e96bee74ae [maven-release-plugin] prepare for next development iteration 2016-02-05 00:15:30 +13:00
Robin Bygrave c8b57c3302 [maven-release-plugin] prepare release avaje-ebeanorm-6.16.4 2016-02-05 00:15:04 +13:00
Robin Bygrave f65ea96b89 #553 - DDL - DB Migration with @History and Postgres needs to re-create the "with_history" view when columns dropped 2016-02-05 00:11:25 +13:00
Robin Bygrave a1bd0b469a #551 - DDL - DB Migration with @History and @Draftable - @DraftOnly columns added when not part of change 2016-02-04 22:31:07 +13:00
Robin Bygrave fd5563e3da No effective change - javadoc update for RawSql tableAliasMapping 2016-02-02 15:35:31 +13:00
Robin Bygrave f9156ede55 No effective change - add tests for RawSql tableAlias mapping of root type to null path and not mapping it 2016-02-02 14:58:59 +13:00
Robin Bygrave 10d2d591db [maven-release-plugin] prepare for next development iteration 2016-02-02 13:38:09 +13:00
Robin Bygrave 998d8ed6f2 [maven-release-plugin] prepare release avaje-ebeanorm-6.16.3 2016-02-02 13:37:46 +13:00
Robin Bygrave a8da472872 #550 - ENH: Add generated file warning to DB migration XML files 2016-02-02 13:33:46 +13:00
Robin Bygrave a9cdf9736a Bump maven plugin version to 4.9.1 2016-02-02 13:23:46 +13:00
Robin Bygrave c930a1dd6b #549 - Regression: ArrayIndexOutOfBoundsException when lazy loading on bean with inheritance - tidy up 2016-02-02 11:29:38 +13:00
Robin Bygrave 67ce6ef58e #549 - Regression: ArrayIndexOutOfBoundsException when lazy loading on bean with inheritance 2016-02-02 11:24:46 +13:00
Robin Bygrave c4f28efc45 Testing CI - .travis - git depth + skip mvn install 2016-01-28 10:54:16 +13:00
Robin Bygrave afa4bc06d9 Testing CI - .travis - try setup_database 2016-01-28 10:44:14 +13:00
Robin Bygrave 828c9ce128 Testing CI - .travis - try sudo required 2016-01-28 09:31:18 +13:00
Robin Bygrave 6f37a0bd72 Testing CI - .travis - print surefire reports + setup_database script 2016-01-28 09:20:27 +13:00
Robin Bygrave 036086af02 Testing CI - .travis - print surefire reports on failure 2016-01-28 09:00:44 +13:00
Robin Bygrave f34b5e52e0 [maven-release-plugin] prepare for next development iteration 2016-01-28 08:36:40 +13:00
Robin Bygrave a70e289b00 [maven-release-plugin] prepare release avaje-ebeanorm-6.16.2 2016-01-28 08:36:18 +13:00
Robin Bygrave 4ad0e06aab Testing CI - TestEncrypt change to only run against H2 for now 2016-01-27 22:53:06 +13:00
Robin Bygrave 86de7e845e Testing CI - add sql logging for TestEncrypt run on CI server 2016-01-27 22:39:03 +13:00
Robin Bygrave 38501ca372 Modify .travis.yml - add postgres pgcrypto extension 2016-01-27 22:15:39 +13:00
Robin Bygrave 4790c83fa1 Modify .travis.yml - cache .m2 directory 2016-01-27 21:56:00 +13:00
Robin Bygrave b410c83492 Modify .travis.yml for postgres - add hstore and postgis extensions 2016-01-27 21:50:43 +13:00
Robin Bygrave b19145f16f Modify .travis.yml for postgres - add hstore and postgis extensions 2016-01-27 21:46:30 +13:00
Robin Bygrave c28cff2f40 Modify .travis.yml for h2 and postgres runs using EBEAN_DB environment variable 2016-01-27 21:37:57 +13:00
Robin Bygrave 0c8cf78ecc Modify .travis.yml for h2 and postgres runs using EBEAN_DB environment variable 2016-01-27 21:21:01 +13:00
Robin Bygrave df112815ff #545 - ENH: Read environment variable "EBEAN_DB" to set default datasource - typically for CI builds 2016-01-27 21:20:13 +13:00
Robin Bygrave 85522ed8bc Modify .travis.yml for h2 and postgres runs 2016-01-27 20:39:53 +13:00
Robin Bygrave cf88f2375b #544 - Postgres @History DB trigger using current_timestamp (transaction) and should instead use statement_timestamp() 2016-01-27 20:34:51 +13:00
Robin Bygrave 24151f11fd #543 - Tidy up test logging - adjust test LoggedSqlCollector - remove logging noise when running tests 2016-01-27 20:12:36 +13:00
Robin Bygrave 424a83fa0a #543 - Tidy up test logging - adjust test LoggedSqlCollector - remove logging noise when running tests 2016-01-27 19:10:52 +13:00
Robin Bygrave 53dd91416c #543 - Tidy up test logging - adjust test LoggedSqlCollector - remove logging noise when running tests 2016-01-27 19:05:19 +13:00
Robin Bygrave 5a463c5071 #543 - Tidy up test logging - adjust test LoggedSqlCollector - remove trace level logging when running tests 2016-01-27 18:25:54 +13:00
Robin Bygrave bc3cf1348a #543 - Tidy up test logging - adjust test LoggedSqlCollector 2016-01-27 18:25:16 +13:00
Robin Bygrave f3b1024283 Fix for test asserts to run against Postgres with escape clause on LIKE expression 2016-01-27 17:22:55 +13:00
Robin Bygrave 7ba35d7a62 Update .travis - postgres service 2016-01-27 16:17:45 +13:00
Robin Bygrave 990ca2980b Add initial .travis.yml 2016-01-27 16:05:33 +13:00
Robin Bygrave 38dd3d82fc #536 - @ManyToOne with @JoinColumn throw error - Update tests 2016-01-26 16:41:15 +13:00
Robin Bygrave 6be26aaff2 #537 - Change PersistenceException: Mapping limitation on @JoinColumn such that it includes the bean type 2016-01-26 15:30:57 +13:00
Robin Bygrave d1462b032a #535 - Bean lazy loading can execute an extra query when one of the lazy loaded beans has been deleted 2016-01-21 20:51:45 +13:00
Robin Bygrave 6ab974a330 #535 - Bean lazy loading can execute an extra query when one of the lazy loaded beans has been deleted 2016-01-21 20:51:32 +13:00
Robin Bygrave 64618da6a7 #534 - REFACTOR: Internals for lazy loading specifically improving errors/logging in cases of lazy load errors due to deletes - Update debug logging for LoadManyRequest when empty collection found (expected frequently) 2016-01-21 17:52:23 +13:00
Robin Bygrave d242ff7351 #534 - REFACTOR: Internals for lazy loading specifically improving errors/logging in cases of lazy load errors due to deletes - Initial refactor for LoadManyRequest 2016-01-21 17:30:49 +13:00
Robin Bygrave 7d54aaa9a7 #534 - REFACTOR: Internals for lazy loading specifically improving errors/logging in cases of lazy load errors due to deletes - Initial refactor 2016-01-21 16:50:51 +13:00
Robin Bygrave 0e46184656 No effective change - Rename test class 2016-01-21 16:03:51 +13:00
Robin Bygrave c9e1a6edbd Bump agent to 4.9.1 2016-01-20 15:13:11 +13:00
Robin Bygrave 3c0cffd146 [maven-release-plugin] prepare for next development iteration 2016-01-19 19:49:31 +13:00
Robin Bygrave d31547fb69 [maven-release-plugin] prepare release avaje-ebeanorm-6.16.1 2016-01-19 19:49:08 +13:00
Robin Bygrave 93adaa12bc Bump pom to 6.16.1-SNAPSHOT 2016-01-19 19:48:22 +13:00
Robin Bygrave d1cdbe94de #529 - @OneToOne with @JoinColumn to non primary key throws Data conversion error 2016-01-19 19:46:41 +13:00
Robin Bygrave e7c6223799 #530 - Bad join with raw() expression on a @ManyToMany path. 2016-01-19 13:18:28 +13:00
Robin Bygrave d33afd85de #533 - DDL - Invalid foreign key constraint name for @ManyToMany when using explicit schema in @Table - Temp testing removed 2016-01-19 10:01:04 +13:00
Robin Bygrave 77bcb4aef9 #533 - DDL - Invalid foreign key constraint name for @ManyToMany when using explicit schema in @Table - Temp testing 2016-01-19 09:57:49 +13:00
Robin Bygrave a70fe184c2 #533 - DDL - Invalid foreign key constraint name for @ManyToMany when using explicit schema in @Table - Fix 2016-01-19 09:56:27 +13:00
Robin Bygrave 7238f39be5 #531 - AutoTune - On shutdown provide ability to saving profiling without garbage collection 2016-01-19 08:16:17 +13:00
Robin Bygrave ae44b59c5f #532 - Change example expression such that it supports nested beans 2016-01-18 23:52:28 +13:00
Robin Bygrave ced4e71307 [maven-release-plugin] prepare for next development iteration 2016-01-13 16:13:59 +13:00
Robin Bygrave 9cb43bd5dd [maven-release-plugin] prepare release avaje-ebeanorm-6.15.2 2016-01-13 16:13:30 +13:00
Robin Bygrave 9665de2dbe #502 - jsonContext.toJson(o, generator, path) can not apply path on @Transient field that is an entity bean 2016-01-13 13:29:06 +13:00
Robin Bygrave e2666f0c4c No effective change - turn off autotune profiling/tuning flags for test running 2016-01-13 12:38:04 +13:00
Robin Bygrave 89c83c90d1 No effective change - add test to show findRowCount with joins 2016-01-13 12:35:52 +13:00
Robin Bygrave cdd25351a6 No effective change - test code static imports 2016-01-13 11:40:23 +13:00
Robin Bygrave 17e0413837 No effective change - code format 2016-01-13 11:38:53 +13:00
Robin Bygrave b04419d9c7 #527 - @OrderBy on child-of-child property 2016-01-13 11:37:38 +13:00
Robin Bygrave 0453892ebd #526 - findPagedList with @EmbeddedId broken - automatically adds orderby t0.null 2016-01-13 10:43:56 +13:00
Robin Bygrave 55493c5b7d #524 - ExplicitJdbcTransaction leaves dangling “begin” - comment update 2016-01-13 00:17:22 +13:00
Robin Bygrave eb2f7cd852 #525 - Automatic autotune data 2016-01-13 00:08:00 +13:00
Robin Bygrave f44eb234c8 #525 - Automatic autotune data - initial wip 2016-01-12 11:45:24 +13:00
Robin Bygrave 404b57ab21 #524 - ExplicitJdbcTransaction leaves dangling “begin” - expected fix 2016-01-12 08:37:12 +13:00
Robin Bygrave a54f09ca4b #524 - ExplicitJdbcTransaction leaves dangling “begin” - expected fix 2016-01-11 14:04:14 +13:00
Robin Bygrave a3bb909308 [maven-release-plugin] prepare for next development iteration 2016-01-08 00:22:06 +13:00
Robin Bygrave 7eb443859e [maven-release-plugin] prepare release avaje-ebeanorm-6.15.1 2016-01-08 00:21:44 +13:00
Robin Bygrave 8b39788ae3 Bump pom to 6.15.1-SNAPSHOT 2016-01-08 00:20:27 +13:00
Robin Bygrave 1ec132b7dd #508 - Upgrading to 6.13.5 causes "No suitable driver found for jdbc:mysql" error 2016-01-08 00:18:20 +13:00
Robin Bygrave 343a975073 #520 - SPI - Deprecate SpiEbeanPlugin in favor of SpiServerPlugin. - Deprecate SpiEbeanPlugin 2016-01-07 23:24:57 +13:00
Robin Bygrave 944f7bd086 #520 - SPI - Deprecate SpiEbeanPlugin in favor of SpiServerPlugin. - Add ServiceLoading for SpiServerPlugin 2016-01-07 16:45:24 +13:00
Robin Bygrave 3639c2a540 #518 - Refactor: Remove getDdlGenerator() from SpiEbeanServer. 2016-01-07 14:27:27 +13:00
Robin Bygrave a9cc8ed702 #517 - Refactor DdlGenerator such that it is not an SpiEbeanPlugin 2016-01-07 14:22:37 +13:00
Robin Bygrave 0351a15067 #516 - DdlParser for seed and init sql is not ignoring sql comment lines (starting with --) 2016-01-07 14:03:17 +13:00
Robin Bygrave c7300a1707 #246 - ENH: Add ebean.ddl.initsql=.... to support executing a sql script prior to running the create all DDL - was - When the scripts generates the evolution, it should generate the create schema too. 2016-01-07 13:12:43 +13:00
Robin Bygrave c48008c4b2 #515 - ENH: Add ebean.ddl.seedSql=xxx.sql ... such that a sql script will execute to insert seed data typically for testing 2016-01-07 12:48:55 +13:00
Robin Bygrave e5d8804591 #514 - ENH: Add ebean.ddl.createOnly=true ... such that all the drop table statements are skipped (for running tests against H2 usually) 2016-01-07 10:06:35 +13:00
Robin Bygrave f6dc294bc2 No effective change - update public project url in pom 2016-01-05 21:38:25 +13:00
Robin Bygrave 692baf8bb6 [maven-release-plugin] prepare for next development iteration 2016-01-05 21:28:03 +13:00
Robin Bygrave e1c00f3856 [maven-release-plugin] prepare release avaje-ebeanorm-6.14.1 2016-01-05 21:27:41 +13:00
Robin Bygrave cf173d0695 Bump pom to 6.14.1-SNAPSHOT 2016-01-05 21:26:20 +13:00
Robin Bygrave a3798c6ca3 #506 - Changes to DB Migration, support run on startup and external version numbering - suffix/subdirectory refactor 2016-01-05 21:25:07 +13:00
Robin Bygrave 7bcf1da823 #506 - Changes to DB Migration, support run on startup and external version numbering - suffix/subdirectory refactor 2016-01-05 21:21:16 +13:00
Rob Bygrave 2ccd8dabeb Merge pull request #510 from apuckey/master
Added support for custom database functions that have multiple arguments
2016-01-05 10:25:19 +13:00
Robin Bygrave f9800dd59e #509 - ExpressList.notIn method does not work 2016-01-05 09:11:14 +13:00
Robin Bygrave fb3e8b9fc4 #511 - PagedList getTotalRowCount() includes soft deleted rows in its count 2016-01-05 07:37:17 +13:00
Antony Puckey 18be5989c7 Added support for custom database functions that have multiple arguments
seperated by commas inside brackets.
2015-12-29 11:06:22 +10:00
Robin Bygrave be91e3f3f7 #506 - Changes to DB Migration, support run on startup and external version numbering 2015-12-24 16:41:06 +13:00
Robin Bygrave 03a9aa3dec #507 - PropertiesWrapper support null enum values with getEnum() 2015-12-24 15:23:25 +13:00
Robin Bygrave a2a301beda No effective change - remove commented out lines 2015-12-23 09:13:31 +13:00
Robin Bygrave 695e4f653b No effective change - typo in comment 2015-12-23 07:38:58 +13:00
Robin Bygrave e84c75929c #505 - Remove unused method - EntityBean._ebean_createCopy(); 2015-12-22 17:04:51 +13:00
Robin Bygrave 7592178b6b No effective change - update tests to ensure query does not hit L2 cache 2015-12-22 17:02:35 +13:00
Robin Bygrave 70d65b734f #504 - @Draft treated as transient such that it doesn't invoke lazy loading in 4.8.1 enhancement agent 2015-12-22 16:48:42 +13:00
Robin Bygrave f9a3dfeda0 #503 - @DraftDirty should be marked as not null automatically 2015-12-22 07:52:05 +13:00
Robin Bygrave eb85931fe2 #500 - Change raw(String, Object[]) expression to varargs raw(String, Object...) 2015-12-16 08:11:32 +13:00
Robin Bygrave 1745334737 No effective change - add extra test 2015-12-16 08:06:12 +13:00
Robin Bygrave ea92ddfd89 [maven-release-plugin] prepare for next development iteration 2015-12-15 15:46:21 +13:00
Robin Bygrave 3400928798 [maven-release-plugin] prepare release avaje-ebeanorm-6.13.5 2015-12-15 15:45:55 +13:00
Robin Bygrave 4e665fd66f #499 - DDL issue for entity bean that is both @Draftable with @History - draft only columns included in history table 2015-12-15 15:44:22 +13:00
Robin Bygrave 09cd2c12e2 Add tests for @Draftable from example application 2015-12-15 15:25:19 +13:00
Robin Bygrave e3e45929f0 #498 - @Draftable - lazy loading after stateless update results in - EntityNotFoundException: Bean not found during lazy load or refresh 2015-12-15 15:15:20 +13:00
Robin Bygrave 2caeafaaa2 #498 - @Draftable - lazy loading after stateless update results in - EntityNotFoundException: Bean not found during lazy load or refresh 2015-12-15 14:38:39 +13:00
Robin Bygrave 5cd21de174 #496 - @EnumValue is being trimmed, may result in unexpected behaviour with CHAR columns for some database systems 2015-12-14 17:21:01 +13:00
Robin Bygrave 78df595861 [maven-release-plugin] prepare for next development iteration 2015-12-11 10:28:21 +13:00
Robin Bygrave 3c89a0537f [maven-release-plugin] prepare release avaje-ebeanorm-6.13.4 2015-12-11 10:28:01 +13:00
Robin Bygrave 282463c2e8 #247 - @AttributeOverride at class level not read - was: @AttributeOverride annotation does not seem to work (Play 2.2.0 - ebean 3.2.2) 2015-12-11 10:23:34 +13:00
Robin Bygrave 03bb7a4aaf #494 - ENH: Support findPagingList() ... that uses firstRow & maxRows (rather than pageIndex, pageSize) 2015-12-11 10:20:53 +13:00
Robin Bygrave e4fa031cd3 #494 - ENH: Support findPagingList() ... that uses firstRow & maxRows (rather than pageIndex, pageSize) 2015-12-10 14:52:27 +13:00
Robin Bygrave 00d227c598 #491 - RawSqlParser doesn't seem to understand new lines directly after the SELECT keyword 2015-12-09 17:24:58 +13:00
Robin Bygrave fb86cb91bc #492 - MS Sql Server DDL - Fix for drop constraint syntax (remove extra IF EXISTS) and ignore table and column comments 2015-12-09 16:59:51 +13:00
Robin Bygrave f11ee20b73 #365 - ENH: Add @DbComment with DDL generation of table and column comments 2015-12-09 16:56:29 +13:00
Robin Bygrave 3665c5bfaf No effective change - adjust test connection properties for sql server 2015-12-09 16:53:26 +13:00
Robin Bygrave 638446680c #365 - ENH: Add @DbComment with DDL generation of table and column comments 2015-12-09 16:52:58 +13:00
Robin Bygrave bd9bfa25be No effective change - rename test property from 'top' as that is ms sql server keyword 2015-12-09 16:49:35 +13:00
Robin Bygrave 753d17a8d2 [maven-release-plugin] prepare for next development iteration 2015-12-09 12:46:40 +13:00
Robin Bygrave f5cfce3f44 [maven-release-plugin] prepare release avaje-ebeanorm-6.13.3 2015-12-09 12:46:18 +13:00
Robin Bygrave 1c6363e85c #490 - Invalid SQL for generating ID from sequence on DB2 2015-12-09 12:44:27 +13:00
Robin Bygrave b8bcbd8af9 #489 - @Draftable - insert does not set 'draft' to true ... so subsequent update fails 2015-12-09 11:06:48 +13:00
Robin Bygrave d70768277b #488 - BeanPropertyAssocManyJsonHelp error when Jackson not in classPath 2015-12-09 11:00:21 +13:00
Robin Bygrave b39b4a2e8c #487 - DDL - @SoftDelete deleted column should have NOT NULL constraint in create table DDL 2015-12-09 10:27:04 +13:00
Robin Bygrave 93b2f4035c #485 - @SoftDelete with join to nullable relation (optional @ManyToOne for example) ... will incorrectly filter out row from result when FK value is null. 2015-12-09 10:12:25 +13:00
Robin Bygrave 31ee0c4582 #486 - Postgres DDL - Add "if exists" to alter table [if exists] drop constraint if exists .... 2015-12-09 10:06:03 +13:00
Robin Bygrave 6c2dad4851 [maven-release-plugin] prepare for next development iteration 2015-12-07 22:20:54 +13:00
Robin Bygrave ed190ede03 [maven-release-plugin] prepare release avaje-ebeanorm-6.13.2 2015-12-07 22:20:25 +13:00
Robin Bygrave f252b80c2d #476 - ENH: Enable ServiceConfig to use alternate ClassLoader - was ServiceConfig add setClassloader api --- part 3: Refactor with ClassLoadConfig 2015-12-07 22:13:27 +13:00
Robin Bygrave 2859ea657e #484 - JDBC4+ drivers do not need Class.forName() registration - removing that call 2015-12-07 21:02:00 +13:00
Robin Bygrave 664b1cbd75 #476 - ENH: Enable ServiceConfig to use alternate ClassLoader - was ServiceConfig add setClassloader api --- part 2 : Use current context classLoader 2015-12-07 17:41:56 +13:00
Robin Bygrave 8bc283fef4 #476 - ENH: Enable ServiceConfig to use alternate ClassLoader - was ServiceConfig add setClassloader api --- part 1 : protected methods 2015-12-07 17:37:59 +13:00
Robin Bygrave 7d85398139 #483 - ENH: Draftable - Add FK from live table back to draft table (for top level @Draftable tables) 2015-12-07 15:21:22 +13:00
Robin Bygrave f42be3d65a #482 - ENH: @Draftable - Save or update is not allowed on a 'live' bean - only draft beans ... add this check when @Draft property is used 2015-12-07 12:09:10 +13:00
Robin Bygrave ff8e5af4e5 #481 - ENH: @Draftable ... add support for transient @Draft boolean draft; property ... used to distinguish a 'live' instance from a 'draft' instance. 2015-12-07 11:11:22 +13:00
Robin Bygrave 526d67eeb4 No effective change - whitespace 2015-12-07 11:02:32 +13:00
Robin Bygrave 374fc8d702 #480 - @History trigger on @Draftable does not exclude the @DraftOnly and @DraftDirty properties - ERROR: column "dirty" of relation "link_history" does not exist Where: PL/pgSQL function link_history_version() 2015-12-07 09:44:34 +13:00
Robin Bygrave 9c6c59afab #479 - Insert of @Draftable with getGeneratedKeys ... PersistenceException executing insert 2015-12-07 09:21:26 +13:00
Robin Bygrave c3eae0d3a5 #477 - findUnique() should throw NonUniqueResultException and not PersistenceException 2015-12-04 11:12:45 +13:00
Robin Bygrave 25ec73364e [maven-release-plugin] prepare for next development iteration 2015-12-03 21:41:41 +13:00
Robin Bygrave c7818e7f23 [maven-release-plugin] prepare release avaje-ebeanorm-6.13.1 2015-12-03 21:41:20 +13:00
Robin Bygrave 8318bbc4ca #118 - Additional: Add query includeSoftDeletes() asDraft() to ExpressionList (for fluid style when added after predicates) 2015-12-03 17:42:26 +13:00
Robin Bygrave 337646a6ce No effective change - javadoc update 2015-12-03 16:47:19 +13:00
Robin Bygrave fa6ee93e5b Bump pom to 6.13.1-SNAPSHOT 2015-12-03 16:35:43 +13:00
Robin Bygrave 0fe691112f Merge branch 'softDelete1' into softDelete2 2015-12-03 00:33:47 +13:00
Robin Bygrave 6946ff07e0 [maven-release-plugin] prepare for next development iteration 2015-12-02 23:48:15 +13:00
Robin Bygrave 7c3d052da0 [maven-release-plugin] prepare release avaje-ebeanorm-6.12.3 2015-12-02 23:47:49 +13:00
Robin Bygrave aea7a7fd65 #118 - ENH: Add support for for Soft Deletes (Logical Deletion) ... 2015-12-02 23:46:26 +13:00
Robin Bygrave f39a684c8e #118 - ENH: Add support for for Soft Deletes (Logical Deletion) ... 2015-12-02 21:38:34 +13:00
Robin Bygrave 3cb5854786 #475 - Unique constraint name not unique when using @Draftable 2015-12-02 07:57:27 +13:00
Robin Bygrave e8192723cc [maven-release-plugin] prepare for next development iteration 2015-12-01 23:25:26 +13:00
Robin Bygrave 3787748eae [maven-release-plugin] prepare release avaje-ebeanorm-6.12.2 2015-12-01 23:25:00 +13:00
Robin Bygrave 0ad52cf6a7 #118 - ENH: Add support for for Soft Deletes (Logical Deletion) ... - initial 2015-12-01 23:21:11 +13:00
Robin Bygrave 51bee836d4 #472 - DDL column ordering for @WhoCreated / @WhoModified. These columns should appear in the DDL with the @WhenCreated/@WhenModified columns. 2015-12-01 10:19:36 +13:00
Robin Bygrave 9193b6b971 No effective change - remove whitespace 2015-12-01 09:32:09 +13:00
Robin Bygrave e48b9fab0f No effective change - spelling in javadoc 2015-12-01 08:08:14 +13:00
Robin Bygrave a14ca24b33 [maven-release-plugin] prepare for next development iteration 2015-11-30 23:25:13 +13:00
Robin Bygrave 761f43d6a1 [maven-release-plugin] prepare release avaje-ebeanorm-6.12.1 2015-11-30 23:24:46 +13:00
Robin Bygrave 737f9a893e Bump pom - 6.12.1-SNAPSHOT 2015-11-30 23:23:58 +13:00
Robin Bygrave 579812d717 #455 - Should not generate "FOR UPDATE" for delete query 2015-11-30 16:50:26 +13:00
Robin Bygrave fae39fe650 #291 - ENH: Add ability to validate a query or property expression - Was Please check column exist on entity 2015-11-30 15:10:22 +13:00
Robin Bygrave debd8ad617 #465 - The encrypt key is logged out in sql statement - when included in where predicate 2015-11-30 12:25:25 +13:00
Robin Bygrave 6450ba219c #469 - Embedded bean made dirty after a prior insert does not trigger dirty state on 'outer' bean 2015-11-27 18:19:59 +13:00
Robin Bygrave a578eda2b1 #467 - Delete bean with unloaded version property throws OptimisticLockException - API Change, return boolean 2015-11-26 16:09:25 +13:00
Robin Bygrave a2ee0bfdbe #467 - Delete bean with unloaded version property throws OptimisticLockException 2015-11-26 15:12:59 +13:00
Robin Bygrave 872f0e21cb #466 - Delete of @Draftable bean ... means also delete matching live bean (aka delete has automatic publish behavior) 2015-11-26 00:49:18 +13:00
Robin Bygrave 8620dbf337 #464 - ENH: Add draftRestore(Class<?> beanType, Object id) ... to refresh a draft from the live (@Draftable feature) 2015-11-25 23:36:17 +13:00
Robin Bygrave 4f51a3b130 #463 - ENH: Add @DraftReset support - property that is set to null on the draft been when it is published (@Draftable feature) 2015-11-25 11:06:14 +13:00
Robin Bygrave 5f194f066a [maven-release-plugin] prepare for next development iteration 2015-11-24 01:04:26 +13:00
Robin Bygrave 31f6e56333 [maven-release-plugin] prepare release avaje-ebeanorm-6.11.1 2015-11-24 01:04:04 +13:00
Robin Bygrave 0efbe061ab #461 - ENH: Add @Draftable support - optimise publish query 2015-11-24 01:01:37 +13:00
Robin Bygrave 555e5ba6fd #461 - ENH: Add @Draftable support - API sans transaction 2015-11-24 01:01:14 +13:00
Robin Bygrave 5d3da60828 #461 - ENH: Add @Draftable support - delete 2015-11-24 00:46:45 +13:00
Robin Bygrave 2ac0d136e6 Bump pom to 6.11.1-SNAPSHOT 2015-11-24 00:02:35 +13:00
Robin Bygrave 97462cb21a #461 - ENH: Add @Draftable support - delete 2015-11-24 00:01:28 +13:00
Robin Bygrave afaacd4eeb #461 - ENH: Add @Draftable support - javadoc 2015-11-23 23:26:09 +13:00
Robin Bygrave 5e8afbe50d #461 - ENH: Add @Draftable support - @DraftDirty 2015-11-23 23:11:15 +13:00
Robin Bygrave db371cbc6a #461 - ENH: Add @Draftable support - publish 2015-11-23 21:28:58 +13:00
Robin Bygrave fd9a5167b1 #461 - ENH: Add @Draftable support - load context 2015-11-23 10:07:09 +13:00
Robin Bygrave 7b76e13bce #461 - ENH: Add @Draftable support - phase 1 2015-11-19 20:44:25 +13:00
Robin Bygrave 42e7103aa6 #458 - Support use of test-ebean.properties without an existing ebean.properties 2015-11-12 10:17:30 +13:00
Robin Bygrave 29ca678f01 No effective change - remove unused code 2015-11-12 09:59:36 +13:00
Robin Bygrave cca6143420 No effective change - code format 2015-11-12 09:48:18 +13:00
Robin Bygrave fe7b110577 #457 - When ebean.properties does not exist do not log error message 2015-11-10 09:47:33 +13:00
Robin Bygrave 16df55eafa [maven-release-plugin] prepare for next development iteration 2015-11-09 14:44:45 +13:00
Robin Bygrave 905a0ce9ec [maven-release-plugin] prepare release avaje-ebeanorm-6.10.4 2015-11-09 14:44:05 +13:00
Robin Bygrave bfa8837e61 #451 - avaje-ebeanorm-jackson - com.fasterxml.jackson.core.JsonParseException: Expecting start_array event but got START_OBJECT at 2015-11-05 16:38:22 +13:00
Robin Bygrave 8d5845b9a2 [maven-release-plugin] prepare for next development iteration 2015-11-04 22:10:38 +13:00
Robin Bygrave 87a7d4958e [maven-release-plugin] prepare release avaje-ebeanorm-6.10.3 2015-11-04 22:10:13 +13:00
Robin Bygrave 511ebd8a29 #450 - @ManyToMany with cascade and jdbc batch - ensure flush occurs 2015-11-03 16:31:27 +13:00
Robin Bygrave 11f4c8d7a3 #449 - Remove whitespace from generated Postgres trigger DDL (as Play evolution not parsing it) 2015-11-03 16:28:00 +13:00
Robin Bygrave d417a92843 [maven-release-plugin] prepare for next development iteration 2015-11-02 16:42:33 +13:00
Robin Bygrave 4bd5e52df3 [maven-release-plugin] prepare release avaje-ebeanorm-6.10.2 2015-11-02 16:42:10 +13:00
Robin Bygrave 788a200d16 #445 - Multiple @*ToMany relations referencing the same type 2015-11-02 14:11:23 +13:00
Robin Bygrave e18d2004dc #448 - ENH: Postgres Support for UUID mapping to native DB UUID type (relating to #430) 2015-11-02 12:57:47 +13:00
Robin Bygrave b326724139 #443 - ENH: Enum mapping - Add annotation @DbEnumValue that can be used to on a enum method which provides DB values 2015-10-30 21:42:21 +13:00
Robin Bygrave fc0b47342b #436 - @DiscriminatorColumn mapped also as @Column leads to NullPointerException 2015-10-29 22:01:28 +13:00
Robin Bygrave ec1a68a133 #435 - Duplicate foreign key name with ManyToMany relations 2015-10-29 17:44:29 +13:00
Robin Bygrave 8ca12521d7 No effective change - reduce debug level 2015-10-29 17:43:54 +13:00
Robin Bygrave 2362ef4130 [maven-release-plugin] prepare for next development iteration 2015-10-29 09:01:17 +13:00
Robin Bygrave 7e233edcc3 [maven-release-plugin] prepare release avaje-ebeanorm-6.10.1 2015-10-29 09:00:55 +13:00
Robin Bygrave a8b98282a1 Bump pom to 6.10.1-SNAPSHOT 2015-10-29 09:00:00 +13:00
Robin Bygrave b4506aa718 #444 - Spring Boot classpath scanning not finding entity beans - part2 - embedded jar scanning 2015-10-29 08:59:06 +13:00
Robin Bygrave 848a3b8888 #444 - Spring Boot classpath scanning not finding entity beans 2015-10-28 15:45:09 +13:00
Robin Bygrave 67c711d75f #442 - @JsonIgnore / @Expose ... not working on @OneToMany or @ManyToMany - was - @Transient field on @MappedSuperclass is not ignored by toJson() 2015-10-28 09:10:19 +13:00
Robin Bygrave 3d62f58930 #439 - @EnumValue("01") stored as integer rather than string - ENum stores strings as numerics? 2015-10-28 08:53:14 +13:00
Robin Bygrave a30948d38d #438 - findPagedList and getTotalRowCount, the query.getAlias() is null 2015-10-28 08:15:15 +13:00
Robin Bygrave a8232d2d8b #441 - ENH: Add support for test-ebean.properties ... for mechanism to configure ebean to run tests 2015-10-27 00:17:47 +13:00
Robin Bygrave d4b8f23a5a Fix test - MySql limitations with delete query syntax 2015-10-26 21:52:35 +13:00
Robin Bygrave bcf2a44187 #430 - ENH: Support for UUID mapping to native DB UUID type (Postgres, H2) 2015-10-26 20:52:16 +13:00
Robin Bygrave f3102ba02c #432 - Delete using Query does not commit 2015-10-22 13:29:21 +13:00
Robin Bygrave 0351eab3a7 #431 - Annotation PrivateOwned seems not enough to update an change in the list of children (fix) 2015-10-22 11:10:41 +13:00
Robin Bygrave 409e2b75ce #431 - Add failing test ... Annotation PrivateOwned seems not enough to update an change in the list of children 2015-10-22 09:27:32 +13:00
Robin Bygrave dc968f16bf Q: Ebean @ManyToMany(cascade=REMOVE) described #429 2015-10-06 14:38:05 +13:00
Robin Bygrave bbbb6482fb [maven-release-plugin] prepare for next development iteration 2015-10-02 13:03:34 +13:00
Robin Bygrave 001968fcf8 [maven-release-plugin] prepare release avaje-ebeanorm-6.9.1 2015-10-02 13:03:07 +13:00
Robin Bygrave 6abcb186a4 Bump pom to 6.9.1-SNAPSHOT 2015-10-02 13:02:13 +13:00
Robin Bygrave f250447fbe Add test for ManyToMany delete scenario 2015-10-01 22:21:47 +13:00
Robin Bygrave bfa86f241b #427 - ENH: Add support for Removing ShutdownManager.shutdownHook ... manually control entire shutdown. 2015-10-01 10:33:09 +13:00
Robin Bygrave 19459b71b4 Fix for #425 - Extra instance of root level bean with findIterate() and fetch of OneToMany relationship - Ebean parses the first bean correctly and the rest not 2015-09-30 23:35:10 +13:00
Robin Bygrave 5e97c3bbbc #425 - Extra instance of root level bean with findIterate() and fetch of OneToMany relationship - Ebean parses the first bean correctly and the rest not 2015-09-30 23:24:53 +13:00
Robin Bygrave 986eadd023 #424 - DDL generation - support turning off lower casing of table and column names DbConstraintNaming, DbConstraintNormalise 2015-09-30 22:44:47 +13:00
Robin Bygrave c6787d0901 Update javadoc 2015-09-30 17:26:30 +13:00
Robin Bygrave 3792e06859 Update javadoc 2015-09-30 17:26:05 +13:00
Robin Bygrave c77446ba24 Update javadoc 2015-09-30 17:25:26 +13:00
Robin Bygrave dba245c517 #421 - ENH: Add support for unsetting the loaded state of a bean property (via BeanState) 2015-09-22 13:21:19 +12:00
Robin Bygrave 489eb483c0 No effective change - parameter name from val -> value 2015-09-22 12:34:30 +12:00
Robin Bygrave 11301846be #422 - ENH: Add jsonBetween() expression 2015-09-22 12:32:46 +12:00
Robin Bygrave d022e4aec8 No effective change - parameter name from val -> value 2015-09-22 11:48:41 +12:00
Robin Bygrave aa788edb68 #421 - ENH: Add support for unsetting the loaded state of a bean property (via BeanState) ... initial test 2015-09-22 09:00:06 +12:00
Robin Bygrave 288adcdf68 Update README 2015-09-21 18:01:31 +12:00
Robin Bygrave ddb07ca202 Update README 2015-09-21 17:59:45 +12:00
Robin Bygrave 524b592e82 [maven-release-plugin] prepare for next development iteration 2015-09-21 17:45:47 +12:00
Robin Bygrave 0124f0f254 [maven-release-plugin] prepare release avaje-ebeanorm-6.8.1 2015-09-21 17:45:21 +12:00
Robin Bygrave eddd6a36d6 No effective change - javadoc only 2015-09-21 17:36:13 +12:00
Robin Bygrave 91e309d770 Bump pom version to 6.8.1-SNAPSHOT 2015-09-21 17:03:22 +12:00
Robin Bygrave 5726410f6f #417 - ENH: Add JSON expressions ... path exists and value at path equals value 2015-09-21 16:20:14 +12:00
Robin Bygrave 054f7dc86f #415 - ENH: Add ExplicitJdbcTransaction ... so like AutoCommitJdbcTransaction but using explicit statements to commit and rollback 2015-09-18 22:25:19 +12:00
Robin Bygrave 06b5ebc14e #419 - Support running History DDL scripts in full drop and create ddl execution - detect $$ procedures/triggers in ddl script 2015-09-18 22:19:52 +12:00
Robin Bygrave f6ee82428f Change test - disable this test for MySql - it does not like trying to delete using sub query select from same table 2015-09-18 22:18:37 +12:00
Robin Bygrave e1d45dd79d #419 - Support running History DDL scripts in full drop and create ddl execution - detect $$ procedures/triggers in ddl script 2015-09-18 22:03:26 +12:00
Robin Bygrave 08c455279f #418 - Postgres History DDL generation - invalid update table statement to initialise the sys_period 2015-09-18 21:30:59 +12:00
Robin Bygrave 32dcbc6703 Change test to only run with H2 (but it would also run with db's that use history table views/triggers but not with oracle total recall) 2015-09-18 21:13:19 +12:00
Robin Bygrave c9e733df4e Fix test - incorrect raw sql syntax (breaks in Oracle) 2015-09-18 21:06:54 +12:00
Robin Bygrave 606e1e6d3a #414 - Enh info: @History support for H2 2015-09-18 17:16:46 +12:00
Robin Bygrave fcb50ea13a No effective change - remove whitespace 2015-09-18 11:45:19 +12:00
Robin Bygrave 5b26e77cfd #413 - ENH: Add ability to clear the OrderBy ... so that a default order by can be set in code and then cleared / overwritten 2015-09-18 11:39:47 +12:00
Robin Bygrave 9fc5d8a201 Pom - bump test Postgres JDBC driver version 2015-09-17 11:33:09 +12:00
Robin Bygrave ba78c5e904 [maven-release-plugin] prepare for next development iteration 2015-09-14 16:19:59 +12:00
Robin Bygrave 6627195fc2 [maven-release-plugin] prepare release avaje-ebeanorm-6.7.1 2015-09-14 16:19:33 +12:00
Robin Bygrave b76c4a83ec #411 - AutoTune - add reporting empty tuned profiles, ignore org.avaje.ebean type safe finders, refactor CallStack creation 2015-09-14 16:16:22 +12:00
Robin Bygrave 3dcb82b1f5 gitignore example ebean-autotune.xml 2015-09-14 12:58:58 +12:00
Robin Bygrave ae55a40ebd Remove example ebean-autotune.xml 2015-09-14 12:57:57 +12:00
Robin Bygrave 8ba07419fa Bump pom to 6.7.1-SNAPSHOT 2015-09-14 12:02:26 +12:00
Robin Bygrave 5f8f735bbe #412 - SQL_LOGGER trace() to debug() issue - Unintelligible logging settings 2015-09-14 11:49:16 +12:00
Robin Bygrave 47829f3985 #410 - Require findPagedList() query to specify an order by clause - throw exception if no order by supplied 2015-09-14 11:29:38 +12:00
Robin Bygrave ec4f655312 #410 - Require findPagedList() query to specify an order by clause - throw exception if no order by supplied 2015-09-14 10:39:41 +12:00
Robin Bygrave 04fda0a6b4 #411 - Refactor AutoFetch, rename to "AutoTune", store/load tuning and profiling as XML 2015-09-10 23:22:23 +12:00
Robin Bygrave 0a8c902790 #411 - Refactor AutoFetch, rename to "AutoTune", store/load tuning and profiling as XML 2015-09-10 23:20:57 +12:00
Robin Bygrave 9632279c2f AutoTune update - clean up for query ignore 2015-09-10 22:36:12 +12:00
Robin Bygrave 262d52ed44 Merge AutoTune refactor with master 2015-09-10 10:27:24 +12:00
Robin Bygrave 74330918e1 AutoTune update - .gitignore the profiling output 2015-09-10 10:04:31 +12:00
Robin Bygrave 373598ab26 AutoTune update - config properties for queryTuningFile and profilingFile + logging adjustment 2015-09-10 10:02:17 +12:00
Robin Bygrave 0096477757 AutoTune update - repackage tests and sort profiling xml entries 2015-09-10 09:16:39 +12:00
Robin Bygrave a2a4a15f32 AutoTune update - rename and profiling against original query 2015-09-10 00:18:11 +12:00
Robin Bygrave 71dd0e5728 AutoTune update - rename and profiling against original query 2015-09-10 00:17:49 +12:00
Robin Bygrave 116cc3a3fe AutoTune update - remove resources 2015-09-09 15:21:10 +12:00
Robin Bygrave 92132d6613 [maven-release-plugin] prepare for next development iteration 2015-09-09 00:08:33 +12:00
Robin Bygrave d6e3292a7d [maven-release-plugin] prepare release avaje-ebeanorm-6.6.1 2015-09-09 00:08:12 +12:00
Robin Bygrave 227a1ba032 Bump pom to 6.6.1-SNAPSHOT 2015-09-09 00:07:20 +12:00
Robin Bygrave 953cae6ce8 #407 - ENH: Add example uses of raw() into javadoc for ExpressionList.raw() 2015-09-09 00:06:14 +12:00
Robin Bygrave 98fc739600 #404 - ENH: ExpressionList missing setUseQueryCache() method - need to add it. 2015-09-08 23:55:53 +12:00
Robin Bygrave fc3ab10984 No effective change - javadoc on Ebean 2015-09-08 16:20:56 +12:00
Robin Bygrave 5b8ce8eaa0 WIP AutoTune refactor 2015-09-04 08:48:25 +12:00
Robin Bygrave 97cf8b30f6 Extend test for #322 - using inheritance discriminator with RawSql - extra test with columnMappingIgnore() 2015-09-03 16:29:45 +12:00
Robin Bygrave 7e66e0db1f Extend test for #322 - using inheritance discriminator with RawSql 2015-09-03 15:57:38 +12:00
Robin Bygrave 572bb41b73 Code Cleanup - move diff flatten into DiffHelp class from DiffHelpUpdate #406 2015-09-03 14:31:36 +12:00
Robin Bygrave 088fcfb296 #406 - Remove diff "non flat mode" ... so diff going forward only supports flat mode 2015-09-03 14:29:03 +12:00
Robin Bygrave 54172aec6c #405 - ENH: Add @ReadAudit and associated functionality for auditing reads including queries and L2 cache access 2015-09-03 13:54:52 +12:00
Robin Bygrave 5c1de0a886 WIP Autotune refactor 2015-09-02 09:28:17 +12:00
Robin Bygrave c292da736b #403 - Long property names result in invalid DDL 2015-09-01 08:00:46 +12:00
Robin Bygrave 987fe38618 WIP AutoTune refactor 2015-09-01 07:55:25 +12:00
Robin Bygrave f4ed813c08 No effective change - code format only 2015-08-31 16:16:10 +12:00
Robin Bygrave a358fba31d Bump agent and maven enhancer versions to 4.7.1 2015-08-31 15:37:32 +12:00
Robin Bygrave 76783d525a No effective change - improve error message 2015-08-31 15:36:56 +12:00
Robin Bygrave 3f0f5c7fde #401 - Fix for - Caused by: java.lang.NullPointerException at com.avaje.ebeaninternal.server.changelog.DefaultChangeLogListener.configure(DefaultChangeLogListener.java:62) 2015-08-30 23:38:05 +12:00
Robin Bygrave 6df1058aab [maven-release-plugin] prepare for next development iteration 2015-08-29 01:03:00 +12:00
Robin Bygrave 335c5fb69b [maven-release-plugin] prepare release avaje-ebeanorm-6.5.1 2015-08-29 01:02:37 +12:00
Robin Bygrave 94ed568812 Bump pom to 6.5.1-SNAPSHOT 2015-08-29 01:01:17 +12:00
Robin Bygrave 1c23720605 #398 - ENH: Support delete using a Query instance 2015-08-29 00:58:47 +12:00
Robin Bygrave ccba5d08ef #368 - ENH: Enhance @Index to support multiple columns, unique flag and hence also be able to put on the class (annotation target TYPE) 2015-08-28 21:56:38 +12:00
Robin Bygrave 641ada001e Fix test for CustomerFinder 2015-08-28 20:43:05 +12:00
Robin Bygrave fca80ac649 #399 - ENH: Add new Finder ... to effectively replace Model.Finder 2015-08-28 20:32:40 +12:00
Robin Bygrave 379cc39e38 Initial add of Finder 2015-08-28 07:52:46 +12:00
Robin Bygrave 386d3a37f1 No effective change - format only 2015-08-27 09:37:22 +12:00
Robin Bygrave 37612c6f83 [maven-release-plugin] prepare for next development iteration 2015-08-26 10:48:57 +12:00
Robin Bygrave 7984553d96 [maven-release-plugin] prepare release avaje-ebeanorm-6.4.1 2015-08-26 10:48:35 +12:00
Robin Bygrave d592e7d35f No effective change - format only 2015-08-26 10:47:22 +12:00
Robin Bygrave 5a0b65b4f2 Bump pom to 6.4.1-SNAPSHOT 2015-08-26 10:45:06 +12:00
Robin Bygrave aaefaa5dcd #390 - ChangeLog - Add inheritance hierarchy check for @ChangeLog 2015-08-26 10:42:12 +12:00
Robin Bygrave f3e66c459a #390 - ChangeLog - Add ServerConfig.isChangeLogIncludeInserts() and ChangeLogInsertMode enum with associated changes 2015-08-25 13:54:34 +12:00
Robin Bygrave 16d5e04809 #390 - ChangeLog - Change userContext to be Map<String,String> 2015-08-25 13:22:09 +12:00
Robin Bygrave b01df515bd #390 - ChangeLog - Refactor DefaultChangeLogListener (simplify to use standard logger) 2015-08-25 13:05:58 +12:00
Robin Bygrave 7fda911931 #394 - ENH: SpiServer - Add getServerConfig() to the api 2015-08-25 13:04:36 +12:00
Robin Bygrave e332aace16 No effective change - format test logback-test.xml 2015-08-25 11:54:11 +12:00
Robin Bygrave c79231c846 #394 - ENH: Add plugin API SpiServer - add shutdown() method to SpiServerPlugin. 2015-08-25 11:52:58 +12:00
Robin Bygrave efad23d482 #390 - ENH: Add Change log mechanism - javadoc update - no effective change 2015-08-25 08:12:22 +12:00
Robin Bygrave fe8a32ea18 #390 - ENH: Add Change log mechanism for easy fine grained logging of insert, update, delete activity.
This adds default implementations for register,filter, prepare and log of the change sets.
2015-08-22 12:10:30 +12:00
Robin Bygrave 31099f6dda #397 - Internal logger name change - Rename DefaultContainer logger to be com.avaje.ebean.internal.DefaultContainer ... so that the offline debugging messages come out without a extra logback name logger entry 2015-08-22 12:02:21 +12:00
Robin Bygrave 58f4f791f6 Opps - remove Oracle jdbc and MS SQL Server jdbc drivers ... (put those in here by mistake during @History testing). 2015-08-22 10:18:46 +12:00
Robin Bygrave b27989f541 #396 - Rename migration method to DbMigration.generateMigration() ... update javadoc 2015-08-21 21:37:36 +12:00
Robin Bygrave 7bc1a902ed No effective change - code format only 2015-08-21 21:10:22 +12:00
Robin Bygrave 358720776e No effective change - code format only 2015-08-21 21:08:29 +12:00
Robin Bygrave 417ee4061e #395 - No functional change - cleanup unused BeanDelta 2015-08-21 21:06:33 +12:00
Robin Bygrave 394cb3854a No effective change - format and organise imports 2015-08-21 18:31:55 +12:00
Robin Bygrave 547fa342c4 Internal change only - just reuse class name as bean descriptor key 2015-08-21 18:28:10 +12:00
Robin Bygrave f8b8a41bce #394 - ENH: Add plugin API SpiServer, SpiBeanType ... migrate plugins towards using this API, migrate away from direct use of BeanDescriptor etc. 2015-08-21 17:33:43 +12:00
Robin Bygrave ba39897b18 ChangeSet - add size() method 2015-08-21 16:05:30 +12:00
Robin Bygrave 1437843f08 #393 - ENH: Add ServerConfig.getProperties() ... serverConfig remembers the properties that were used in configuration in order to make these available to plugins 2015-08-21 16:05:09 +12:00
Robin Bygrave 7c705e2baa #377 - Add back support for JsonWriteBeanVisitor 2015-08-21 08:20:47 +12:00
Robin Bygrave 2caeb4fff1 #392 - Fix for AutoCommit mode ... fixing change from #204 ... such that AutoCommitJdbcTransaction works as expected 2015-08-20 22:38:53 +12:00
Robin Bygrave 84190f3c2a #390 - ENH: Add Change log mechanism for easy fine grained logging of insert, update, delete activity 2015-08-20 20:46:28 +12:00
Robin Bygrave 46b158a0a0 #391 - Minor internals - Ebean catch Throwable on instantiation rather than RuntimeException 2015-08-20 10:08:54 +12:00
Robin Bygrave b172a32710 No effective change - remove commented out test 2015-08-19 15:58:13 +12:00
Robin Bygrave f8ef87f7a8 #389 - ENH: Allow Postgres8 platform also support identity (stills defaults to use sequences but can also use identity if defined explicitly) 2015-08-19 13:24:58 +12:00
Robin Bygrave ea54d1b794 #388 - Postgres DbType.HSTORE ... not registered as logical type for DbMigration 2015-08-19 13:16:22 +12:00
Robin Bygrave b1780948a8 #387 - Change ebeanServer.diff() to default to 'flat' mode 2015-08-19 12:47:31 +12:00
Robin Bygrave 1a0f3a6614 #386 - ENH: Add setDistinct() onto ExpressionList ... so you don't need to get back to the query(and #385 javadoc) 2015-08-19 12:37:53 +12:00
Robin Bygrave 580b51381e #384 - ENH: Add findVersionsBetween(start, end) ... including implementation support for Oracle total recall 2015-08-18 23:57:11 +12:00
Robin Bygrave 75e9770d5e #383 - Refactor - Rename Oracle10Platform to OraclePlatform, remove Oracle9Platform (as not different) 2015-08-18 22:26:44 +12:00
Robin Bygrave 10937de24b #382 - ENH: Add support for @History using Oracle Total Recall ... for 'as of' queries 2015-08-18 22:19:55 +12:00
Robin Bygrave 18aeedc153 #381 - Change DbMigration to use default server platform when no platform specified 2015-08-18 22:15:11 +12:00
Robin Bygrave 9ca1a87f8b No effective change - add missing javadoc 2015-08-18 22:13:12 +12:00
Robin Bygrave 111354f391 [maven-release-plugin] prepare for next development iteration 2015-08-18 08:21:32 +12:00
Robin Bygrave 79879fb326 [maven-release-plugin] prepare release avaje-ebeanorm-6.3.1 2015-08-18 08:21:11 +12:00
Robin Bygrave 9f6ccdee66 #369 - Add test .sql resources 2015-08-18 08:16:19 +12:00
Robin Bygrave bbf469bd54 #369 - Rollback of base column attributes 2015-08-18 08:02:37 +12:00
Robin Bygrave ad97ac2be9 #369 - Rollback of create index - drop index 2015-08-18 07:00:34 +12:00
Robin Bygrave 9d83017374 #379 - Add MySql support for @History 2015-08-18 06:13:59 +12:00
Robin Bygrave 98ec00a2d6 #374 - Add @History support with MySql - refactor extracting DbTriggerBasedHistoryDdl 2015-08-17 22:12:06 +12:00
Robin Bygrave 24971bcc86 #374 - Refactor to support generating multiple platform DDL for a single migration 2015-08-17 16:03:51 +12:00
Robin Bygrave c1c45139a0 #374 - Cleanup - remove 'all' migration xml 2015-08-17 14:48:29 +12:00
Robin Bygrave 116425b460 #374 - Add support for rollback on history function 2015-08-17 14:43:44 +12:00
Robin Bygrave 48acb6294b #374 - Add DropIndex and CreateIndex migration 2015-08-17 13:06:05 +12:00
Robin Bygrave 61f5057528 #374 - Add DropIndex and CreateIndex migration 2015-08-17 13:05:54 +12:00
Robin Bygrave b91ef46243 #374 - Cleanup - remove unused migration objects 2015-08-17 11:42:12 +12:00
Robin Bygrave 0eddcc30bb #374 - Cleanup - remove unused migration objects 2015-08-17 11:42:06 +12:00
Robin Bygrave 24ec0fefba #374 - DbConstrainNaming - add index naming 2015-08-17 11:41:49 +12:00
Robin Bygrave 5ac28cb3fb #374 - BaseTableDdl change to protected visibility 2015-08-17 11:41:31 +12:00
Robin Bygrave d4635fb615 #374 - Add PlatformDdl.configure() and move add fk and create index onto PlatformDdl 2015-08-17 08:35:43 +12:00
Robin Bygrave b9774e64e9 #374 - Add comments for when a history table trigger/function is regenerated 2015-08-17 07:44:59 +12:00
Robin Bygrave f29ba8383e #374 - Find whenCreatedColumn and use as default effective start when adding history 2015-08-16 20:19:52 +12:00
Robin Bygrave a15dd33380 #374 - Add GeneratedWhenCreated and GeneratedWhenModified marker interfaces etc - used to find bean properties with those behaviours 2015-08-16 20:08:56 +12:00
Robin Bygrave f22563b36a #374 - ms sql server ... alter column default values 2015-08-15 16:53:02 +12:00
Robin Bygrave fe17ec5dbb #374 - Update tests 2015-08-15 16:09:27 +12:00
Robin Bygrave 85fdf8646d #374 - Update migration generation 2015-08-15 01:58:35 +12:00
Robin Bygrave bd9acab335 #374 - Update ModelDiff and migration generation 2015-08-15 00:06:24 +12:00
Robin Bygrave 0a6941bda5 #374 - Update ModelDiff and migration generation 2015-08-15 00:06:14 +12:00
Robin Bygrave 215417a43c #374 - Move db constraint max length to database platform 2015-08-14 17:06:08 +12:00
Robin Bygrave 60c1a5b111 #374 - Add DbOffline check into TransactionManager isReadCommittedIsolation() 2015-08-14 17:02:58 +12:00
Robin Bygrave 5166fbed96 #374 - Merge BaseColumnDdl into BaseTableDdl 2015-08-14 12:14:18 +12:00
Robin Bygrave 851f40e7b0 DbMigration update - constraints up front 2015-08-11 08:25:29 +12:00
Robin Bygrave 845faf74ff WIP: Db migration alterColumn ... 2015-08-10 14:26:47 +12:00
Robin Bygrave c0d4dac2b3 #374 - Update example/sample xml for xml schema changes 2015-08-07 13:26:35 +12:00
Robin Bygrave f6c3279e86 #374 - Table remarks -> comment 2015-08-07 13:25:22 +12:00
Robin Bygrave 48f0da9343 No effective change - update test to give slf4j a little time in multithreaded case to catch logged sql 2015-08-07 13:24:26 +12:00
Robin Bygrave ce0d73cf23 #374 - updated migration xml generated 2015-08-07 13:23:25 +12:00
Robin Bygrave 1585bd7cd0 #374 - ChangeSetType ... baseline, CreateHistoryTable whenCreatedColumn 2015-08-07 12:46:17 +12:00
Robin Bygrave 1603c69156 #374 - IdentityType lowered 2015-08-07 12:45:45 +12:00
Robin Bygrave 7cd9dc0c8d Quiet down the logging of enhancement via AgentLoader 2015-08-07 12:45:03 +12:00
Robin Bygrave e4304494e1 #374 - ChangeSetType ... baseline, CreateHistoryTable whenCreatedColumn 2015-08-07 12:44:13 +12:00
Robin Bygrave 0612d89e9a #376 - Refactor - Remove PstmtDelegate ... that was used to access the underlying oracle specific PreparedStatement 2015-08-06 23:03:25 +12:00
Robin Bygrave e6f779268a Update .gitignore to include ddl-review directory 2015-08-06 22:26:23 +12:00
Robin Bygrave 815d846695 Add ddl-review with sql/ddl for the various databases, can review/diff over time 2015-08-06 22:25:35 +12:00
Robin Bygrave 4b74062d80 #374 - uniqueOneToOne reflected in migration.xml 2015-08-06 22:03:18 +12:00
Robin Bygrave 1dd0841f00 #374 - MsSqlServer - adjust tests (due to jdbc batch support etc) add in support for unique index handling 2015-08-06 21:49:04 +12:00
Robin Bygrave 3a9668fe6c #375 - javax.persistence.PersistenceException: Query threw SQLException:Incorrect syntax near the keyword distinct 2015-08-06 19:30:57 +12:00
Robin Bygrave 93f802f7fe #374 - Drop foreign keys before indexes 2015-08-06 13:37:51 +12:00
Robin Bygrave 8cde0da419 #374 - Update tests for cross db (order by and too fast) 2015-08-06 13:36:55 +12:00
Robin Bygrave 14f984ea3e #374 - Remove old DbDdlSyntax - move to PlatformDdl 2015-08-06 13:09:41 +12:00
Robin Bygrave 253bebb9bb No effective change - camel case variable names 2015-08-06 12:27:03 +12:00
Robin Bygrave 483538bbc1 #374 -Move DdlGenerator 2015-08-06 12:16:06 +12:00
Robin Bygrave c0ef6d8b34 #374 - removed old ddl generation mechanism 2015-08-06 12:04:41 +12:00
Robin Bygrave 7f06863b19 #374 - SpiEbeanPlugin API change : DatabasePlatform dbPlatform parameter removed 2015-08-06 12:03:32 +12:00
Robin Bygrave 8be7ee1b7d identityType="EXTERNAL" - Internal changes for DB Migration / DDL generation #369 2015-08-06 11:51:00 +12:00
Robin Bygrave 15e2fde864 Postgres updated migration xml - Internal changes for DB Migration / DDL generation #369 2015-08-06 11:46:29 +12:00
Robin Bygrave 4e5140c877 Postgres dropTableCascade - Internal changes for DB Migration / DDL generation #369 2015-08-06 11:46:12 +12:00
Robin Bygrave 13ed298ee8 MySql update - Internal changes for DB Migration / DDL generation #369 2015-08-06 11:15:31 +12:00
Robin Bygrave e83a6f05bc Oracle specific changes - Internal changes for DB Migration / DDL generation #369 2015-08-06 08:09:20 +12:00
Robin Bygrave a0c312e5a4 #373 - Internals for Oracle - Remove the oracle proprietary jdbc batch handling in favour of standard jdbc batch api 2015-08-06 08:06:46 +12:00
Robin Bygrave 1eabb7fdb4 #373 - Internals for Oracle - Remove the oracle proprietary jdbc batch handling in favour of standard jdbc batch api 2015-08-06 08:02:44 +12:00
Robin Bygrave 9e170b40f6 Support duplicate index detection, max constraint names - Internal changes for DB Migration / DDL generation #369 2015-08-06 07:39:50 +12:00
Robin Bygrave efd5e16511 Update tests for better cross database execution (ordering of results etc) 2015-08-06 07:27:04 +12:00
Robin Bygrave c4e0d7aedc Internal - BeanRequest.rollbackTransIfRequired() ... change catch from PersistenceException -> Exception #371 2015-08-06 05:31:55 +12:00
Robin Bygrave d1584bed40 Change tests for better portability - Internal changes for DB Migration / DDL generation #369 2015-08-06 05:28:25 +12:00
Robin Bygrave 689d201b04 Update for pg - Internal changes for DB Migration / DDL generation #369 2015-08-05 20:59:09 +12:00
Robin Bygrave 22407506ff DB migration initial 2015-08-04 23:23:32 +12:00
Robin Bygrave 009f91b949 WIP Db Migration compound keys 2015-08-04 19:48:47 +12:00
Robin Bygrave 3bd281bea0 DB migration initial 2015-08-04 17:37:16 +12:00
Robin Bygrave 30c3a435d6 Internal changes for DB Migration / DDL generation #369 2015-08-03 17:29:57 +12:00
Robin Bygrave 0fe321b0ef Bump pom to 6.3.1-SNAPSHOT 2015-08-03 17:23:40 +12:00
Robin Bygrave 8f12442ac7 #363 - API CHANGE - BeanPersistController postLoad() ... moved to new/separate BeanPostLoad interface 2015-08-02 21:56:56 +12:00
Robin Bygrave 40ab3c81dc #364 - CallableStatement with a parameter that is both IN and OUT (so an INOUT parameter) 2015-08-02 15:24:01 +12:00
Robin Bygrave d5a8bf38ad No effective change - @SuppressWarnings("unchecked") 2015-08-02 13:48:15 +12:00
Robin Bygrave 0e793036fb No effective change - remove unused ScalarTypeConverter from BeanPropertyCompound (ala wrapper type like Option) 2015-08-02 13:27:32 +12:00
Robin Bygrave 19b7637d46 No effective change - param always true 2015-08-02 13:18:40 +12:00
Robin Bygrave 5609bc6d02 No effective change - add extra tests 2015-08-02 13:07:48 +12:00
Robin Bygrave fceeeacf88 #367 - ENH: Add EbeanServer deleteAll() with an explicit transaction 2015-08-02 12:43:19 +12:00
Robin Bygrave 4327108ddf No effective change - param always null, removed 2015-08-02 11:27:49 +12:00
Robin Bygrave cb77f33fc8 No effective change - param always null, removed 2015-08-02 11:22:46 +12:00
Robin Bygrave b687305be2 No effective change - param always true, removed 2015-08-02 11:15:43 +12:00
Robin Bygrave 192305c61f No effective change - suppress code inspection warnings 2015-08-02 11:06:38 +12:00
Robin Bygrave 03faf29bcf #366 - ServerConfigStart when registered via instance rather than class not fired 2015-08-02 11:02:02 +12:00
Robin Bygrave d389f8b5ac No effective change - remove unread variable 2015-08-02 09:52:56 +12:00
Robin Bygrave 56348938fb No effective change - remove unread variable (include props) 2015-08-02 09:48:00 +12:00
Robin Bygrave 9b0aafbfa8 No effective change - remove unused fields 2015-08-02 09:37:17 +12:00
Robin Bygrave 9239d61c74 No effective change - simplify ManyType to be an enum 2015-08-02 09:34:11 +12:00
Robin Bygrave 58a110e109 No effective change - remove unused 2015-08-02 09:33:46 +12:00
Robin Bygrave b255102780 No effective change - remove unused 2015-08-02 09:18:49 +12:00
Robin Bygrave 3a14b4c87f No effective change - remove unused methods 2015-08-02 09:17:10 +12:00
Robin Bygrave e1d6bf5961 No effective change - BeanPropertyAssocOne - importedPrimaryKey never set 2015-08-02 09:04:46 +12:00
Robin Bygrave 8e546bde0b No effective change - remove unused methods 2015-08-02 09:04:07 +12:00
Robin Bygrave 29a97d84a1 No effective change - format only 2015-08-02 08:55:36 +12:00
Robin Bygrave c526b3ef57 DataSourcePool - use IllegalArgumentException - remove need for DataSourceException 2015-08-02 08:54:00 +12:00
Robin Bygrave 032721d246 No effective change - remove unused 2015-08-02 08:51:40 +12:00
Robin Bygrave 0731084ec0 No effective change - remove unused 2015-08-02 08:47:37 +12:00
Robin Bygrave 11a3e49daa No effective change - remove unused 2015-08-02 08:41:10 +12:00
Robin Bygrave 68481844ee No effective change - param always true 2015-08-02 08:24:44 +12:00
Robin Bygrave 96a9def513 No effective change - LoadBeanRequest / LoadManyRequest cleanup of constructors 2015-08-01 22:35:35 +12:00
Robin Bygrave 98a4f046ee No effective change - format only 2015-08-01 22:21:08 +12:00
Robin Bygrave 9db8c941dc No effective change - SplitName - extract constant 2015-08-01 22:20:24 +12:00
Robin Bygrave fd4a6906bd No effective change - SqlTreeNodeBean cleanup - always same value params 2015-08-01 22:17:50 +12:00
Robin Bygrave da65256208 No effective change - ArrayStack cleanup 2015-08-01 22:00:00 +12:00
Robin Bygrave 0d2615522f No effective change - suppress warnings, simplify if 2015-08-01 21:16:03 +12:00
Robin Bygrave 6e5e5fb666 No effective change - remove unused assignment 2015-08-01 21:07:57 +12:00
Robin Bygrave 8005ef8432 No effective change - simplify if 2015-08-01 21:07:09 +12:00
Robin Bygrave 49fe97bbe4 No effective change - simplify if 2015-08-01 21:06:36 +12:00
Robin Bygrave 95ab97df73 No effective change - add code inspection suppression comments 2015-08-01 21:01:53 +12:00
Robin Bygrave 3be9833ee0 No effective change - DeployBeanPropertyLists cleanup - Assoc One / Many types when collected 2015-08-01 20:58:43 +12:00
Robin Bygrave b82223dc1d No effective change - add code inspection suppression comments 2015-08-01 20:41:50 +12:00
Robin Bygrave 17d97623d5 No effective change - add test HashQueryPlanTest 2015-08-01 20:41:07 +12:00
Robin Bygrave 1fca5ba008 BeanMap - code cleanup - while loop to foreach 2015-08-01 20:17:57 +12:00
Robin Bygrave 5bb97ee42f No effective change - code cleanup - remove unnecessary boxing 2015-08-01 20:12:09 +12:00
Robin Bygrave ae9a03e58c No effective change - code cleanup - remove unused 2015-08-01 20:11:21 +12:00
Robin Bygrave ca12761fb2 No effective change - code cleanup - remove unused 2015-08-01 20:06:13 +12:00
Robin Bygrave 18a61416fd No effective change - code cleanup - unused imports 2015-08-01 20:03:31 +12:00
Robin Bygrave 37ff2c7227 No effective change - code cleanup - removed unused param 2015-08-01 20:02:19 +12:00
Robin Bygrave af4018403b No effective change - code cleanup - removed unused param 2015-08-01 19:59:54 +12:00
Robin Bygrave d3b9bde5c2 No effective change - code cleanup - removed unused param 2015-08-01 19:59:01 +12:00
Robin Bygrave d704fef294 No effective change - code cleanup - removed unused param 2015-08-01 19:57:53 +12:00
Robin Bygrave bb4bb64795 No effective change - code cleanup - removed unused param 2015-08-01 19:55:52 +12:00
Robin Bygrave 402ab092d8 No effective change - code cleanup - removed unused param 2015-08-01 19:53:07 +12:00
Robin Bygrave 9769e4b574 No effective change - code cleanup - removed unused param 2015-08-01 19:47:05 +12:00
Robin Bygrave e19fe5ccd3 No effective change - code cleanup - removed unused param 2015-08-01 19:42:39 +12:00
Robin Bygrave 11963e1ff7 No effective change - code cleanup - removed unused param 2015-08-01 19:41:07 +12:00
Robin Bygrave ec0d4fbd07 No effective change - code cleanup - removed unused param 2015-08-01 19:38:40 +12:00
Robin Bygrave 4e66e348fc No effective change - code cleanup - removed unused param 2015-08-01 19:36:52 +12:00
Robin Bygrave eb6fce5a72 No effective change - code cleanup - removed unused param - TypeManager 2015-08-01 19:33:48 +12:00
Robin Bygrave 21b33bb9cd No effective change - code cleanup - removed unused BeanCollectionParams 2015-08-01 19:30:06 +12:00
Robin Bygrave 430b3cff96 No effective change - code cleanup - removed not required throws 2015-08-01 19:29:09 +12:00
Robin Bygrave 334a8b66bd No effective change - code cleanup - removed not required throws 2015-08-01 19:20:51 +12:00
Robin Bygrave 204b9ca6e5 No effective change - code cleanup - return void (unused return values), remove unused methods 2015-08-01 17:54:06 +12:00
Robin Bygrave 93f13113e6 No effective change - code cleanup - return void (unused return values) 2015-08-01 17:51:04 +12:00
Robin Bygrave ca1f95df7a No effective change - code cleanup - remove unused 2015-08-01 17:40:40 +12:00
Robin Bygrave 0c9bcca584 No effective change - code cleanup - BeanPropertyOverride - unused override of sql formula 2015-08-01 17:21:09 +12:00
Robin Bygrave a27433dc11 No effective change - code cleanup - unused params 2015-08-01 17:16:33 +12:00
Robin Bygrave dbd789f4be No effective change - suppress warnings in test 2015-08-01 16:56:12 +12:00
Robin Bygrave 7efbffb46d No effective change - format only 2015-08-01 09:11:04 +12:00
Robin Bygrave 559383a810 No effective change - format only 2015-08-01 09:02:34 +12:00
Robin Bygrave 1897ac67a0 No effective change - OrmQueryDetail - remove unnecessary if, simplify if 2015-08-01 09:01:43 +12:00
Robin Bygrave 4f2d669897 No effective change - format only 2015-08-01 08:54:49 +12:00
Robin Bygrave f50b18556e No effective change - SqlTreeBuilder , remove unnecessary null check 2015-08-01 08:51:40 +12:00
Robin Bygrave 1dc8a7f314 Add int getPageSize() to PagedList 2015-08-01 08:42:37 +12:00
Robin Bygrave b526d07eed No effective change - remove unused methods and parameters, simplify if 2015-08-01 08:42:09 +12:00
Robin Bygrave 97cd0909e8 No effective change - format only 2015-07-31 23:10:26 +12:00
Robin Bygrave 39cb85fda6 No effective change - remove unused BindValue comment 2015-07-31 23:09:31 +12:00
Robin Bygrave 498f567e37 No effective change - format only 2015-07-31 23:03:17 +12:00
Robin Bygrave 99cecd6756 No effective change - simplify if, remove unused 2015-07-31 23:02:17 +12:00
Robin Bygrave 7ab374b4ee No effective change - format only 2015-07-31 22:59:02 +12:00
Robin Bygrave 22d36bd1c4 No effective change - remove unused 2015-07-31 22:55:58 +12:00
Robin Bygrave ebc4d9fdc5 No effective change - format only 2015-07-31 22:52:59 +12:00
Robin Bygrave b1c41a58f2 No effective change - remove unused 2015-07-31 22:51:45 +12:00
Robin Bygrave 40710f788d No effective change - remove unused 2015-07-31 22:49:13 +12:00
Robin Bygrave 5513c46f78 No effective change - format only 2015-07-31 22:47:37 +12:00
Robin Bygrave 8879bd2be8 No effective change - format only 2015-07-31 22:46:20 +12:00
Robin Bygrave 4ab8ced4a3 No effective change - remove unused 2015-07-31 22:45:40 +12:00
Robin Bygrave 5bb9e1b188 No effective change - format only 2015-07-31 22:45:32 +12:00
Robin Bygrave db97d4576f No effective change - code cleanup - remove unused for GenerateDmlRequest 2015-07-31 22:42:28 +12:00
Robin Bygrave c581fa27ab No effective change - code cleanup - remove unused 2015-07-31 22:29:32 +12:00
Robin Bygrave bef4e476d7 No effective change - code cleanup - remove unused 2015-07-31 22:26:44 +12:00
Robin Bygrave e30e35bf4f No effective change - code cleanup - remove unused 2015-07-31 22:25:09 +12:00
Robin Bygrave 2e1f02163c No effective change - code cleanup - remove unused - TableJoin properties 2015-07-31 22:22:57 +12:00
Robin Bygrave 1ce84ec343 No effective change - code cleanup - remove unused - methods 2015-07-31 22:06:34 +12:00
Robin Bygrave 6dc21ce69b No effective change - code cleanup - remove unused - methods 2015-07-31 22:03:45 +12:00
Robin Bygrave 8d5621248f No effective change - code cleanup - remove unused - objects 2015-07-31 22:00:52 +12:00
Robin Bygrave b73cc378b5 No effective change - code cleanup - remove unused - methods 2015-07-31 21:57:26 +12:00
Robin Bygrave 564c7b8317 No effective change - code cleanup - remove unused - methods 2015-07-31 21:55:35 +12:00
Robin Bygrave f4a61cddaf No effective change - code cleanup - remove unused - methods 2015-07-31 21:51:48 +12:00
Robin Bygrave 456f5c1d6a No effective change - code cleanup - remove unused - BeanSqlSelect 2015-07-31 21:48:34 +12:00
Robin Bygrave ae0404b1a7 No effective change - code cleanup - BeanRequest remove unused 2015-07-31 21:46:17 +12:00
Robin Bygrave 31f91e571d No effective change - code cleanup - format only 2015-07-31 21:44:08 +12:00
Robin Bygrave 20acd56bb9 No effective change - code cleanup - format only 2015-07-31 21:43:38 +12:00
Robin Bygrave a764006523 No effective change - code cleanup - remove unused propMap 2015-07-31 21:43:23 +12:00
Robin Bygrave 84b8777c2b No effective change - code cleanup - BeanPropertyAssoc cleanup 2015-07-31 21:41:28 +12:00
Robin Bygrave c0fc7d69a6 No effective change - code cleanup - remove unused validateCascade property 2015-07-31 21:38:05 +12:00
Robin Bygrave 4807ca32be No effective change - code cleanup - remove unused methods 2015-07-31 21:33:05 +12:00
Robin Bygrave 4c841a8f9f No effective change - code cleanup - remove unused BeanPathUpdate 2015-07-31 21:32:36 +12:00
Robin Bygrave 6babebfec5 No effective change - code cleanup - simplify if 2015-07-31 21:28:36 +12:00
Robin Bygrave 660666a28b No effective change - code cleanup - removed unused logger 2015-07-31 21:25:41 +12:00
Robin Bygrave 34550dd778 No effective change - code cleanup - BeanIdList - removed unused methods 2015-07-31 21:24:05 +12:00
Robin Bygrave 64bc0636d7 No effective change - code cleanup - empty method 2015-07-31 21:09:35 +12:00
Robin Bygrave aa199da57d No effective change - code cleanup - SocketCluster 2015-07-31 21:07:22 +12:00
Robin Bygrave b265ffd7d6 No effective change - code cleanup - ResourceSource 2015-07-31 21:02:31 +12:00
Robin Bygrave 00f4aee80a No effective change - code cleanup - remove unused throws exception 2015-07-31 20:58:18 +12:00
Robin Bygrave d6973ed88d No effective change - code cleanup - remove unused throws exception 2015-07-31 20:56:26 +12:00
Robin Bygrave 2ada43f6ba No effective change - code cleanup - remove unused throws exception 2015-07-31 20:53:31 +12:00
Robin Bygrave e800a18b31 No effective change - code cleanup - remove unused methods 2015-07-31 20:49:21 +12:00
Robin Bygrave ea5ceb61ca No effective change - code cleanup - BeanProperty - remove unused extraAttributeMap 2015-07-31 20:45:58 +12:00
Robin Bygrave 972609281f No effective change - code cleanup - BeanProperty - remove unused defaultValue 2015-07-31 20:43:30 +12:00
Robin Bygrave 4ea68ebce4 No effective change - code cleanup - IdBinder - remove unused method 2015-07-31 20:36:18 +12:00
Robin Bygrave d01c6262b6 No effective change - format only 2015-07-31 20:34:17 +12:00
Robin Bygrave 19e3d82d98 No effective change - code cleanup - BeanFkeyProperty 2015-07-31 20:32:27 +12:00
Robin Bygrave f06c1b83a9 No effective change - code cleanup - change return to void 2015-07-31 20:28:41 +12:00
Robin Bygrave ea504a93cf No effective change - code cleanup - remove redundant casts 2015-07-31 20:11:31 +12:00
Robin Bygrave 9fe47194ff No effective change - code cleanup - remove unnecessary boxing 2015-07-31 20:08:30 +12:00
Robin Bygrave ba3b1fea6f No effective change - code cleanup - suppress some warnings 2015-07-31 19:48:59 +12:00
Robin Bygrave 58088b2090 No effective change - code cleanup - remove unnecessary colon 2015-07-31 19:43:12 +12:00
Robin Bygrave cca7a505a3 No effective change - code cleanup - while to foreach on BeanList etc 2015-07-31 19:39:18 +12:00
Robin Bygrave ece7466117 No effective change - code cleanup - while to foreach 2015-07-31 16:51:43 +12:00
Robin Bygrave 3451280679 No effective change - code cleanup - while to foreach 2015-07-31 16:51:12 +12:00
Robin Bygrave bef2894949 No effective change - code cleanup - StringBuffer to StringBuilder 2015-07-31 15:02:46 +12:00
Robin Bygrave 06b6638926 No effective change - code cleanup - string indexOf to contains 2015-07-31 15:00:02 +12:00
Robin Bygrave 53cf6c162c No effective change - code cleanup - simplify if 2015-07-31 14:51:34 +12:00
Robin Bygrave 069b83b78d No effective change - code cleanup - unused imports 2015-07-31 14:37:13 +12:00
Robin Bygrave c0c56c0040 No effective change - code cleanup - remove redundant overrides 2015-07-31 14:14:25 +12:00
Robin Bygrave 92c298b848 No effective change - code cleanup - duplicate throws 2015-07-31 14:08:12 +12:00
Robin Bygrave 831d2a6179 No effective change - add final modifier 2015-07-31 14:07:09 +12:00
Robin Bygrave 90886193c0 No effective change - add final modifier 2015-07-31 14:02:38 +12:00
Robin Bygrave deed0bb01d No effective change - add final modifier 2015-07-31 13:53:10 +12:00
Robin Bygrave 7f2c705b94 No effective change - remove unused 2015-07-31 13:42:09 +12:00
Robin Bygrave 6c0401b191 No effective change - remove unused 2015-07-31 13:34:32 +12:00
Robin Bygrave 331d28b512 No effective change - Code cleanup, remove unused param 2015-07-31 13:33:35 +12:00
Robin Bygrave 9fd936c521 No effective change - Code cleanup, remove redundant variables 2015-07-31 13:29:42 +12:00
Robin Bygrave 4a13fc307b No effective change - Code cleanup, remove unnecessary return 2015-07-31 13:25:54 +12:00
Robin Bygrave adef15ce2b No effective change - Code cleanup, simplified if 2015-07-31 13:23:49 +12:00
Robin Bygrave 88340618af No effective change - Code cleanup, simplified if 2015-07-31 13:20:23 +12:00
Robin Bygrave 49b97887b0 No effective change - Code cleanup,remove unnecessary comma 2015-07-31 13:18:26 +12:00
Robin Bygrave 6843c72149 No effective change - Code cleanup,remove unnecessary public modifier on interfaces 2015-07-31 13:16:36 +12:00
Robin Bygrave f78c217d83 No effective change - Code cleanup,remove unnecessary public modifier on interfaces 2015-07-31 13:11:08 +12:00
Robin Bygrave ede91ecf78 No effective change - Code cleanup,remove unnecessary public modifier on interfaces 2015-07-31 13:08:07 +12:00
Robin Bygrave efe4e69ed1 No effective change - Code cleanup,remove unnecessary public modifier on interfaces 2015-07-31 13:05:22 +12:00
Robin Bygrave 8a3d9edd34 No effective change - Code cleanup, convert unnecessary fields to local vars 2015-07-31 13:00:53 +12:00
Robin Bygrave b9aa76c367 [maven-release-plugin] prepare for next development iteration 2015-07-30 06:45:59 +12:00
Robin Bygrave a49b99156b [maven-release-plugin] prepare release avaje-ebeanorm-6.2.2 2015-07-30 06:45:36 +12:00
Robin Bygrave 54f3dbf35a #361 - ENH: Add ServerConfig expressionEqualsWithNullAsNoop - Can eq ne gt ... methods in ExpressionList treat null value as 1=1 ? 2015-07-30 06:41:51 +12:00
Rob Bygrave 27847424b3 Merge pull request #362 from kdeng/master
Introduce a ClassPathSearchService to support multiple ClassPath search processes with customise search methods
2015-07-30 05:12:47 +12:00
Robin Bygrave a5e94f6ae2 #357 - batch insertAll has no effect when tx commited 2015-07-30 04:23:02 +12:00
Kefeng Deng 9f8b3799eb Merge branch 'master' of github.com:kdeng/avaje-ebeanorm 2015-07-29 21:11:17 +12:00
Kefeng Deng 7734919010 Merge branch 'master' of github.com:kdeng/avaje-ebeanorm 2015-07-29 21:10:45 +12:00
Robin Bygrave 19f40cb2e5 No effective change - format 2015-07-29 20:56:58 +12:00
Robin Bygrave 3d4bd15dac #360 ENH: Add query setDisableLazyLoading(true) ... for use when graph serialised via external library (and you don't want lazy loading to fire) 2015-07-29 20:31:25 +12:00
Kefeng Deng a3c81c3a31 Merge branch 'master' of github.com:kdeng/avaje-ebeanorm
# Conflicts:
#	src/main/java/com/avaje/ebeaninternal/server/core/BootupClassPathSearch.java
#	src/main/java/com/avaje/ebeaninternal/server/util/ClassPathSearch.java
2015-07-29 20:19:43 +12:00
Kefeng Deng 3549f88232 Introduced a service interface to allow multiple ClassPathSearchs with its own customized search way 2015-07-29 20:14:44 +12:00
Robin Bygrave 59d009bc94 No effective change - change to assertJ from hamcrest matchers 2015-07-29 15:54:31 +12:00
Robin Bygrave a6edafbf2d No effective change - add generics type on variable 2015-07-29 15:40:21 +12:00
Robin Bygrave 5fab66204c #359 - ENH: add BeanState.setDisableLazyLoad(boolean) 2015-07-29 15:36:11 +12:00
Kefeng Deng 2fa7c57357 Introduced a service interface to allow multiple ClassPathSearchs with its own customized search way 2015-07-28 21:31:49 +12:00
Robin Bygrave 890e924eb0 [maven-release-plugin] prepare for next development iteration 2015-07-27 23:03:50 +12:00
Robin Bygrave 1c6592a6ec [maven-release-plugin] prepare release avaje-ebeanorm-6.2.1 2015-07-27 23:03:27 +12:00
Robin Bygrave 554c5a7bfc No effective change - format 2015-07-27 23:02:33 +12:00
Robin Bygrave 7a32c50894 Bump pom to 6.2.1-SNAPSHOT 2015-07-27 23:00:12 +12:00
Robin Bygrave 3fa8f04a4c #358 - ENH: Add ServerConfig updateAllPropertiesInBatch with a default of true 2015-07-27 22:59:18 +12:00
Robin Bygrave 962d7f601d #356 - ENH: Change to Binder logging such that the value in the bind log is the converted/bound value 2015-07-27 20:59:40 +12:00
Robin Bygrave f2aa2b5b8b No effective change - format and tidy 2015-07-27 20:47:23 +12:00
Robin Bygrave 87b485cfa4 #355 - ENH: Add notIn(...) expressions. Just to make life easier in those cases 2015-07-27 20:39:34 +12:00
Robin Bygrave 5a55b5235d No effective change - tidy 2015-07-27 15:56:06 +12:00
Robin Bygrave 97adb76eac No effective change - remove unused methods 2015-07-27 15:54:20 +12:00
Robin Bygrave d0d5ab474d No effective change - remove unused import 2015-07-27 15:42:57 +12:00
Robin Bygrave d396f09b3a #296 - ENH: Add to transaction setUpdateAllLoadedProperties() - force update all properties api 2015-07-24 21:56:11 +12:00
Robin Bygrave 3baa5bca46 #352 - Remove deprecated API - ValuePair getValue1() getValue2() ... use getNewValue() getOldValue() 2015-07-24 20:15:13 +12:00
Robin Bygrave c00484026c #351 - ENH: Add diff to Version beans returned from findVersions() 2015-07-24 20:12:26 +12:00
Robin Bygrave 71798afadd #350 - ENH: Add @History findVersions() query - add default ordering to lower sys period desc 2015-07-24 16:52:58 +12:00
Robin Bygrave 1ec2f74df9 #350 - ENH: Add @History findVersions() query ... returning historic versions for a given bean using history view 2015-07-24 16:20:15 +12:00
Robin Bygrave 61a0651439 No effective change - code format 2015-07-24 12:33:35 +12:00
Robin Bygrave eae06059c9 #349 - ENH: Add @WhoCreated @WhoModified ... with CurrentUserProvider interface 2015-07-24 12:33:04 +12:00
Robin Bygrave a1ff9034b6 No effective change - format 2015-07-24 12:09:04 +12:00
Robin Bygrave 1085a8d608 #348 - ENH: Add @WhenCreated and @WhenModified ... as alias to existing @CreatedTimestamp and @UpdatedTimstamp 2015-07-24 10:50:35 +12:00
Robin Bygrave 3a547bf487 #347 - @History support with query.asOf(Timestamp) - javadoc update 2015-07-24 10:24:28 +12:00
Robin Bygrave 82489636d5 #347 - @History support with query.asOf(Timestamp) 2015-07-24 10:18:17 +12:00
Robin Bygrave 3cafb37a73 [maven-release-plugin] prepare for next development iteration 2015-07-20 20:09:05 +12:00
Robin Bygrave b4c7cf529d [maven-release-plugin] prepare release avaje-ebeanorm-6.1.1 2015-07-20 20:08:42 +12:00
Robin Bygrave ba5c67f936 #346 - ENH: Add @Nullable annotation on find by id and findUnique() methods 2015-07-20 20:06:55 +12:00
Robin Bygrave 2bd7995ca1 Bump pom to 6.1.1-SNAPSHOT 2015-07-20 12:55:33 +12:00
Robin Bygrave cc8c860709 Internal DefaultOrmQuery cleanup : timeout can default to 0 (rather than -1) 2015-07-20 12:51:24 +12:00
Robin Bygrave 7d25e31289 No effective change - unused imports 2015-07-20 12:48:08 +12:00
Robin Bygrave 936e56835c Internal SpiQuery : remove unused lazyLoadForParentsIds 2015-07-20 12:47:09 +12:00
Robin Bygrave 0d848e9311 Internal SpiQuery : remove unused context additions 2015-07-20 12:44:26 +12:00
Robin Bygrave b794b6c77e Internal SpiQuery : remove unused convertWhereNaturalKeyToId() 2015-07-20 12:40:08 +12:00
Robin Bygrave f45d240682 #345 - Expose Query.getId() and Query.getBeanType() methods ... (previously on SpiQuery) 2015-07-20 12:24:56 +12:00
Robin Bygrave 1a6f68edd3 No effective change - javadoc 2015-07-20 11:55:24 +12:00
Robin Bygrave 81683c5d2a No effective change - javadoc 2015-07-20 11:50:38 +12:00
Robin Bygrave 2b535d59b8 No effective change - javadoc 2015-07-20 11:41:23 +12:00
Robin Bygrave ae0bbaaaf8 #344 - Remove deprecated annotation @ColumnHstore ... migrate to @DbHstore 2015-07-20 11:38:40 +12:00
Robin Bygrave aaca20f9c3 #343 - Remove deprecated interface BeanFinder<T> ... migrate to BeanFindController 2015-07-20 11:34:05 +12:00
Robin Bygrave 245cbb0ea1 #342 - Remove deprecated method - JsonContext createJsonContext() ... migrate to json() 2015-07-20 11:27:00 +12:00
Robin Bygrave dbe984c668 #341 - Remove deprecated method - insert(Collection<?> beans); ... migrate to insertAll() 2015-07-20 11:22:16 +12:00
Robin Bygrave 89088f9480 #340 - Remove deprecated method - update(Collection<?> beans) ... migrate to updateAll() 2015-07-20 11:18:51 +12:00
Robin Bygrave 80253c4e07 #339 - Remove deprecated method - save(Collection<?> beans, Transaction transaction) ... migrate to saveAll() 2015-07-20 11:15:10 +12:00
Robin Bygrave f96ce11c73 #338 - Remove deprecated method - save(Iterator<?> it, Transaction transaction) ... please change to iterate yourself and save. 2015-07-20 11:11:45 +12:00
Robin Bygrave b8f8cb5ae7 #337 - Remove deprecated method - delete(Class<?> beanType, Collection<?> ids) ... migrate to deleteAll() 2015-07-20 11:07:52 +12:00
Robin Bygrave b8a2aac95a #336 - Remove deprecated method - delete(Iterator<?> it, Transaction transaction) 2015-07-20 10:59:52 +12:00
Robin Bygrave 7b090a6346 #335 - Remove deprecated method - delete(Collection<?> beans) ... migrate to deleteAll() 2015-07-20 10:54:18 +12:00
Robin Bygrave b10c68489f #334 - Remove deprecated method - delete(Iterator<?> it) ... change to iterate yourself and delete() 2015-07-20 10:47:51 +12:00
Robin Bygrave 2dbb2d9911 #333 - Remove deprecated method - save(Iterator<?> it) ... change to iterate yourself and save() 2015-07-20 10:43:37 +12:00
Robin Bygrave b3b4c72a77 #332 - Remove deprecated method - save(Collection<?> beans) ... migrate to saveAll(beans) 2015-07-20 10:39:15 +12:00
Robin Bygrave 1c040e4583 No effective change - code format 2015-07-20 10:24:10 +12:00
Robin Bygrave 9677e585b6 #331 - Remove deprecated method - EbeanServer.findVisit() ... in favor of findEachWhile() or findEach() 2015-07-20 10:22:50 +12:00
Robin Bygrave c53806224f [maven-release-plugin] prepare for next development iteration 2015-07-20 09:53:59 +12:00
Robin Bygrave 6fd5927c64 [maven-release-plugin] prepare release avaje-ebeanorm-5.1.1 2015-07-20 09:53:35 +12:00
Robin Bygrave 920635c6df #326 - API Addition - saveAll(), deleteAll() etc 2015-07-20 09:51:36 +12:00
Robin Bygrave fb1c29b57c Bump pom to 5.1.1-SNAPSHOT 2015-07-20 09:46:31 +12:00
Robin Bygrave 89bed8be67 #326 - API Addition - saveAll(), deleteAll() etc 2015-07-20 09:42:05 +12:00
Robin Bygrave 776e48a501 [maven-release-plugin] prepare for next development iteration 2015-07-20 09:06:01 +12:00
Robin Bygrave 0666a72df7 [maven-release-plugin] prepare release avaje-ebeanorm-4.9.1 2015-07-20 09:05:34 +12:00
Robin Bygrave 55000a3515 No effective change - rename parameter ctx -> parser 2015-07-20 09:01:54 +12:00
Robin Bygrave 8307e259ba bump pom to 4.9.1-SNAPSHOT 2015-07-20 08:50:54 +12:00
Robin Bygrave 95b7574d04 No effective change - format 2015-07-20 08:49:31 +12:00
Robin Bygrave f6466d3211 #280 - ENH: Add ServerConfig.setJsonInclude(...) ALL, NON_NULL, NON_EMPTY 2015-07-20 08:45:46 +12:00
Robin Bygrave 160e4d7dd1 #318 - JSON - toBean error at Transient (with support for #327, #328, #329) 2015-07-19 21:41:20 +12:00
Robin Bygrave a00980c61f #329 - JSON - Remove @Deprecated from JsonWriteOptions ... to support ObjectMapper which can be used for serialize/deserialize of @Transient properties 2015-07-19 21:38:27 +12:00
Robin Bygrave 72d2fcb59e #330 - JSON - Add ebean @JsonIgnore ... with serialize() default false and deserialize() default false 2015-07-19 21:37:37 +12:00
Robin Bygrave 0f503b2a2f No effective change - format code 2015-07-19 09:35:27 +12:00
Robin Bygrave a79e2e786a #324 - on effective change, sync internal name from primaryServer to defaultServer 2015-07-19 09:20:03 +12:00
Robin Bygrave c9ffa2673f #324 - ENH: Add Ebean.getDefaultServer() 2015-07-18 07:46:53 +12:00
Robin Bygrave 0e0fa37f0d #324 - ENH: Add Ebean.getDefaultServer() 2015-07-18 07:46:42 +12:00
Robin Bygrave f7bbd5b3bb No effective change - code format (fix variable names) 2015-07-18 07:35:19 +12:00
Robin Bygrave ba614cd287 No effective change - code format 2015-07-18 07:34:56 +12:00
Robin Bygrave 7d028f3318 [maven-release-plugin] prepare for next development iteration 2015-07-14 23:28:55 +12:00
Robin Bygrave 21b04c244b [maven-release-plugin] prepare release avaje-ebeanorm-4.8.1 2015-07-14 23:28:32 +12:00
Robin Bygrave 957c2def43 bump pom to 4.8.1-SNAPSHOT 2015-07-14 23:24:34 +12:00
Robin Bygrave 35f9cd3821 Bump pom to 4.8.1-SNAPSHOT 2015-07-14 23:18:51 +12:00
Robin Bygrave e95d3304bf #322 - RawSql fetch object with inheritance 2015-07-14 23:09:38 +12:00
rbygrave 0f7c9da5d2 #319 - Beans loaded without an @Id value ... return in NEW state rather than LOADED state (also refer to #317) 2015-07-09 22:18:03 +12:00
rbygrave b4008da70c #317 - RawSql getting error - Caused by: java.sql.SQLException: Column Index out of range, 0 < 1. 2015-07-09 21:44:45 +12:00
rbygrave 34a0f16c74 No effective change - bump mysql-connector-java test dependency version 2015-07-07 23:07:10 +12:00
Rob Bygrave a880109201 Merge pull request #316 from castovoid/master
Resolve NullPointerException on JtaTransacionManager constructor
2015-06-30 21:17:27 +12:00
Rob Bygrave 0607151ac8 Merge pull request #315 from ossd/patch-1
Update ScalarTypeEnumStandard.java
2015-06-30 21:15:47 +12:00
Leone Parise 5c4ad4c01c Resolve NullPointerException on JtaTransacionManager 2015-06-30 01:01:35 -03:00
ossd 3564504e00 Update ScalarTypeEnumStandard.java
Using toString() to calculate the Enum length is wrong. If you overwrite the Enum's toString() the length may be shorter. In this situation, the ddl script will create a to small varchar field for the value and you get an exception on save
2015-06-29 22:36:24 +02:00
rbygrave 49babef495 #314 - ServerCache API - change from int to long for ServerCacheStatistics (hitCount, missCount) and ServerCache remove putIfAbsent() method 2015-06-30 00:56:11 +12:00
rbygrave 9e3362d004 No effective change - tidy 2015-06-26 23:05:40 +12:00
Rob Bygrave 3f0dcdb6d1 Update README.md 2015-06-25 00:12:16 +12:00
rbygrave 481116251d [maven-release-plugin] prepare for next development iteration 2015-06-24 23:50:22 +12:00
1469 changed files with 98376 additions and 35293 deletions
+6 -1
View File
@@ -1,13 +1,18 @@
*.autofetch
*.sql
*create-all.sql
*drop-all.sql
*.orig
.classpath
.project
.settings/
target/
logs/
log/
ebean-autotune.xml
ebean-profiling*.xml
/db
/mydb.db
!src/test/ddl-review/*.sql
# Intellij project files
+32
View File
@@ -0,0 +1,32 @@
sudo: required
language: java
jdk:
- oraclejdk8
git:
depth: 3
addons:
postgresql: "9.4"
services:
- postgresql
before_script:
- ./.travis/setup_database
env:
- EBEAN_DB=h2
- EBEAN_DB=pg
install: true
script:
- mvn clean test
after_failure:
- ./.travis/print_surefire_reports
cache:
directories:
- $HOME/.m2
+10
View File
@@ -0,0 +1,10 @@
#!/bin/sh
echo "\n=== SUREFIRE REPORTS ===\n"
for file in target/surefire-reports/*.txt
do
echo ${file}
cat ${file}
echo
done
+14
View File
@@ -0,0 +1,14 @@
#!/bin/sh
echo "\n=== SETUP DATABASE ===\n"
#set -e
#set -x
# Setup postgres' users and databases
sudo -u postgres psql -c "CREATE USER unit WITH PASSWORD 'unit';"
sudo -u postgres psql -c 'CREATE DATABASE unit WITH OWNER unit;'
sudo -u postgres psql unit -c 'CREATE EXTENSION hstore;'
sudo -u postgres psql unit -c 'CREATE EXTENSION pgcrypto;'
#sudo -u postgres psql test2 -c 'CREATE EXTENSION postgis;'
+6 -14
View File
@@ -1,19 +1,11 @@
[![Stories in Ready](https://badge.waffle.io/ebean-orm/avaje-ebeanorm.png?label=ready&title=Ready)](https://waffle.io/ebean-orm/avaje-ebeanorm)
* [![Maven Central : avaje-ebeanorm](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebeanorm/avaje-ebeanorm/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebeanorm/avaje-ebeanorm) - avaje-ebeanorm
* [![Maven Central : avaje-ebeanorm-agent](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebeanorm/avaje-ebeanorm-agent/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebeanorm/avaje-ebeanorm-agent) - avaje-ebeanorm-agent
* [![Maven Central : avaje-ebeanorm-agent](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebeanorm/avaje-ebeanorm-mavenenhancer/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebeanorm/avaje-ebeanorm-mavenenhancer) - avaje-ebeanorm-mavenenhancer
Ebean ORM
==============
Project Website
----------------
[http://ebean-orm.github.io/](http://ebean-orm.github.io/ "Ebean ORM's Website")
Maven Dependency
----------------
<dependency>
<groupId>org.avaje.ebeanorm</groupId>
<artifactId>avaje-ebeanorm</artifactId>
<version>4.7.1</version>
</dependency>
[https://ebean-orm.github.io/](http://ebean-orm.github.io/ "Ebean ORM's Website")
[Maven central - avaje-ebeanorm](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.avaje.ebeanorm%22%20AND%20a%3A%22avaje-ebeanorm%22 "maven central ebeanorm")
+50 -40
View File
@@ -9,11 +9,11 @@
<groupId>org.avaje.ebeanorm</groupId>
<artifactId>avaje-ebeanorm</artifactId>
<version>4.7.3</version>
<version>7.2.2</version>
<packaging>jar</packaging>
<name>avaje-ebeanorm</name>
<url>http://www.avaje.org</url>
<url>http://ebean-orm.github.io/</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -43,6 +43,12 @@
<dependencies>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>13.0</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
@@ -55,11 +61,19 @@
<version>1.7.7</version>
</dependency>
<!-- provided scope for Spring boot loader classpath scanning support -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
<version>1.2.7.RELEASE</version>
<scope>provided</scope>
</dependency>
<!-- provided scope for JsonNode support -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
<version>2.6.5</version>
<scope>provided</scope>
</dependency>
@@ -67,7 +81,7 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.3</version>
<version>2.6.5</version>
</dependency>
<dependency>
@@ -103,15 +117,29 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1201-jdbc41</version>
<version>9.4-1202-jdbc41</version>
<scope>provided</scope>
</dependency>
<!--<dependency>-->
<!--<groupId>oracle</groupId>-->
<!--<artifactId>oracle-jdbc</artifactId>-->
<!--<version>7.0</version>-->
<!--<scope>test</scope>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>microsoft</groupId>-->
<!--<artifactId>sqlserver-jdbc</artifactId>-->
<!--<version>4.2</version>-->
<!--<scope>test</scope>-->
<!--</dependency>-->
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>2.1.0</version>
<scope>test</scope>
<version>2.4.0</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -124,21 +152,23 @@
<dependency>
<groupId>org.avaje.ebeanorm</groupId>
<artifactId>avaje-ebeanorm-agent</artifactId>
<version>4.5.1</version>
<version>4.9.2</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>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.182</version>
<scope>test</scope>
<version>1.4.189</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.7.2</version>
<version>3.8.11.2</version>
<scope>test</scope>
</dependency>
@@ -152,36 +182,16 @@
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.27</version>
<version>5.1.36</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-integration</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.9</version>
<groupId>org.avaje.composite</groupId>
<artifactId>avaje-composite-testing</artifactId>
<version>1.1</version>
<scope>test</scope>
<type>pom</type>
</dependency>
<dependency>
@@ -209,7 +219,7 @@
<plugin>
<groupId>org.avaje.ebeanorm</groupId>
<artifactId>avaje-ebeanorm-mavenenhancer</artifactId>
<version>4.5.1</version>
<version>4.9.2</version>
<executions>
<!-- Not going to enhance Model bean -->
<execution>
@@ -263,11 +273,11 @@
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<doctitle>Ebean 4</doctitle>
<doctitle>Ebean 6</doctitle>
<overview>src/main/java/com/avaje/ebean/overview.html</overview>
<source>1.8</source>
<doclet>org.avaje.doclet.PygmentsDoclet</doclet>
<excludePackageNames>com.avaje.ebeaninternal.*:com.avaje.ebean.util</excludePackageNames>
<excludePackageNames>com.avaje.ebeaninternal.*:com.avaje.ebean.util:com.avaje.ebean.dbmigration.ddlgeneration:com.avaje.ebean.dbmigration.migration:com.avaje.ebean.dbmigration.migrationreader:com.avaje.ebean.dbmigration.model</excludePackageNames>
<docletArtifact>
<groupId>org.avaje</groupId>
<artifactId>pygments-doclet</artifactId>
@@ -1,137 +0,0 @@
package com.avaje.ebean;
/**
* Administrative control of Autofetch during runtime.
*/
public interface AdminAutofetch {
/**
* Return true if profiling is enabled.
*/
boolean isProfiling();
/**
* Set to true to enable profiling.
*/
void setProfiling(boolean enable);
/**
* Return true if autoFetch automatic query tuning is enabled.
*/
boolean isQueryTuning();
/**
* Set to true to enable autoFetch automatic query tuning.
*/
void setQueryTuning(boolean enable);
/**
* Returns the rate which profiling is collected. This is an int between 0 and
* 100.
*/
double getProfilingRate();
/**
* Set the rate at which profiling is collected after the base.
*
* @param rate
* a int between 0 and 100.
*/
void setProfilingRate(double rate);
/**
* Return the number of queries profiled after which profiling is collected at
* a percentage rate.
*/
int getProfilingBase();
/**
* Set a base number of queries to profile per query point.
* <p>
* After this amount of profiling has been obtained profiling is collected at
* the Profiling Percentage rate.
* </p>
*/
void setProfilingBase(int profilingBase);
/**
* Return the minimum number of queries profiled before autoFetch will start
* automatically tuning the queries.
* <p>
* This could be one which means start autoFetch tuning after the first
* profiling information is collected.
* </p>
*/
int getProfilingMin();
/**
* Set the minimum number of queries profiled per query point before autoFetch
* will automatically tune the queries.
* <p>
* Increasing this number will mean more profiling is collected before
* autoFetch starts tuning the query.
* </p>
*/
void setProfilingMin(int autoFetchMinThreshold);
/**
* Fire a garbage collection (hint to the JVM). Assuming garbage collection
* fires this will gather the usage profiling information.
*/
String collectUsageViaGC();
/**
* This will take the current profiling information and update the "tuned
* query detail".
* <p>
* This is done periodically and can also be manually invoked.
* </p>
*
* @return a summary of the updates that occurred
*/
String updateTunedQueryInfo();
/**
* Clear all the tuned query info.
* <p>
* Should only need do this for testing and playing around.
* </p>
*
* @return the amount of tuned query information cleared.
*/
int clearTunedQueryInfo();
/**
* Clear all the profiling information.
* <p>
* This means the profiling information will need to be re-gathered.
* </p>
* <p>
* Should only need do this for testing and playing around.
* </p>
*
* @return the amount of profiled information cleared.
*/
int clearProfilingInfo();
/**
* Clear the query execution statistics.
*/
void clearQueryStatistics();
/**
* Return the number of queries tuned by AutoFetch.
*/
int getTotalTunedQueryCount();
/**
* Return the size of the TuneQuery map.
*/
int getTotalTunedQuerySize();
/**
* Return the size of the profile map.
*/
int getTotalProfileSize();
}
@@ -0,0 +1,24 @@
package com.avaje.ebean;
/**
* Administrative control of AutoTune during runtime.
*/
public interface AutoTune {
/**
* Fire a garbage collection (hint to the JVM). Assuming garbage collection
* fires this will gather remaining usage profiling information.
*/
void collectProfiling();
/**
* Output the profiling.
* <p>
* When profiling updates are applied to tuning at runtime this reports all tuning and profiling combined.
* When profiling is not applied at runtime then this reports the diff report with new and diff entries relative
* to the existing tuning.
* </p>
*/
void reportProfiling();
}
@@ -33,6 +33,38 @@ public interface BeanState {
*/
boolean isDirty();
/**
* This can be called with true to disable lazy loading on the bean.
*/
void setDisableLazyLoad(boolean disableLazyLoading);
/**
* Set the loaded state of the property given it's name.
*
* <p>
* Typically this would be used to set the loaded state of a property
* to false to ensure that the specific property is excluded from a
* stateless update.
* </p>
*
* <pre>{@code
*
* // populate a bean via say JSON
* User user = ...;
*
* // set loaded state on the email property to false so that
* // the email property is not included in a stateless update
* Ebean.getBeanState(user).setPropertyLoaded("email", false);
*
* user.update();
*
* }</pre>
*
*
* This will throw an IllegalArgumentException if the property is unknown.
*/
void setPropertyLoaded(String propertyName, boolean loaded);
/**
* For partially populated beans returns the properties that are loaded on the
* bean.
@@ -80,7 +80,7 @@ public interface CallableSql {
/**
* Return the label that is put into the transaction log.
*/
public String getLabel();
String getLabel();
/**
* Set the label that is put in the transaction log.
@@ -45,7 +45,7 @@ final class DRawSqlColumnsParser {
String colInfo = sqlSelect.substring(start, pos++);
colInfo = colInfo.trim();
String[] split = colInfo.split(" ");
String[] split = colInfo.split("\\s(?=[^\\)]*(?:\\(|$))");
if (split.length > 1) {
ArrayList<String> tmp = new ArrayList<String>(split.length);
for (int i = 0; i < split.length; i++) {
@@ -80,17 +80,18 @@ final class DRawSqlColumnsParser {
return new ColumnMapping.Column(indexPos++, sb.toString(), split[split.length - 1]);
}
private int nextComma() {
private void nextComma() {
boolean inQuote = false;
int inbrackets = 0;
while (pos < end) {
char c = sqlSelect.charAt(pos);
if (c == '\'') {
inQuote = !inQuote;
} else if (!inQuote && c == ',') {
return pos;
if (c == '\'') inQuote = !inQuote;
else if (c == '(') inbrackets++;
else if (c == ')') inbrackets--;
else if (!inQuote && inbrackets == 0 && c == ',') {
return;
}
pos++;
}
return pos;
}
}
@@ -24,7 +24,7 @@ class DRawSqlParser {
private int placeHolderAndWhere;
private int placeHolderHaving;
private int placeHolderAndHaving;
private boolean hasPlaceHolders;
private final boolean hasPlaceHolders;
private int selectPos = -1;
private int distinctPos = -1;
@@ -46,6 +46,7 @@ class DRawSqlParser {
private DRawSqlParser(String sqlString) {
sqlString = sqlString.trim();
sqlString = sqlString.replace('\n',' ');
this.sql = sqlString;
this.hasPlaceHolders = findAndRemovePlaceHolders();
this.textParser = new SimpleTextParser(sqlString);
@@ -70,7 +71,7 @@ class DRawSqlParser {
preFrom = trimSelectKeyword(preFrom);
return new Sql(sql.hashCode(), preFrom, preWhere, whereExprAnd, preHaving, havingExprAnd, orderByPrefix, orderBySql, (distinctPos > -1));
return new Sql(sql, preFrom, preWhere, whereExprAnd, preHaving, havingExprAnd, orderByPrefix, orderBySql, (distinctPos > -1));
}
/**
@@ -98,19 +99,7 @@ class DRawSqlParser {
}
private boolean hasPlaceHolders() {
if (placeHolderWhere > -1) {
return true;
}
if (placeHolderAndWhere > -1) {
return true;
}
if (placeHolderHaving > -1) {
return true;
}
if (placeHolderAndHaving > -1) {
return true;
}
return false;
return placeHolderWhere > -1 || placeHolderAndWhere > -1 || placeHolderHaving > -1 || placeHolderAndHaving > -1;
}
/**
@@ -132,8 +121,7 @@ class DRawSqlParser {
// trim of distinct keyword
String distinct = preWhereExprSql.substring(0, 9);
if (!distinct.equalsIgnoreCase("distinct ")) {
throw new RuntimeException("Expecting [" + preWhereExprSql
+ "] to start with \"select distinct\"");
throw new RuntimeException("Expecting [" + preWhereExprSql + "] to start with \"select distinct\"");
}
preWhereExprSql = preWhereExprSql.substring(9);
}
@@ -0,0 +1,94 @@
package com.avaje.ebean;
/**
* Bean holding the details to update the document store.
*/
public final class DocStoreQueueEntry {
/**
* Action to either update or delete a document from the index.
*/
public enum Action {
/**
* Action is to update a document in the doc store.
*/
INDEX(1),
/**
* Action is to delete a document from the doc store..
*/
DELETE(2),
/**
* An update is required based on a change to a nested/embedded object at a given path.
*/
NESTED(3);
int value;
Action(int value) {
this.value = value;
}
/**
* Return the value associated with this action type.
*/
public int getValue() {
return value;
}
}
final Action type;
final String queueId;
final String path;
final Object beanId;
/**
* Construct for an INDEX or DELETE action.
*/
public DocStoreQueueEntry(Action type, String queueId, Object beanId) {
this(type, queueId, null, beanId);
}
/**
* Construct for an NESTED/embedded path invalidation action.
*/
public DocStoreQueueEntry(Action type, String queueId, String path, Object beanId) {
this.type = type;
this.queueId = queueId;
this.path = path;
this.beanId = beanId;
}
/**
* Return the event type.
*/
public Action getType() {
return type;
}
/**
* Return the associate queueId.
*/
public String getQueueId() {
return queueId;
}
/**
* Return the path if this is a nested update.
*/
public String getPath() {
return path;
}
/**
* Return the bean id (which matches the document id).
*/
public Object getBeanId() {
return beanId;
}
}
@@ -0,0 +1,270 @@
package com.avaje.ebean;
import com.avaje.ebeanservice.docstore.api.DocQueryRequest;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.List;
/**
* Document storage operations.
*/
public interface DocumentStore {
/**
* Update the associated document store using the result of the query.
* <p>
* This will execute the query against the database creating a document for each
* bean graph and sending this to the document store.
* </p>
* <p>
* Note that the select and fetch paths of the query is set for you to match the
* document structure needed based on <code>@DocStore</code> and <code>@DocStoreEmbedded</code>
* so what this query requires is the predicates only.
* </p>
* <p>
* This query will be executed using findEach so it is safe to use a query
* that will fetch a lot of beans. The default bulkBatchSize is used.
* </p>
*
* @param query The query that selects object to send to the document store.
*/
<T> void indexByQuery(Query<T> query);
/**
* Update the associated document store index using the result of the query additionally specifying a
* bulkBatchSize to use for sending the messages to ElasticSearch.
*
* @param query The query that selects object to send to the document store.
* @param bulkBatchSize The batch size to use when bulk sending to the document store.
*/
<T> void indexByQuery(Query<T> query, int bulkBatchSize);
/**
* Update the document store for all beans of this type.
* <p>
* This is the same as indexByQuery where the query has no predicates and so fetches all rows.
* </p>
*/
void indexAll(Class<?> beanType);
/**
* Return the bean by fetching it's content from the document store.
* If the document is not found null is returned.
* <p>
* Typically this is called indirectly by findUnique() on the query.
* </p>
* <pre>{@code
*
* Customer customer =
* server.find(Customer.class)
* .setUseDocStore(true)
* .setId(42)
* .findUnique();
*
* }</pre>
*/
@Nullable
<T> T find(DocQueryRequest<T> request);
/**
* Execute the find list query. This request is prepared to execute secondary queries.
* <p>
* Typically this is called indirectly by findList() on the query that has setUseDocStore(true).
* </p>
* <pre>{@code
*
* List<Customer> newCustomers =
* server.find(Customer.class)
* .setUseDocStore(true)
* .where().eq("status, Customer.Status.NEW)
* .findList();
*
* }</pre>
*/
<T> List<T> findList(DocQueryRequest<T> request);
/**
* Execute the query against the document store returning the paged list.
* <p>
* The query should have <code>firstRow</code> or <code>maxRows</code> set prior to calling this method.
* </p>
* <p>
* Typically this is called indirectly by findPagedList() on the query that has setUseDocStore(true).
* </p>
*
* <pre>{@code
*
* PagedList<Customer> newCustomers =
* server.find(Customer.class)
* .setUseDocStore(true)
* .where().eq("status, Customer.Status.NEW)
* .setMaxRows(50)
* .findPagedList();
*
* }</pre>
*
*/
<T> PagedList<T> findPagedList(DocQueryRequest<T> request);
/**
* Execute the query against the document store with the expectation of a large set of results
* that are processed in a scrolling resultSet fashion.
* <p>
* For example, with the ElasticSearch doc store this uses SCROLL.
* </p>
* <p>
* Typically this is called indirectly by findEach() on the query that has setUseDocStore(true).
* </p>
*
* <pre>{@code
*
* server.find(Order.class)
* .setUseDocStore(true)
* .where()... // perhaps add predicates
* .findEach(new QueryEachConsumer<Order>() {
* @Override
* public void accept(Order bean) {
* // process the bean
* }
* });
*
* }</pre>
*/
<T> void findEach(DocQueryRequest<T> query, QueryEachConsumer<T> consumer);
/**
* Execute the query against the document store with the expectation of a large set of results
* that are processed in a scrolling resultSet fashion.
* <p>
* Unlike findEach() this provides the opportunity to stop iterating through the large query.
* </p>
* <p>
* For example, with the ElasticSearch doc store this uses SCROLL.
* </p>
* <p>
* Typically this is called indirectly by findEachWhile() on the query that has setUseDocStore(true).
* </p>
*
*
* <pre>{@code
*
* server.find(Order.class)
* .setUseDocStore(true)
* .where()... // perhaps add predicates
* .findEachWhile(new QueryEachWhileConsumer<Order>() {
* @Override
* public void accept(Order bean) {
* // process the bean
*
* // return true to continue, false to stop
* // boolean shouldContinue = ...
* return shouldContinue;
* }
* });
*
* }</pre>
*/
<T> void findEachWhile(DocQueryRequest<T> query, QueryEachWhileConsumer<T> consumer);
/**
* Process the queue entries sending updates to the document store or queuing them for later processing.
*/
long process(List<DocStoreQueueEntry> queueEntries) throws IOException;
/**
* Drop the index from the document store (similar to DDL drop table).
*
* <pre>{@code
*
* DocumentStore documentStore = server.docStore();
*
* documentStore.dropIndex("product_copy");
*
* }</pre>
*
*/
void dropIndex(String indexName);
/**
* Create an index given a mapping file as a resource in the classPath (similar to DDL create table).
*
* <pre>{@code
*
* DocumentStore documentStore = server.docStore();
*
* // uses product_copy.mapping.json resource
* // ... to define mappings for the index
*
* documentStore.createIndex("product_copy", null);
*
* }</pre>
*
* @param indexName the name of the new index
* @param alias the alias of the index
*/
void createIndex(String indexName, String alias);
/**
* Copy the index to a new index.
* <p>
* This copy process does not use the database but instead will copy from the source index to a destination index.
* </p>
*
* <pre>{@code
*
* long copyCount = documentStore.copyIndex(Product.class, "product_copy");
*
* }</pre>
*
* @param beanType The bean type of the source index
* @param newIndex The name of the index to copy to
* @return the number of documents copied to the new index
*/
long copyIndex(Class<?> beanType, String newIndex);
/**
* Copy entries from an index to a new index but limiting to documents that have been
* modified since the sinceEpochMillis time.
* <p>
* To support this the document needs to have a <code>@WhenModified</code> property.
* </p>
*
* <pre>{@code
*
* long copyCount = documentStore.copyIndex(Product.class, "product_copy", sinceMillis);
*
* }</pre>
*
* @param beanType The bean type of the source index
* @param newIndex The name of the index to copy to
* @return the number of documents copied to the new index
*/
long copyIndex(Class<?> beanType, String newIndex, long sinceEpochMillis);
/**
* Copy from a source index to a new index taking only the documents
* matching the given query.
*
* <pre>{@code
*
* // predicates to select the source documents to copy
* Query<Product> query = server.find(Product.class)
* .where()
* .ge("whenModified", new Timestamp(since))
* .ge("name", "A")
* .lt("name", "D")
* .query();
*
* // copy from the source index to "product_copy" index
* long copyCount = documentStore.copyIndex(query, "product_copy", 1000);
*
* }</pre>
*
* @param query The query to select the source documents to copy
* @param newIndex The target index to copy the documents to
* @param bulkBatchSize The ElasticSearch bulk batch size, if 0 uses the default.
* @return The number of documents copied to the new index.
*/
long copyIndex(Query<?> query, String newIndex, int bulkBatchSize);
}
+125 -112
View File
@@ -2,7 +2,6 @@ package com.avaje.ebean;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -10,6 +9,7 @@ import java.util.concurrent.ConcurrentHashMap;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -22,7 +22,7 @@ import com.avaje.ebean.text.json.JsonContext;
/**
* This Ebean object is effectively a singleton that holds a map of registered
* {@link EbeanServer}s. It additionally provides a convenient way to use the
* 'default/primary' EbeanServer.
* 'default' EbeanServer.
* <p>
* If you are using a Dependency Injection framework such as
* <strong>Spring</strong> or <strong>Guice</strong> you will probably
@@ -101,7 +101,7 @@ import com.avaje.ebean.text.json.JsonContext;
* specific database.
* </p>
*
* <pre> {@code
* <pre>{@code
*
* // Get access to the Human Resources EbeanServer/Database
* EbeanServer hrDb = Ebean.getServer("hr");
@@ -146,9 +146,9 @@ public final class Ebean {
private final Object monitor = new Object();
/**
* The 'default/primary' EbeanServer.
* The 'default' EbeanServer.
*/
private EbeanServer primaryServer;
private EbeanServer defaultServer;
private ServerManager() {
@@ -162,31 +162,31 @@ public final class Ebean {
} else {
// look to see if there is a default server defined
String primaryName = PrimaryServer.getPrimaryServerName();
logger.debug("primaryName:" + primaryName);
if (primaryName != null && primaryName.trim().length() > 0) {
primaryServer = getWithCreate(primaryName.trim());
String defaultName = PrimaryServer.getDefaultServerName();
logger.debug("defaultName:" + defaultName);
if (defaultName != null && defaultName.trim().length() > 0) {
defaultServer = getWithCreate(defaultName.trim());
}
}
} catch (RuntimeException e) {
} catch (Throwable e) {
logger.error("Error trying to create the default EbeanServer", e);
throw e;
throw new RuntimeException(e);
}
}
private EbeanServer getPrimaryServer() {
if (primaryServer == null) {
private EbeanServer getDefaultServer() {
if (defaultServer == null) {
String msg = "The default EbeanServer has not been defined?";
msg += " This is normally set via the ebean.datasource.default property.";
msg += " Otherwise it should be registered programatically via registerServer()";
msg += " Otherwise it should be registered programmatically via registerServer()";
throw new PersistenceException(msg);
}
return primaryServer;
return defaultServer;
}
private EbeanServer get(String name) {
if (name == null || name.length() == 0) {
return primaryServer;
return defaultServer;
}
// non-synchronized read
EbeanServer server = concMap.get(name);
@@ -217,16 +217,16 @@ public final class Ebean {
/**
* Register a server so we can get it by its name.
*/
private void register(EbeanServer server, boolean isPrimaryServer) {
registerWithName(server.getName(), server, isPrimaryServer);
private void register(EbeanServer server, boolean isDefaultServer) {
registerWithName(server.getName(), server, isDefaultServer);
}
private void registerWithName(String name, EbeanServer server, boolean isPrimaryServer) {
private void registerWithName(String name, EbeanServer server, boolean isDefaultServer) {
synchronized (monitor) {
concMap.put(name, server);
syncMap.put(name, server);
if (isPrimaryServer) {
primaryServer = server;
if (isDefaultServer) {
defaultServer = server;
}
}
}
@@ -254,12 +254,22 @@ public final class Ebean {
* }</pre>
*
* @param name
* the name of the server, use null for the 'default server'
* the name of the server, can use null for the 'default server'
*/
public static EbeanServer getServer(String name) {
return serverMgr.get(name);
}
/**
* Returns the default EbeanServer.
* <p>
* This is equivalent to <code>Ebean.getServer(null);</code>
* </p>
*/
public static EbeanServer getDefaultServer() {
return serverMgr.getDefaultServer();
}
/**
* Return the ExpressionFactory from the default server.
* <p>
@@ -278,23 +288,23 @@ public final class Ebean {
* </p>
*/
public static ExpressionFactory getExpressionFactory() {
return serverMgr.getPrimaryServer().getExpressionFactory();
return serverMgr.getDefaultServer().getExpressionFactory();
}
/**
* Register the server with this Ebean singleton. Specify if the registered
* server is the primary/default server.
*/
public static void register(EbeanServer server, boolean isPrimaryServer) {
serverMgr.register(server, isPrimaryServer);
public static void register(EbeanServer server, boolean defaultServer) {
serverMgr.register(server, defaultServer);
}
/**
* Backdoor for registering a mock implementation of EbeanServer as the default server.
*/
protected static EbeanServer mock(String name, EbeanServer server, boolean isPrimaryServer) {
EbeanServer originalPrimaryServer = serverMgr.primaryServer;
serverMgr.registerWithName(name, server, isPrimaryServer);
protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
EbeanServer originalPrimaryServer = serverMgr.defaultServer;
serverMgr.registerWithName(name, server, defaultServer);
return originalPrimaryServer;
}
@@ -311,7 +321,7 @@ public final class Ebean {
* </p>
*/
public static Object nextId(Class<?> beanType) {
return serverMgr.getPrimaryServer().nextId(beanType);
return serverMgr.getDefaultServer().nextId(beanType);
}
/**
@@ -359,7 +369,7 @@ public final class Ebean {
* </p>
*/
public static Transaction beginTransaction() {
return serverMgr.getPrimaryServer().beginTransaction();
return serverMgr.getDefaultServer().beginTransaction();
}
/**
@@ -370,7 +380,7 @@ public final class Ebean {
*
*/
public static Transaction beginTransaction(TxIsolation isolation) {
return serverMgr.getPrimaryServer().beginTransaction(isolation);
return serverMgr.getDefaultServer().beginTransaction(isolation);
}
/**
@@ -425,7 +435,7 @@ public final class Ebean {
* }</pre>
*/
public static Transaction beginTransaction(TxScope scope){
return serverMgr.getPrimaryServer().beginTransaction(scope);
return serverMgr.getDefaultServer().beginTransaction(scope);
}
/**
@@ -433,7 +443,7 @@ public final class Ebean {
* in scope.
*/
public static Transaction currentTransaction() {
return serverMgr.getPrimaryServer().currentTransaction();
return serverMgr.getDefaultServer().currentTransaction();
}
/**
@@ -446,21 +456,21 @@ public final class Ebean {
* @throws PersistenceException if there is no currently active transaction
*/
public static void register(TransactionCallback transactionCallback) throws PersistenceException {
serverMgr.getPrimaryServer().register(transactionCallback);
serverMgr.getDefaultServer().register(transactionCallback);
}
/**
* Commit the current transaction.
*/
public static void commitTransaction() {
serverMgr.getPrimaryServer().commitTransaction();
serverMgr.getDefaultServer().commitTransaction();
}
/**
* Rollback the current transaction.
*/
public static void rollbackTransaction() {
serverMgr.getPrimaryServer().rollbackTransaction();
serverMgr.getDefaultServer().rollbackTransaction();
}
/**
@@ -489,7 +499,7 @@ public final class Ebean {
* }</pre>
*/
public static void endTransaction() {
serverMgr.getPrimaryServer().endTransaction();
serverMgr.getDefaultServer().endTransaction();
}
/**
@@ -500,7 +510,7 @@ public final class Ebean {
* </p>
*/
public static Map<String, ValuePair> diff(Object a, Object b) {
return serverMgr.getPrimaryServer().diff(a, b);
return serverMgr.getDefaultServer().diff(a, b);
}
/**
@@ -523,7 +533,6 @@ public final class Ebean {
* public class Order { ...
*
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
* @JoinColumn(name="order_id")
* List<OrderDetail> details;
* ...
* }
@@ -537,7 +546,7 @@ public final class Ebean {
* </p>
*/
public static void save(Object bean) throws OptimisticLockException {
serverMgr.getPrimaryServer().save(bean);
serverMgr.getDefaultServer().save(bean);
}
/**
@@ -545,14 +554,14 @@ public final class Ebean {
* want to explicitly insert it.
*/
public static void insert(Object bean) {
serverMgr.getPrimaryServer().insert(bean);
serverMgr.getDefaultServer().insert(bean);
}
/**
* Insert a collection of beans.
*/
public static void insert(Collection<?> beans) {
serverMgr.getPrimaryServer().insert(beans);
public static void insertAll(Collection<?> beans) {
serverMgr.getDefaultServer().insertAll(beans);
}
/**
@@ -576,7 +585,7 @@ public final class Ebean {
* }</pre>
*/
public static void markAsDirty(Object bean) throws OptimisticLockException {
serverMgr.getPrimaryServer().markAsDirty(bean);
serverMgr.getDefaultServer().markAsDirty(bean);
}
/**
@@ -616,28 +625,21 @@ public final class Ebean {
* @see ServerConfig#setUpdateChangesOnly(boolean)
*/
public static void update(Object bean) throws OptimisticLockException {
serverMgr.getPrimaryServer().update(bean);
serverMgr.getDefaultServer().update(bean);
}
/**
* Update the beans in the collection.
*/
public static void update(Collection<?> beans) throws OptimisticLockException {
serverMgr.getPrimaryServer().update(beans);
}
/**
* Save all the beans from an Iterator.
*/
public static int save(Iterator<?> iterator) throws OptimisticLockException {
return serverMgr.getPrimaryServer().save(iterator);
public static void updateAll(Collection<?> beans) throws OptimisticLockException {
serverMgr.getDefaultServer().updateAll(beans);
}
/**
* Save all the beans from a Collection.
*/
public static int save(Collection<?> beans) throws OptimisticLockException {
return serverMgr.getPrimaryServer().save(beans);
public static int saveAll(Collection<?> beans) throws OptimisticLockException {
return serverMgr.getDefaultServer().saveAll(beans);
}
/**
@@ -651,7 +653,7 @@ public final class Ebean {
* @return the number of associations deleted (from the intersection table).
*/
public static int deleteManyToManyAssociations(Object ownerBean, String propertyName) {
return serverMgr.getPrimaryServer().deleteManyToManyAssociations(ownerBean, propertyName);
return serverMgr.getDefaultServer().deleteManyToManyAssociations(ownerBean, propertyName);
}
/**
@@ -669,7 +671,7 @@ public final class Ebean {
* </p>
*/
public static void saveManyToManyAssociations(Object ownerBean, String propertyName) {
serverMgr.getPrimaryServer().saveManyToManyAssociations(ownerBean, propertyName);
serverMgr.getDefaultServer().saveManyToManyAssociations(ownerBean, propertyName);
}
/**
@@ -689,46 +691,65 @@ public final class Ebean {
* the property we want to save
*/
public static void saveAssociation(Object ownerBean, String propertyName) {
serverMgr.getPrimaryServer().saveAssociation(ownerBean, propertyName);
serverMgr.getDefaultServer().saveAssociation(ownerBean, propertyName);
}
/**
* Delete the bean.
* <p>
* This will return true if the bean was deleted successfully or JDBC batch is being used.
* </p>
* <p>
* If there is no current transaction one will be created and committed for
* you automatically.
* </p>
* <p>
* If the bean is configured with <code>@SoftDelete</code> then this will perform a soft
* delete rather than a hard/permanent delete.
* </p>
* <p>
* If the Bean does not have a version property (or loaded version property) and
* the bean does not exist then this returns false indicating that nothing was
* deleted. Note that, if JDBC batch mode is used then this always returns true.
* </p>
*/
public static void delete(Object bean) throws OptimisticLockException {
serverMgr.getPrimaryServer().delete(bean);
public static boolean delete(Object bean) throws OptimisticLockException {
return serverMgr.getDefaultServer().delete(bean);
}
/**
* Delete the bean in permanent fashion (will not use soft delete).
*/
public static boolean deletePermanent(Object bean) throws OptimisticLockException {
return serverMgr.getDefaultServer().deletePermanent(bean);
}
/**
* Delete the bean given its type and id.
*/
public static int delete(Class<?> beanType, Object id) {
return serverMgr.getPrimaryServer().delete(beanType, id);
return serverMgr.getDefaultServer().delete(beanType, id);
}
/**
* Delete several beans given their type and id values.
*/
public static void delete(Class<?> beanType, Collection<?> ids) {
serverMgr.getPrimaryServer().delete(beanType, ids);
public static void deleteAll(Class<?> beanType, Collection<?> ids) {
serverMgr.getDefaultServer().deleteAll(beanType, ids);
}
/**
* Delete all the beans from an Iterator.
* Delete all the beans in the Collection.
*/
public static int delete(Iterator<?> it) throws OptimisticLockException {
return serverMgr.getPrimaryServer().delete(it);
public static int deleteAll(Collection<?> beans) throws OptimisticLockException {
return serverMgr.getDefaultServer().deleteAll(beans);
}
/**
* Delete all the beans from a Collection.
* Delete permanent all the beans in the Collection (will not use soft delete).
*/
public static int delete(Collection<?> c) throws OptimisticLockException {
return delete(c.iterator());
public static int deleteAllPermanent(Collection<?> beans) throws OptimisticLockException {
return serverMgr.getDefaultServer().deleteAllPermanent(beans);
}
/**
@@ -739,7 +760,7 @@ public final class Ebean {
* </p>
*/
public static void refresh(Object bean) {
serverMgr.getPrimaryServer().refresh(bean);
serverMgr.getDefaultServer().refresh(bean);
}
/**
@@ -760,7 +781,7 @@ public final class Ebean {
* the property name of the List Set or Map to refresh.
*/
public static void refreshMany(Object bean, String manyPropertyName) {
serverMgr.getPrimaryServer().refreshMany(bean, manyPropertyName);
serverMgr.getDefaultServer().refreshMany(bean, manyPropertyName);
}
/**
@@ -788,7 +809,7 @@ public final class Ebean {
* the id value
*/
public static <T> T getReference(Class<T> beanType, Object id) {
return serverMgr.getPrimaryServer().getReference(beanType, id);
return serverMgr.getDefaultServer().getReference(beanType, id);
}
/**
@@ -834,7 +855,7 @@ public final class Ebean {
* the properties to sort the list by
*/
public static <T> void sort(List<T> list, String sortByClause) {
serverMgr.getPrimaryServer().sort(list, sortByClause);
serverMgr.getDefaultServer().sort(list, sortByClause);
}
/**
@@ -883,8 +904,9 @@ public final class Ebean {
* @param id
* the id value
*/
@Nullable
public static <T> T find(Class<T> beanType, Object id) {
return serverMgr.getPrimaryServer().find(beanType, id);
return serverMgr.getDefaultServer().find(beanType, id);
}
/**
@@ -896,7 +918,7 @@ public final class Ebean {
* </p>
*/
public static SqlQuery createSqlQuery(String sql) {
return serverMgr.getPrimaryServer().createSqlQuery(sql);
return serverMgr.getDefaultServer().createSqlQuery(sql);
}
/**
@@ -909,7 +931,7 @@ public final class Ebean {
* the name of the query
*/
public static SqlQuery createNamedSqlQuery(String namedQuery) {
return serverMgr.getPrimaryServer().createNamedSqlQuery(namedQuery);
return serverMgr.getDefaultServer().createNamedSqlQuery(namedQuery);
}
/**
@@ -927,7 +949,7 @@ public final class Ebean {
* </p>
*/
public static SqlUpdate createSqlUpdate(String sql) {
return serverMgr.getPrimaryServer().createSqlUpdate(sql);
return serverMgr.getDefaultServer().createSqlUpdate(sql);
}
/**
@@ -936,7 +958,7 @@ public final class Ebean {
* @see CallableSql
*/
public static CallableSql createCallableSql(String sql) {
return serverMgr.getPrimaryServer().createCallableSql(sql);
return serverMgr.getDefaultServer().createCallableSql(sql);
}
/**
@@ -959,7 +981,7 @@ public final class Ebean {
* }</pre>
*/
public static SqlUpdate createNamedSqlUpdate(String namedQuery) {
return serverMgr.getPrimaryServer().createNamedSqlUpdate(namedQuery);
return serverMgr.getDefaultServer().createNamedSqlUpdate(namedQuery);
}
/**
@@ -987,7 +1009,7 @@ public final class Ebean {
*/
public static <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
return serverMgr.getPrimaryServer().createNamedQuery(beanType, namedQuery);
return serverMgr.getDefaultServer().createNamedQuery(beanType, namedQuery);
}
/**
@@ -1015,7 +1037,7 @@ public final class Ebean {
* the object query
*/
public static <T> Query<T> createQuery(Class<T> beanType, String query) {
return serverMgr.getPrimaryServer().createQuery(beanType, query);
return serverMgr.getDefaultServer().createQuery(beanType, query);
}
/**
@@ -1074,7 +1096,7 @@ public final class Ebean {
*/
public static <T> Update<T> createNamedUpdate(Class<T> beanType, String namedUpdate) {
return serverMgr.getPrimaryServer().createNamedUpdate(beanType, namedUpdate);
return serverMgr.getDefaultServer().createNamedUpdate(beanType, namedUpdate);
}
/**
@@ -1108,7 +1130,7 @@ public final class Ebean {
*/
public static <T> Update<T> createUpdate(Class<T> beanType, String ormUpdate) {
return serverMgr.getPrimaryServer().createUpdate(beanType, ormUpdate);
return serverMgr.getDefaultServer().createUpdate(beanType, ormUpdate);
}
/**
@@ -1116,7 +1138,7 @@ public final class Ebean {
*/
public static <T> CsvReader<T> createCsvReader(Class<T> beanType) {
return serverMgr.getPrimaryServer().createCsvReader(beanType);
return serverMgr.getDefaultServer().createCsvReader(beanType);
}
/**
@@ -1173,7 +1195,7 @@ public final class Ebean {
*/
public static <T> Query<T> createQuery(Class<T> beanType) {
return serverMgr.getPrimaryServer().createQuery(beanType);
return serverMgr.getDefaultServer().createQuery(beanType);
}
/**
@@ -1190,7 +1212,7 @@ public final class Ebean {
*/
public static <T> Query<T> find(Class<T> beanType) {
return serverMgr.getPrimaryServer().find(beanType);
return serverMgr.getDefaultServer().find(beanType);
}
/**
@@ -1204,7 +1226,7 @@ public final class Ebean {
* </p>
*/
public static <T> Filter<T> filter(Class<T> beanType) {
return serverMgr.getPrimaryServer().filter(beanType);
return serverMgr.getDefaultServer().filter(beanType);
}
/**
@@ -1251,7 +1273,7 @@ public final class Ebean {
* @see Ebean#execute(CallableSql)
*/
public static int execute(SqlUpdate sqlUpdate) {
return serverMgr.getPrimaryServer().execute(sqlUpdate);
return serverMgr.getDefaultServer().execute(sqlUpdate);
}
/**
@@ -1280,7 +1302,7 @@ public final class Ebean {
* @see Ebean#execute(SqlUpdate)
*/
public static int execute(CallableSql callableSql) {
return serverMgr.getPrimaryServer().execute(callableSql);
return serverMgr.getDefaultServer().execute(callableSql);
}
/**
@@ -1305,7 +1327,7 @@ public final class Ebean {
* }</pre>
*/
public static void execute(TxScope scope, TxRunnable r) {
serverMgr.getPrimaryServer().execute(scope, r);
serverMgr.getDefaultServer().execute(scope, r);
}
/**
@@ -1333,7 +1355,7 @@ public final class Ebean {
* }</pre>
*/
public static void execute(TxRunnable r) {
serverMgr.getPrimaryServer().execute(r);
serverMgr.getDefaultServer().execute(r);
}
/**
@@ -1360,7 +1382,7 @@ public final class Ebean {
*
*/
public static <T> T execute(TxScope scope, TxCallable<T> c) {
return serverMgr.getPrimaryServer().execute(scope, c);
return serverMgr.getDefaultServer().execute(scope, c);
}
/**
@@ -1394,7 +1416,7 @@ public final class Ebean {
* }</pre>
*/
public static <T> T execute(TxCallable<T> c) {
return serverMgr.getPrimaryServer().execute(c);
return serverMgr.getDefaultServer().execute(c);
}
/**
@@ -1431,10 +1453,9 @@ public final class Ebean {
* @param deletes
* true if rows on the table where deleted
*/
public static void externalModification(String tableName, boolean inserts, boolean updates,
boolean deletes) {
public static void externalModification(String tableName, boolean inserts, boolean updates, boolean deletes) {
serverMgr.getPrimaryServer().externalModification(tableName, inserts, updates, deletes);
serverMgr.getDefaultServer().externalModification(tableName, inserts, updates, deletes);
}
/**
@@ -1444,7 +1465,7 @@ public final class Ebean {
* </p>
*/
public static BeanState getBeanState(Object bean) {
return serverMgr.getPrimaryServer().getBeanState(bean);
return serverMgr.getDefaultServer().getBeanState(bean);
}
/**
@@ -1452,7 +1473,7 @@ public final class Ebean {
*
*/
public static ServerCacheManager getServerCacheManager() {
return serverMgr.getPrimaryServer().getServerCacheManager();
return serverMgr.getDefaultServer().getServerCacheManager();
}
/**
@@ -1460,7 +1481,7 @@ public final class Ebean {
* queries.
*/
public static BackgroundExecutor getBackgroundExecutor() {
return serverMgr.getPrimaryServer().getBackgroundExecutor();
return serverMgr.getDefaultServer().getBackgroundExecutor();
}
/**
@@ -1471,7 +1492,7 @@ public final class Ebean {
* </p>
*/
public static void runCacheWarming() {
serverMgr.getPrimaryServer().runCacheWarming();
serverMgr.getDefaultServer().runCacheWarming();
}
/**
@@ -1483,22 +1504,14 @@ public final class Ebean {
*/
public static void runCacheWarming(Class<?> beanType) {
serverMgr.getPrimaryServer().runCacheWarming(beanType);
serverMgr.getDefaultServer().runCacheWarming(beanType);
}
/**
* Return the JsonContext for reading/writing JSON.
*/
public static JsonContext json() {
return serverMgr.getPrimaryServer().json();
}
/**
* Return the JsonContext for reading/writing JSON.
* @deprecated Please use #json instead.
*/
public static JsonContext createJsonContext() {
return json();
return serverMgr.getDefaultServer().json();
}
}
+268 -85
View File
@@ -1,20 +1,21 @@
package com.avaje.ebean;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import com.avaje.ebean.annotation.CacheStrategy;
import com.avaje.ebean.cache.ServerCacheManager;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.meta.MetaInfoManager;
import com.avaje.ebean.plugin.SpiServer;
import com.avaje.ebean.text.csv.CsvReader;
import com.avaje.ebean.text.json.JsonContext;
import org.jetbrains.annotations.Nullable;
import javax.persistence.NonUniqueResultException;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Provides the API for fetching and saving beans to a particular DataSource.
@@ -106,10 +107,9 @@ public interface EbeanServer {
void shutdown(boolean shutdownDataSource, boolean deregisterDriver);
/**
* Return the AdminAutofetch which is used to control and configure the
* Autofetch service at runtime.
* Return AutoTune which is used to control the AutoTune service at runtime.
*/
AdminAutofetch getAdminAutofetch();
AutoTune getAutoTune();
/**
* Return the name. This is used with {@link Ebean#getServer(String)} to get a
@@ -128,6 +128,11 @@ public interface EbeanServer {
*/
MetaInfoManager getMetaInfoManager();
/**
* Return the extended API intended for use by plugins.
*/
SpiServer getPluginApi();
/**
* Return the BeanState for a given entity bean.
* <p>
@@ -148,7 +153,7 @@ public interface EbeanServer {
* difference comparison.
* </p>
*/
Map<String, ValuePair> diff(Object a, Object b);
Map<String, ValuePair> diff(Object newBean, Object oldBean);
/**
* Create a new instance of T that is an EntityBean.
@@ -905,17 +910,13 @@ public interface EbeanServer {
<T> void findEachWhile(Query<T> query, QueryEachWhileConsumer<T> consumer, Transaction transaction);
/**
* Deprecated in favor of #findEachWhile which is functionally exactly the same
* but has a much better name.
* Return versions of a @History entity bean.
* <p>
* Execute the query visiting the results. This is similar to findIterate in
* that not all the result beans need to be held in memory at the same time
* and as such is go for processing large queries.
* Generally this query is expected to be a find by id or unique predicates query.
* It will execute the query against the history returning the versions of the bean.
* </p>
*
* @deprecated
*/
<T> void findVisit(Query<T> query, QueryResultVisitor<T> visitor, Transaction transaction);
<T> List<Version<T>> findVersions(Query<T> query, Transaction transaction);
/**
* Execute a query returning a list of beans.
@@ -1019,7 +1020,7 @@ public interface EbeanServer {
SqlFutureList findFutureList(SqlQuery query, Transaction transaction);
/**
* Return a PagedList for this query.
* Return a PagedList for this query using pageIndex and pageSize.
* <p>
* The benefit of using this over just using the normal {@link Query#setFirstRow(int)} and
* {@link Query#setMaxRows(int)} is that it additionally wraps an optional call to
@@ -1041,6 +1042,38 @@ public interface EbeanServer {
*/
<T> PagedList<T> findPagedList(Query<T> query, Transaction transaction, int pageIndex, int pageSize);
/**
* Return a PagedList for this query using firstRow and maxRows.
* <p>
* The benefit of using this over findList() is that it provides functionality to get the
* total row count etc.
* </p>
* <p>
* If maxRows is not set on the query prior to calling findPagedList() then a
* PersistenceException is thrown.
* </p>
*
* <pre>{@code
*
* PagedList<Order> pagedList = Ebean.find(Order.class)
* .setFirstRow(50)
* .setMaxRows(20)
* .findPagedList();
*
* // fetch the total row count in the background
* pagedList.loadRowCount();
*
* List<Order> orders = pagedList.getList();
* int totalRowCount = pagedList.getTotalRowCount();
*
* }</pre>
*
* @return The PagedList
*
* @see Query#findPagedList()
*/
<T> PagedList<T> findPagedList(Query<T> query, Transaction transaction);
/**
* Execute the query returning a set of entity beans.
* <p>
@@ -1091,14 +1124,17 @@ public interface EbeanServer {
<T> Map<?, T> findMap(Query<T> query, Transaction transaction);
/**
* Execute the query returning at most one entity bean. This will throw a
* PersistenceException if the query finds more than one result.
* Execute the query returning at most one entity bean or null (if no matching
* bean is found).
* <p>
* This will throw a NonUniqueResultException if the query finds more than one result.
* </p>
* <p>
* Generally you are able to use {@link Query#findUnique()} rather than
* explicitly calling this method. You could use this method if you wish to
* explicitly control the transaction used for the query.
* </p>
*
*
* @param <T>
* the type of entity bean to fetch.
* @param query
@@ -1106,11 +1142,28 @@ public interface EbeanServer {
* @param transaction
* the transaction to use (can be null).
* @return the list of fetched beans.
* @throws NonUniqueResultException if more than one result was found
*
* @see Query#findUnique()
*/
@Nullable
<T> T findUnique(Query<T> query, Transaction transaction);
/**
* Execute as a delete query deleting the 'root level' beans that match the predicates
* in the query.
* <p>
* Note that if the query includes joins then the generated delete statement may not be
* optimal depending on the database platform.
* </p>
*
* @param query the query used for the delete
* @param transaction the transaction to use (can be null)
* @param <T> the type of entity bean to fetch.
* @return the number of beans/rows that were deleted
*/
<T> int delete(Query<T> query, Transaction transaction);
/**
* Execute the sql query returning a list of MapBean.
* <p>
@@ -1185,6 +1238,7 @@ public interface EbeanServer {
*
* @see SqlQuery#findUnique()
*/
@Nullable
SqlRow findUnique(SqlQuery query, Transaction transaction);
/**
@@ -1207,7 +1261,6 @@ public interface EbeanServer {
* public class Order { ...
*
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
* @JoinColumn(name="order_id")
* List<OrderDetail> details;
* ...
* }
@@ -1222,34 +1275,60 @@ public interface EbeanServer {
*/
void save(Object bean) throws OptimisticLockException;
/**
* Save all the beans in the iterator.
*/
int save(Iterator<?> it) throws OptimisticLockException;
/**
* Save all the beans in the collection.
*/
int save(Collection<?> beans) throws OptimisticLockException;
int saveAll(Collection<?> beans) throws OptimisticLockException;
/**
* Delete the bean.
* <p>
* This will return true if the bean was deleted successfully or JDBC batch is being used.
* </p>
* <p>
* If there is no current transaction one will be created and committed for
* you automatically.
* </p>
* <p>
* If the Bean does not have a version property (or loaded version property) and
* the bean does not exist then this returns false indicating that nothing was
* deleted. Note that, if JDBC batch mode is used then this always returns true.
* </p>
*/
void delete(Object bean) throws OptimisticLockException;
boolean delete(Object bean) throws OptimisticLockException;
/**
* Delete all the beans from an Iterator.
* Delete the bean with an explicit transaction.
* <p>
* This will return true if the bean was deleted successfully or JDBC batch is being used.
* </p>
* <p>
* If the Bean does not have a version property (or loaded version property) and
* the bean does not exist then this returns false indicating that nothing was
* deleted. However, if JDBC batch mode is used then this always returns true.
* </p>
*/
int delete(Iterator<?> it) throws OptimisticLockException;
boolean delete(Object bean, Transaction transaction) throws OptimisticLockException;
/**
* Delete all the beans in the collection.
* Delete a bean permanently without soft delete.
*/
int delete(Collection<?> c) throws OptimisticLockException;
boolean deletePermanent(Object bean) throws OptimisticLockException;
/**
* Delete a bean permanently without soft delete using an explicit transaction.
*/
boolean deletePermanent(Object bean, Transaction transaction) throws OptimisticLockException;
/**
* Delete all the beans in the collection permanently without soft delete.
*/
int deleteAllPermanent(Collection<?> beans) throws OptimisticLockException;
/**
* Delete all the beans in the collection permanently without soft delete using an explicit transaction.
*/
int deleteAllPermanent(Collection<?> beans, Transaction transaction) throws OptimisticLockException;
/**
* Delete the bean given its type and id.
@@ -1261,16 +1340,26 @@ public interface EbeanServer {
*/
int delete(Class<?> beanType, Object id, Transaction transaction);
/**
* Delete all the beans in the collection.
*/
int deleteAll(Collection<?> beans) throws OptimisticLockException;
/**
* Delete all the beans in the collection using an explicit transaction.
*/
int deleteAll(Collection<?> beans, Transaction transaction) throws OptimisticLockException;
/**
* Delete several beans given their type and id values.
*/
void delete(Class<?> beanType, Collection<?> ids);
void deleteAll(Class<?> beanType, Collection<?> ids);
/**
* Delete several beans given their type and id values with an explicit
* transaction.
*/
void delete(Class<?> beanType, Collection<?> ids, Transaction transaction);
void deleteAll(Class<?> beanType, Collection<?> ids, Transaction transaction);
/**
* Execute a Sql Update Delete or Insert statement. This returns the number of
@@ -1328,7 +1417,7 @@ public interface EbeanServer {
* Execute a ORM insert update or delete statement with an explicit
* transaction.
*/
int execute(Update<?> update, Transaction t);
int execute(Update<?> update, Transaction transaction);
/**
* For making calls to stored procedures.
@@ -1400,27 +1489,22 @@ public interface EbeanServer {
* the type of entity bean to find
* @param beanType
* the type of entity bean to find
* @param uid
* @param id
* the bean id value
* @param transaction
* the transaction to use (can be null)
*/
<T> T find(Class<T> beanType, Object uid, Transaction transaction);
<T> T find(Class<T> beanType, Object id, Transaction transaction);
/**
* Insert or update a bean with an explicit transaction.
*/
void save(Object bean, Transaction transaction) throws OptimisticLockException;
/**
* Save all the beans in the iterator with an explicit transaction.
*/
int save(Iterator<?> it, Transaction transaction) throws OptimisticLockException;
/**
* Save all the beans in the collection with an explicit transaction.
*/
int save(Collection<?> beans, Transaction transaction) throws OptimisticLockException;
int saveAll(Collection<?> beans, Transaction transaction) throws OptimisticLockException;
/**
* Marks the entity bean as dirty.
@@ -1445,7 +1529,7 @@ public interface EbeanServer {
void markAsDirty(Object bean);
/**
* Saves the bean using an update. If you know you are updating a bean then it is preferrable to
* Saves the bean using an update. If you know you are updating a bean then it is preferable to
* use this update() method rather than save().
* <p>
* <b>Stateless updates:</b> Note that the bean does not have to be previously fetched to call
@@ -1485,7 +1569,7 @@ public interface EbeanServer {
/**
* Update a bean additionally specifying a transaction.
*/
void update(Object bean, Transaction t) throws OptimisticLockException;
void update(Object bean, Transaction transaction) throws OptimisticLockException;
/**
* Update a bean additionally specifying a transaction and the deleteMissingChildren setting.
@@ -1497,7 +1581,6 @@ public interface EbeanServer {
* @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;
@@ -1505,13 +1588,13 @@ public interface EbeanServer {
* Update a collection of beans. If there is no current transaction one is created and used to
* update all the beans in the collection.
*/
void update(Collection<?> beans) throws OptimisticLockException;
void updateAll(Collection<?> beans) throws OptimisticLockException;
/**
* Update a collection of beans with an explicit transaction.
*/
void update(Collection<?> beans, Transaction transaction) throws OptimisticLockException;
void updateAll(Collection<?> beans, Transaction transaction) throws OptimisticLockException;
/**
* Insert the bean.
* <p>
@@ -1525,18 +1608,18 @@ public interface EbeanServer {
/**
* Insert the bean with a transaction.
*/
void insert(Object bean, Transaction t);
void insert(Object bean, Transaction transaction);
/**
* Insert a collection of beans. If there is no current transaction one is created and used to
* insert all the beans in the collection.
*/
void insert(Collection<?> beans);
void insertAll(Collection<?> beans);
/**
* Insert a collection of beans with an explicit transaction.
*/
void insert(Collection<?> beans, Transaction t);
void insertAll(Collection<?> beans, Transaction transaction);
/**
* Delete the associations (from the intersection table) of a ManyToMany given
@@ -1545,7 +1628,7 @@ public interface EbeanServer {
* Typically these deletions occur automatically when persisting a ManyToMany
* collection and this provides a way to invoke those deletions directly.
* </p>
*
*
* @return the number of associations deleted (from the intersection table).
*/
int deleteManyToManyAssociations(Object ownerBean, String propertyName);
@@ -1560,10 +1643,10 @@ public interface EbeanServer {
* Typically these deletions occur automatically when persisting a ManyToMany
* collection and this provides a way to invoke those deletions directly.
* </p>
*
*
* @return the number of associations deleted (from the intersection table).
*/
int deleteManyToManyAssociations(Object ownerBean, String propertyName, Transaction t);
int deleteManyToManyAssociations(Object ownerBean, String propertyName, Transaction transaction);
/**
* Save the associations of a ManyToMany given the owner bean and the
@@ -1585,7 +1668,7 @@ public interface EbeanServer {
* way to invoke those insertions directly.
* </p>
*/
void saveManyToManyAssociations(Object ownerBean, String propertyName, Transaction t);
void saveManyToManyAssociations(Object ownerBean, String propertyName, Transaction transaction);
/**
* Save the associated collection or bean given the property name.
@@ -1622,27 +1705,18 @@ public interface EbeanServer {
* @param propertyName
* the property we want to save
*/
void saveAssociation(Object ownerBean, String propertyName, Transaction t);
void saveAssociation(Object ownerBean, String propertyName, Transaction transaction);
/**
* Delete the bean with an explicit transaction.
*/
void delete(Object bean, Transaction t) throws OptimisticLockException;
/**
* Delete all the beans from an iterator.
*/
int delete(Iterator<?> it, Transaction t) throws OptimisticLockException;
/**
* Execute explicitly passing a transaction.
*/
int execute(SqlUpdate updSql, Transaction t);
int execute(SqlUpdate updSql, Transaction transaction);
/**
* Execute explicitly passing a transaction.
*/
int execute(CallableSql callableSql, Transaction t);
int execute(CallableSql callableSql, Transaction transaction);
/**
* Execute a TxRunnable in a Transaction with an explicit scope.
@@ -1665,7 +1739,7 @@ public interface EbeanServer {
*
* }</pre>
*/
void execute(TxScope scope, TxRunnable r);
void execute(TxScope scope, TxRunnable runnable);
/**
* Execute a TxRunnable in a Transaction with the default scope.
@@ -1691,7 +1765,7 @@ public interface EbeanServer {
*
* }</pre>
*/
void execute(TxRunnable r);
void execute(TxRunnable runnable);
/**
* Execute a TxCallable in a Transaction with an explicit scope.
@@ -1715,7 +1789,7 @@ public interface EbeanServer {
*
* }</pre>
*/
<T> T execute(TxScope scope, TxCallable<T> c);
<T> T execute(TxScope scope, TxCallable<T> callable);
/**
* Execute a TxCallable in a Transaction with the default scope.
@@ -1747,7 +1821,7 @@ public interface EbeanServer {
*
* }</pre>
*/
<T> T execute(TxCallable<T> c);
<T> T execute(TxCallable<T> callable);
/**
* Return the manager of the server cache ("L2" cache).
@@ -1777,12 +1851,6 @@ public interface EbeanServer {
*/
void runCacheWarming(Class<?> beanType);
/**
* Return the JsonContext for reading/writing JSON.
* @deprecated Please use #json instead.
*/
JsonContext createJsonContext();
/**
* Return the JsonContext for reading/writing JSON.
* <p>
@@ -1818,9 +1886,124 @@ public interface EbeanServer {
*
* }</pre>
*
* @see com.avaje.ebean.text.PathProperties
* @see Query#apply(com.avaje.ebean.text.PathProperties)
* @see FetchPath
* @see Query#apply(FetchPath)
*/
JsonContext json();
/**
* Return the Document store.
*/
DocumentStore docStore();
/**
* Publish a single bean given its type and id returning the resulting live bean.
* <p>
* The values are published from the draft to the live bean.
* </p>
*
* @param <T> the type of the entity bean
* @param beanType the type of the entity bean
* @param id the id of the entity bean
* @param transaction the transaction the publish process should use (can be null)
*/
<T> T publish(Class<T> beanType, Object id, Transaction transaction);
/**
* Publish a single bean given its type and id returning the resulting live bean.
* This will use the current transaction or create one if required.
* <p>
* The values are published from the draft to the live bean.
* </p>
*
* @param <T> the type of the entity bean
* @param beanType the type of the entity bean
* @param id the id of the entity bean
*/
<T> T publish(Class<T> beanType, Object id);
/**
* Publish the beans that match the query returning the resulting published beans.
* <p>
* The values are published from the draft beans to the live beans.
* </p>
*
* @param <T> the type of the entity bean
* @param query the query used to select the draft beans to publish
* @param transaction the transaction the publish process should use (can be null)
*/
<T> List<T> publish(Query<T> query, Transaction transaction);
/**
* Publish the beans that match the query returning the resulting published beans.
* This will use the current transaction or create one if required.
* <p>
* The values are published from the draft beans to the live beans.
* </p>
*
* @param <T> the type of the entity bean
* @param query the query used to select the draft beans to publish
*/
<T> List<T> publish(Query<T> query);
/**
* Restore the draft bean back to the live state.
* <p>
* The values from the live beans are set back to the draft bean and the
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
* </p>
*
* @param <T> the type of the entity bean
* @param beanType the type of the entity bean
* @param id the id of the entity bean to restore
* @param transaction the transaction the restore process should use (can be null)
*/
<T> T draftRestore(Class<T> beanType, Object id, Transaction transaction);
/**
* Restore the draft bean back to the live state.
* <p>
* The values from the live beans are set back to the draft bean and the
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
* </p>
*
* @param <T> the type of the entity bean
* @param beanType the type of the entity bean
* @param id the id of the entity bean to restore
*/
<T> T draftRestore(Class<T> beanType, Object id);
/**
* Restore the draft beans matching the query back to the live state.
* <p>
* The values from the live beans are set back to the draft bean and the
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
* </p>
*
* @param <T> the type of the entity bean
* @param query the query used to select the draft beans to restore
* @param transaction the transaction the restore process should use (can be null)
*/
<T> List<T> draftRestore(Query<T> query, Transaction transaction);
/**
* Restore the draft beans matching the query back to the live state.
* <p>
* The values from the live beans are set back to the draft bean and the
* <code>@DraftDirty</code> and <code>@DraftReset</code> properties are reset.
* </p>
*
* @param <T> the type of the entity bean
* @param query the query used to select the draft beans to restore
*/
<T> List<T> draftRestore(Query<T> query);
/**
* Returns the set of properties/paths that are unknown (do not map to known properties or paths).
* <p>
* Validate the query checking the where and orderBy expression paths to confirm if
* they represent valid properties/path for the given bean type.
* </p>
*/
<T> Set<String> validateQuery(Query<T> query);
}
@@ -1,10 +1,8 @@
package com.avaje.ebean;
import java.io.Serializable;
/**
* An expression that is part of a WHERE or HAVING clause.
*/
public interface Expression extends Serializable {
public interface Expression {
}
@@ -1,5 +1,11 @@
package com.avaje.ebean;
import com.avaje.ebean.search.Match;
import com.avaje.ebean.search.MultiMatch;
import com.avaje.ebean.search.TextCommonTerms;
import com.avaje.ebean.search.TextQueryString;
import com.avaje.ebean.search.TextSimple;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -36,6 +42,51 @@ import java.util.Map;
*/
public interface ExpressionFactory {
/**
* Path exists - for the given path in a JSON document.
*/
Expression jsonExists(String propertyName, String path);
/**
* Path does not exist - for the given path in a JSON document.
*/
Expression jsonNotExists(String propertyName, String path);
/**
* Equal to - for the given path in a JSON document.
*/
Expression jsonEqualTo(String propertyName, String path, Object val);
/**
* Not Equal to - for the given path in a JSON document.
*/
Expression jsonNotEqualTo(String propertyName, String path, Object val);
/**
* Greater than - for the given path in a JSON document.
*/
Expression jsonGreaterThan(String propertyName, String path, Object val);
/**
* Greater than or equal to - for the given path in a JSON document.
*/
Expression jsonGreaterOrEqual(String propertyName, String path, Object val);
/**
* Less than - for the given path in a JSON document.
*/
Expression jsonLessThan(String propertyName, String path, Object val);
/**
* Less than or equal to - for the given path in a JSON document.
*/
Expression jsonLessOrEqualTo(String propertyName, String path, Object val);
/**
* Between - for the given path in a JSON document.
*/
Expression jsonBetween(String propertyName, String path, Object lowerValue, Object upperValue);
/**
* Equal To - property equal to the given value.
*/
@@ -169,7 +220,22 @@ public interface ExpressionFactory {
* In - property has a value in the collection of values.
*/
Expression in(String propertyName, Collection<?> values);
/**
* Not In - property has a value in the array of values.
*/
Expression notIn(String propertyName, Object[] values);
/**
* Not In - property has a value in the collection of values.
*/
Expression notIn(String propertyName, Collection<?> values);
/**
* Not In - using a subQuery.
*/
Expression notIn(String propertyName, Query<?> subQuery);
/**
* Exists expression
*/
@@ -225,6 +291,31 @@ public interface ExpressionFactory {
*/
Expression raw(String raw);
/**
* Create a Text Match expression (currently doc store/Elastic only).
*/
Expression textMatch(String propertyName, String search, Match options);
/**
* Create a Text Multi match expression (currently doc store/Elastic only).
*/
Expression textMultiMatch(String query, MultiMatch options);
/**
* Create a text simple query expression (currently doc store/Elastic only).
*/
Expression textSimple(String search, TextSimple options);
/**
* Create a text query string expression (currently doc store/Elastic only).
*/
Expression textQueryString(String search, TextQueryString options);
/**
* Create a text common terms expression (currently doc store/Elastic only).
*/
Expression textCommonTerms(String search, TextCommonTerms options);
/**
* And - join two expressions with a logical and.
*/
@@ -259,4 +350,13 @@ public interface ExpressionFactory {
* Return a list of expressions that will be joined by OR's.
*/
<T> Junction<T> disjunction(Query<T> query, ExpressionList<T> parent);
/**
* Return a Text query junction for MUST, SHOULD or MUST NOT.
* <p>
* This is doc store Elastic only.
* </p>
*/
<T> Junction<T> junction(Junction.Type type, Query<T> query, ExpressionList<T> parent);
}
+516 -39
View File
@@ -1,8 +1,14 @@
package com.avaje.ebean;
import com.avaje.ebean.text.PathProperties;
import com.avaje.ebean.search.Match;
import com.avaje.ebean.search.MultiMatch;
import com.avaje.ebean.search.TextCommonTerms;
import com.avaje.ebean.search.TextQueryString;
import com.avaje.ebean.search.TextSimple;
import org.jetbrains.annotations.Nullable;
import java.io.Serializable;
import javax.persistence.NonUniqueResultException;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -28,7 +34,7 @@ import java.util.Set;
*
* @see Query#where()
*/
public interface ExpressionList<T> extends Serializable {
public interface ExpressionList<T> {
/**
* Return the query that owns this expression list.
@@ -92,7 +98,40 @@ public interface ExpressionList<T> extends Serializable {
/**
* Apply the path properties to the query replacing the select and fetch clauses.
*/
Query<T> apply(PathProperties pathProperties);
Query<T> apply(FetchPath fetchPath);
/**
* Perform an 'As of' query using history tables to return the object graph
* as of a time in the past.
* <p>
* To perform this query the DB must have underlying history tables.
* </p>
*
* @param asOf the date time in the past at which you want to view the data
*/
Query<T> asOf(Timestamp asOf);
/**
* Execute the query against the draft set of tables.
*/
Query<T> asDraft();
/**
* Execute the query including soft deleted rows.
*/
Query<T> includeSoftDeletes();
/**
* Execute as a delete query deleting the 'root level' beans that match the predicates
* in the query.
* <p>
* Note that if the query includes joins then the generated delete statement may not be
* optimal depending on the database platform.
* </p>
*
* @return the number of beans/rows that were deleted.
*/
int delete();
/**
* Execute the query iterating over the results.
@@ -116,14 +155,6 @@ public interface ExpressionList<T> extends Serializable {
*/
void findEachWhile(QueryEachWhileConsumer<T> consumer);
/**
* Deprecated in favor of #findEachWhile which is functionally exactly the same
* but has a much better name.
*
* @deprecated
*/
void findVisit(QueryResultVisitor<T> visitor);
/**
* Execute the query returning a list.
*
@@ -166,10 +197,18 @@ public interface ExpressionList<T> extends Serializable {
<K> Map<K, T> findMap(String keyProperty, Class<K> keyType);
/**
* Execute the query returning a single bean.
*
* Execute the query returning a single bean or null (if no matching
* bean is found).
* <p>
* If more than 1 row is found for this query then a NonUniqueResultException is
* thrown.
* </p>
*
* @throws NonUniqueResultException if more than one result was found
*
* @see Query#findUnique()
*/
@Nullable
T findUnique();
/**
@@ -209,7 +248,7 @@ public interface ExpressionList<T> extends Serializable {
FutureList<T> findFutureList();
/**
* Return a PagedList for this query.
* Return a PagedList for this query using pageIndex and pageSize.
* <p>
* The benefit of using this over just using the normal {@link Query#setFirstRow(int)} and
* {@link Query#setMaxRows(int)} is that it additionally wraps an optional call to
@@ -229,6 +268,56 @@ public interface ExpressionList<T> extends Serializable {
*/
PagedList<T> findPagedList(int pageIndex, int pageSize);
/**
* Return a PagedList for this query using firstRow and maxRows.
* <p>
* The benefit of using this over findList() is that it provides functionality to get the
* total row count etc.
* </p>
* <p>
* If maxRows is not set on the query prior to calling findPagedList() then a
* PersistenceException is thrown.
* </p>
*
* <pre>{@code
*
* PagedList<Order> pagedList = Ebean.find(Order.class)
* .setFirstRow(50)
* .setMaxRows(20)
* .findPagedList();
*
* // fetch the total row count in the background
* pagedList.loadRowCount();
*
* List<Order> orders = pagedList.getList();
* int totalRowCount = pagedList.getTotalRowCount();
*
* }</pre>
*
* @return The PagedList
*
* @see Query#findPagedList()
*/
PagedList<T> findPagedList();
/**
* Return versions of a @History entity bean.
* <p>
* Generally this query is expected to be a find by id or unique predicates query.
* It will execute the query against the history returning the versions of the bean.
* </p>
*/
List<Version<T>> findVersions();
/**
* Return versions of a @History entity bean between the 2 timestamps.
* <p>
* Generally this query is expected to be a find by id or unique predicates query.
* It will execute the query against the history returning the versions of the bean.
* </p>
*/
List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end);
/**
* Add some filter predicate expressions to the many property.
*/
@@ -242,6 +331,24 @@ public interface ExpressionList<T> extends Serializable {
*/
Query<T> select(String properties);
/**
* Set whether this query uses DISTINCT.
* <p>
* The select() clause MUST be specified when setDistinct(true) is set. The reason for this is that
* generally ORM queries include the "id" property and this doesn't make sense for distinct queries.
* </p>
* <pre>{@code
*
* List<Customer> customers =
* Ebean.find(Customer.class)
* .setDistinct(true)
* .select("name") // only select the customer name
* .findList();
*
* }</pre>
*/
Query<T> setDistinct(boolean distinct);
/**
* Set the first row to fetch.
*
@@ -270,6 +377,39 @@ public interface ExpressionList<T> extends Serializable {
*/
Query<T> setUseCache(boolean useCache);
/**
* Set to true to use the query for executing this query.
*
* @see Query#setUseQueryCache(boolean)
*/
Query<T> setUseQueryCache(boolean useCache);
/**
* Set to true if this query should execute against the doc store.
* <p>
* When setting this you may also consider disabling lazy loading.
* </p>
*/
Query<T> setUseDocStore(boolean useDocsStore);
/**
* Set true if you want to disable lazy loading.
* <p>
* That is, once the object graph is returned further lazy loading is disabled.
* </p>
*/
Query<T> setDisableLazyLoading(boolean disableLazyLoading);
/**
* Disable read auditing for this query.
* <p>
* This is intended to be used when the query is not a user initiated query and instead
* part of the internal processing in an application to load a cache or document store etc.
* In these cases we don't want the query to be part of read auditing.
* </p>
*/
Query<T> setDisableReadAuditing();
/**
* Add expressions to the having clause.
* <p>
@@ -284,20 +424,136 @@ public interface ExpressionList<T> extends Serializable {
*/
ExpressionList<T> where();
/**
* Path exists - for the given path in a JSON document.
*
* <pre>{@code
*
* where().jsonExists("content", "path.other")
*
* }</pre>
*
* @param propertyName the property that holds a JSON document
* @param path the nested path in the JSON document in dot notation
*/
ExpressionList<T> jsonExists(String propertyName, String path);
/**
* Path does not exist - for the given path in a JSON document.
*
* <pre>{@code
*
* where().jsonNotExists("content", "path.other")
*
* }</pre>
*
* @param propertyName the property that holds a JSON document
* @param path the nested path in the JSON document in dot notation
*/
ExpressionList<T> jsonNotExists(String propertyName, String path);
/**
* Equal to expression for the value at the given path in the JSON document.
*
* <pre>{@code
*
* where().jsonEqualTo("content", "path.other", 34)
*
* }</pre>
*
* @param propertyName the property that holds a JSON document
* @param path the nested path in the JSON document in dot notation
* @param value the value used to test against the document path's value
*/
ExpressionList<T> jsonEqualTo(String propertyName, String path, Object value);
/**
* Not Equal to - for the given path in a JSON document.
*
* <pre>{@code
*
* where().jsonNotEqualTo("content", "path.other", 34)
*
* }</pre>
*
* @param propertyName the property that holds a JSON document
* @param path the nested path in the JSON document in dot notation
* @param value the value used to test against the document path's value
*/
ExpressionList<T> jsonNotEqualTo(String propertyName, String path, Object value);
/**
* Greater than - for the given path in a JSON document.
*
* <pre>{@code
*
* where().jsonGreaterThan("content", "path.other", 34)
*
* }</pre>
*/
ExpressionList<T> jsonGreaterThan(String propertyName, String path, Object value);
/**
* Greater than or equal to - for the given path in a JSON document.
*
* <pre>{@code
*
* where().jsonGreaterOrEqual("content", "path.other", 34)
*
* }</pre>
*/
ExpressionList<T> jsonGreaterOrEqual(String propertyName, String path, Object value);
/**
* Less than - for the given path in a JSON document.
*
* <pre>{@code
*
* where().jsonLessThan("content", "path.other", 34)
*
* }</pre>
*/
ExpressionList<T> jsonLessThan(String propertyName, String path, Object value);
/**
* Less than or equal to - for the given path in a JSON document.
*
* <pre>{@code
*
* where().jsonLessOrEqualTo("content", "path.other", 34)
*
* }</pre>
*/
ExpressionList<T> jsonLessOrEqualTo(String propertyName, String path, Object value);
/**
* Between - for the given path in a JSON document.
*
* <pre>{@code
*
* where().jsonBetween("content", "orderDate", lowerDateTime, upperDateTime)
*
* }</pre>
*/
ExpressionList<T> jsonBetween(String propertyName, String path, Object lowerValue, Object upperValue);
/**
* Add an Expression to the list.
* <p>
* This returns the list so that add() can be chained.
* </p>
*
* <pre class="code">
* Query&lt;Customer&gt; query = Ebean.createQuery(Customer.class);
*
* <pre>{@code
*
* Query<Customer> query = Ebean.find(Customer.class);
* query.where()
* .like(&quot;name&quot;,&quot;Rob%&quot;)
* .eq(&quot;status&quot;, Customer.ACTIVE);
* List&lt;Customer&gt; list = query.findList();
* .like("name","Rob%")
* .eq("status", Customer.ACTIVE);
*
* List<Customer> list = query.findList();
* ...
* </pre>
*
* }</pre>
*/
ExpressionList<T> add(Expression expr);
@@ -378,33 +634,36 @@ public interface ExpressionList<T> extends Serializable {
* those options such as case insensitive etc.
* </p>
*
* <pre class="code">
* <pre>{@code
*
* // create an example bean and set the properties
* // with the query parameters you want
* Customer example = new Customer();
* example.setName(&quot;Rob%&quot;);
* example.setNotes(&quot;%something%&quot;);
* example.setName("Rob%");
* example.setNotes("%something%");
*
* List&lt;Customer&gt; list = Ebean.find(Customer.class).where()
* // pass the bean into the where() clause
* .exampleLike(example)
* // you can add other expressions to the same query
* .gt(&quot;id&quot;, 2).findList();
* .gt("id", 2).findList();
*
* </pre>
* }</pre>
*
* Similarly you can create an ExampleExpression
*
* <pre>
* <pre>{@code
*
* Customer example = new Customer();
* example.setName(&quot;Rob%&quot;);
* example.setNotes(&quot;%something%&quot;);
* example.setName("Rob%");
* example.setNotes("%something%");
*
* // create a ExampleExpression with more control
* ExampleExpression qbe = new ExampleExpression(example, true, LikeType.EQUAL_TO).includeZeros();
*
* List&lt;Customer&gt; list = Ebean.find(Customer.class).where().add(qbe).findList();
* </pre>
* List<Customer> list = Ebean.find(Customer.class).where().add(qbe).findList();
*
* }</pre>
*/
ExpressionList<T> exampleLike(Object example);
@@ -473,7 +732,22 @@ public interface ExpressionList<T> extends Serializable {
* In - property has a value in the collection of values.
*/
ExpressionList<T> in(String propertyName, Collection<?> values);
/**
* Not In - property has a value in the array of values.
*/
ExpressionList<T> notIn(String propertyName, Object... values);
/**
* Not In - property has a value in the collection of values.
*/
ExpressionList<T> notIn(String propertyName, Collection<?> values);
/**
* Not In - using a subQuery.
*/
ExpressionList<T> notIn(String propertyName, Query<?> subQuery);
/**
* Exists expression
*/
@@ -517,6 +791,14 @@ public interface ExpressionList<T> extends Serializable {
* then they are not translated. logical property name names (not fully
* qualified) will still be translated to their physical name.
* </p>
*
* <h4>Example:</h4>
* <pre>{@code
*
* // use a database function
* raw("add_days(orderDate, 10) < ?", someDate)
*
* }</pre>
*/
ExpressionList<T> raw(String raw, Object value);
@@ -532,7 +814,7 @@ public interface ExpressionList<T> extends Serializable {
* qualified) will still be translated to their physical name.
* </p>
*/
ExpressionList<T> raw(String raw, Object[] values);
ExpressionList<T> raw(String raw, Object... values);
/**
* Add raw expression with no parameters.
@@ -541,9 +823,56 @@ public interface ExpressionList<T> extends Serializable {
* then they are not translated. logical property name names (not fully
* qualified) will still be translated to their physical name.
* </p>
*
* <pre>{@code
*
* raw("orderQty < shipQty")
*
* }</pre>
*/
ExpressionList<T> raw(String raw);
/**
* Add a match expression.
*
* @param propertyName The property name for the match
* @param search The search value
*/
ExpressionList<T> match(String propertyName, String search);
/**
* Add a match expression with options.
*
* @param propertyName The property name for the match
* @param search The search value
*/
ExpressionList<T> match(String propertyName, String search, Match options);
/**
* Add a multi-match expression.
*/
ExpressionList<T> multiMatch(String search, String... properties);
/**
* Add a multi-match expression using options.
*/
ExpressionList<T> multiMatch(String search, MultiMatch options);
/**
* Add a simple query string expression.
*/
ExpressionList<T> textSimple(String search, TextSimple options);
/**
* Add a query string expression.
*/
ExpressionList<T> textQueryString(String search, TextQueryString options);
/**
* Add common terms expression.
*/
ExpressionList<T> textCommonTerms(String search, TextCommonTerms options);
/**
* And - join two expressions with a logical and.
*/
@@ -560,20 +889,168 @@ public interface ExpressionList<T> extends Serializable {
ExpressionList<T> not(Expression exp);
/**
* Return a list of expressions that will be joined by AND's.
* Start a list of expressions that will be joined by AND's
* returning the expression list the expressions are added to.
* <p>
* This is exactly the same as conjunction();
* </p>
* <p>
* Use endJunction() to end the AND junction.
* </p>
* <p>
* Note that a where() clause defaults to an AND junction so
* typically you only explicitly need to use the and() junction
* when it is nested inside an or() or not() junction.
* </p>
*
* <pre>{@code
*
* // Example: Nested and()
*
* Ebean.find(Customer.class)
* .where()
* .or()
* .and() // nested and
* .startsWith("name", "r")
* .eq("anniversary", onAfter)
* .endJunction() // end AND junction
* .and()
* .eq("status", Customer.Status.ACTIVE)
* .gt("id", 0)
* .endJunction() // end AND junction
* .orderBy().asc("name")
* .findList();
* }</pre>
*/
Junction<T> and();
/**
* Return a list of expressions that will be joined by OR's.
* This is exactly the same as disjunction();
*
* <p>
* Use endJunction() to end the OR junction.
* </p>
*
* <pre>{@code
*
* // Example: Use or() to join
* // two nested and() expressions
*
* Ebean.find(Customer.class)
* .where()
* .or()
* .and()
* .startsWith("name", "r")
* .eq("anniversary", onAfter)
* .endJunction() // end AND junction
* .and()
* .eq("status", Customer.Status.ACTIVE)
* .gt("id", 0)
* .endJunction() // end AND junction
* .orderBy().asc("name")
* .findList();
*
* }</pre>
*/
Junction<T> or();
/**
* Return a list of expressions that will be wrapped by NOT.
* <p>
* Use endJunction() to end expressions being added to the
* NOT expression list.
* </p>
*
* <pre>@{code
*
* .where()
* .not()
* .gt("id", 1)
* .eq("anniversary", onAfter)
* .endJunction() // end the not expressions
*
* }</pre>
*
* <pre>@{code
*
* // Example: nested not()
*
* Ebean.find(Customer.class)
* .where()
* .eq("status", Customer.Status.ACTIVE)
* .not()
* .gt("id", 1)
* .eq("anniversary", onAfter)
* .endJunction() // end the not expressions
* .orderBy()
* .asc("name")
* .findList();
*
* }</pre>
*/
Junction<T> not();
/**
* Start (and return) a list of expressions that will be joined by AND's.
* <p>
* This is the same as and().
* </p>
*/
Junction<T> conjunction();
/**
* Return a list of expressions that will be joined by OR's.
* Start (and return) a list of expressions that will be joined by OR's.
* <p>
* This is the same as or().
* </p>
*/
Junction<T> disjunction();
/**
* End a Conjunction or Disjunction returning the parent expression list.
* Start a list of expressions that will be joined by MUST.
* <p>
* Alternatively you can always use where() to return the top level expression
* list.
* This automatically makes the query a useDocStore(true) query that
* will execute against the document store (ElasticSearch etc).
* </p>
* <p>
* This is logically similar to and().
* </p>
*/
Junction<T> must();
/**
* Start a list of expressions that will be joined by SHOULD.
* <p>
* This automatically makes the query a useDocStore(true) query that
* will execute against the document store (ElasticSearch etc).
* </p>
* <p>
* This is logically similar to or().
* </p>
*/
Junction<T> should();
/**
* Start a list of expressions that will be joined by MUST NOT.
* <p>
* This automatically makes the query a useDocStore(true) query that
* will execute against the document store (ElasticSearch etc).
* </p>
* <p>
* This is logically similar to not().
* </p>
*/
Junction<T> mustNot();
/**
* End a junction returning the parent expression list.
* <p>
* Ends a and(), or(), not(), must(), mustNot() or should() junction
* such that you get the parent expression.
* </p>
* <p>
* Alternatively you can always use where() to return the top level expression list.
* </p>
*/
ExpressionList<T> endJunction();
+54 -36
View File
@@ -22,57 +22,57 @@ import java.io.Serializable;
* efficient loaded as 2 SQL queries.
* </p>
*
* <pre class="code">
* <pre>{@code
* // Normal fetch join results in a single SQL query
* List&lt;Order&gt; list = Ebean.find(Order.class).fetch(&quot;details&quot;).findList();
* List<Order> list = Ebean.find(Order.class).fetch("details").findList();
*
* // Find Orders join details using a single SQL query
* </pre>
* }</pre>
* <p>
* Example: Using a "query join" instead of a "fetch join" we instead use 2 SQL
* queries
* </p>
*
* <pre class="code">
* <pre>{@code
* // This will use 2 SQL queries to build this object graph
* List&lt;Order&gt; list =
* List<Order> list =
* Ebean.find(Order.class)
* .fetch(&quot;details&quot;, new FetchConfig().query())
* .fetch("details", new FetchConfig().query())
* .findList();
*
* // query 1) find order
* // query 2) find orderDetails where order.id in (?,?...) // first 100 order id's
* </pre>
* }</pre>
* <p>
* Example: Using 2 "query joins"
* </p>
*
* <pre class="code">
* <pre>{@code
* // This will use 3 SQL queries to build this object graph
* List&lt;Order&gt; list =
* List<Order> list =
* Ebean.find(Order.class)
* .fetch(&quot;details&quot;, new FetchConfig().query())
* .fetch(&quot;customer&quot;, new FetchConfig().queryFirst(5))
* .fetch("details", new FetchConfig().query())
* .fetch("customer", new FetchConfig().queryFirst(5))
* .findList();
*
* // query 1) find order
* // query 2) find orderDetails where order.id in (?,?...) // first 100 order id's
* // query 3) find customer where id in (?,?,?,?,?) // first 5 customers
* </pre>
* }</pre>
* <p>
* Example: Using "query joins" and partial objects
* </p>
*
* <pre class="code">
* <pre>{@code
* // This will use 3 SQL queries to build this object graph
* List&lt;Order&gt; list =
* List<Order> list =
* Ebean.find(Order.class)
* .select(&quot;status, shipDate&quot;)
* .fetch(&quot;details&quot;, &quot;quantity, price&quot;, new FetchConfig().query())
* .fetch(&quot;details.product&quot;, &quot;sku, name&quot;)
* .fetch(&quot;customer&quot;, &quot;name&quot;, new FetchConfig().queryFirst(5))
* .fetch(&quot;customer.contacts&quot;)
* .fetch(&quot;customer.shippingAddress&quot;)
* .select("status, shipDate")
* .fetch("details", "quantity, price", new FetchConfig().query())
* .fetch("details.product", "sku, name")
* .fetch("customer", "name", new FetchConfig().queryFirst(5))
* .fetch("customer.contacts")
* .fetch("customer.shippingAddress")
* .findList();
*
* // query 1) find order (status, shipDate)
@@ -81,22 +81,22 @@ import java.io.Serializable;
* // query 3) find customer (name) fetch contacts (*) fetch shippingAddress (*)
* // where id in (?,?,?,?,?)
*
* // Note: the fetch of &quot;details.product&quot; is automatically included into the
* // fetch of &quot;details&quot;
* // Note: the fetch of "details.product" is automatically included into the
* // fetch of "details"
* //
* // Note: the fetch of &quot;customer.contacts&quot; and &quot;customer.shippingAddress&quot;
* // are automatically included in the fetch of &quot;customer&quot;
* </pre>
* // Note: the fetch of "customer.contacts" and "customer.shippingAddress"
* // are automatically included in the fetch of "customer"
* }</pre>
* <p>
* You can use query() and lazy together on a single join. The query is executed
* immediately and the lazy defines the batch size to use for further lazy
* loading (if lazy loading is invoked).
* </p>
*
* <pre class="code">
* List&lt;Order&gt; list =
* <pre>{@code
* List<Order> list =
* Ebean.find(Order.class)
* .fetch(&quot;customer&quot;, new FetchConfig().query(10).lazy(5))
* .fetch("customer", new FetchConfig().query(10).lazy(5))
* .findList();
*
* // query 1) find order
@@ -104,7 +104,7 @@ import java.io.Serializable;
* // .. then if lazy loading of customers is invoked
* // .. use a batch size of 5 to load the customers
*
* </pre>
* }</pre>
*
* <p>
* Example of controlling the lazy loading query:
@@ -114,12 +114,12 @@ import java.io.Serializable;
* case.
* </p>
*
* <pre class="code">
* List&lt;Order&gt; list = Ebean.find(Order.class)
* .fetch(&quot;customer&quot;,&quot;name&quot;, new FetchConfig().lazy(5))
* .fetch(&quot;customer.contacts&quot;,&quotcontactName, phone, email&quot)
* .fetch(&quot;customer.shippingAddress&quot;)
* .where().eq(&quot;status&quot;,Order.Status.NEW)
* <pre>{@code
* List<Order> list = Ebean.find(Order.class)
* .fetch("customer","name", new FetchConfig().lazy(5))
* .fetch("customer.contacts",&quotcontactName, phone, email&quot)
* .fetch("customer.shippingAddress")
* .where().eq("status",Order.Status.NEW)
* .findList();
*
* // query 1) find order where status = Order.Status.NEW
@@ -132,7 +132,7 @@ import java.io.Serializable;
* fetch customer.shippingAddress (*)
* where id in (?,?,?,?,?)
*
* </pre>
* }</pre>
*
* @author mario
* @author rbygrave
@@ -249,4 +249,22 @@ public class FetchConfig implements Serializable {
return queryAll;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FetchConfig that = (FetchConfig) o;
if (lazyBatchSize != that.lazyBatchSize) return false;
if (queryBatchSize != that.queryBatchSize) return false;
return queryAll == that.queryAll;
}
@Override
public int hashCode() {
int result = lazyBatchSize;
result = 92821 * result + queryBatchSize;
result = 92821 * result + (queryAll ? 1 : 0);
return result;
}
}
@@ -0,0 +1,26 @@
package com.avaje.ebean;
import java.util.Set;
/**
* Provides paths and properties for an object graph that can be used to control what parts of the object graph
* is fetching (select and fetch clauses) and also can be used to control JSON marshalling (what parts of the object
* graph are included in the JSON).
*/
public interface FetchPath {
/**
* Return true if the path is included in this FetchPath.
*/
boolean hasPath(String path);
/**
* Return the properties at the given path.
*/
Set<String> getProperties(String path);
/**
* Apply the fetch path to the query.
*/
<T> void apply(Query<T> query);
}
+1 -1
View File
@@ -36,7 +36,7 @@ import java.util.Set;
* .sort(&quot;avgTimeMicros desc&quot;)
* .gt(&quot;executionCount&quot;, 0)
* .gt(&quot;lastQueryTime&quot;, nowMinus24Hrs)
* .eq(&quot;autofetchTuned&quot;, true)
* .eq(&quot;autoTuned&quot;, true)
* .maxRows(10)
* .filter(list);
*
+167
View File
@@ -0,0 +1,167 @@
package com.avaje.ebean;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* Intended to be used as a base class for 'Finder' implementations that can then
* be injected or used as public static fields on the associated entity bean.
* <p>
* These 'finders' are a place to organise all the finder methods for that bean type
* and specific finder methods are expected to be added (find by unique properties etc).
* </p>
*
* <h3>Testing</h3>
* <p>
* For testing the mocki-ebean project has the ability to replace the finder implementation
*
* </p>
* <pre>{@code
*
* public class CustomerFinder extends Finder<Customer> {
*
* public CustomerFinder() {
* super(Customer.class);
* }
*
* // Add your customer finder methods ...
*
* public Customer byName(String name) {
* return query().eq("name", name).findUnique();
* }
*
* public List<Customer> findNew() {
* return query()
* .eq("status", Customer.Status.NEW)
* .orderBy("name")
* .findList()
* }
* }
*
* @Entity
* public class Customer extends BaseModel {
*
* public static final CustomerFinder find = new CustomerFinder();
* ...
*
* }</pre>
*/
public class Finder<I, T> {
/**
* The entity bean type.
*/
private final Class<T> type;
/**
* The name of the EbeanServer, null for the default server.
*/
private final String serverName;
/**
* Create with the type of the entity bean.
*
* <pre>{@code
*
* public class CustomerFinder extends Finder<Customer> {
*
* public CustomerFinder() {
* super(Customer.class);
* }
*
* // ... add extra customer specific finder methods
* }
*
* @Entity
* public class Customer extends BaseModel {
*
* public static final CustomerFinder find = new CustomerFinder();
* ...
*
* }</pre>
*/
public Finder(Class<T> type) {
this.type = type;
this.serverName = null;
}
/**
* Create with the type of the entity bean and specific server name.
*/
public Finder(Class<T> type, String serverName) {
this.type = type;
this.serverName = serverName;
}
/**
* Return the underlying 'default' EbeanServer.
*
* <p>
* This provides full access to the API such as explicit transaction demarcation etc.
*
*/
public EbeanServer db() {
return Ebean.getServer(serverName);
}
/**
* Return typically a different EbeanServer to the default.
* <p>
* This is equivalent to {@link Ebean#getServer(String)}
*
* @param server
* The name of the EbeanServer. If this is null then the default EbeanServer is
* returned.
*/
public EbeanServer db(String server) {
return Ebean.getServer(server);
}
/**
* Creates an entity reference for this ID.
*
* <p>
* Equivalent to {@link EbeanServer#getReference(Class, Object)}
*/
public T ref(I id) {
return db().getReference(type, id);
}
/**
* Retrieves an entity by ID.
*
* <p>
* Equivalent to {@link EbeanServer#find(Class, Object)}
*/
@Nullable
public T byId(I id) {
return db().find(type, id);
}
/**
* Delete a bean by Id.
* <p>
* Equivalent to {@link EbeanServer#delete(Class, Object)}
*/
public void deleteById(I id) {
db().delete(type, id);
}
/**
* Retrieves all entities of the given type.
*/
public List<T> all() {
return query().findList();
}
/**
* Creates a query.
* <p>
* Equivalent to {@link EbeanServer#find(Class)}
*/
public Query<T> query() {
return db().find(type);
}
}
@@ -2,7 +2,6 @@ package com.avaje.ebean;
import javax.persistence.PersistenceException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+104 -45
View File
@@ -9,70 +9,129 @@ package com.avaje.ebean;
* <p>
* Note: where() always takes you to the top level WHERE expression list.
* </p>
*
* <pre class="code">
*
* <pre>{@code
* Query q =
* Ebean.find(Person.class)
* .where().disjunction()
* .like(&quot;name&quot;, &quot;Rob%&quot;)
* .eq(&quot;status&quot;, Status.NEW)
*
* // where() returns us to the top level expression list
* .where().gt(&quot;id&quot;, 10);
*
* .where()
* .or()
* .like("name", "Rob%")
* .eq("status", Status.NEW)
*
* // where() returns us to the top level expression list
* .where().gt("id", 10);
*
* // read as...
* // where ( ((name like Rob%) or (status = NEW)) AND (id &gt; 10) )
* </pre>
*
* }</pre>
*
* <p>
* Note: endJunction() takes you to the parent expression list
* </p>
*
* <pre class="code">
*
* <pre>{@code
* Query q =
* Ebean.find(Person.class)
* .where().disjunction()
* .like(&quot;name&quot;, &quot;Rob%&quot;)
* .eq(&quot;status&quot;, Status.NEW)
* .endJunction()
*
* // endJunction().. takes us to the 'parent' expression list
* // which in this case is the top level (same as where())
*
* .gt(&quot;id&quot;, 10);
*
* .where()
* .or()
* .like("name", "Rob%")
* .eq("status", Status.NEW)
* .endJunction()
*
* // endJunction().. takes us to the 'parent' expression list
* // which in this case is the top level (same as where())
*
* .gt("id", 10);
*
* // read as...
* // where ( ((name like Rob%) or (status = NEW)) AND (id &gt; 10) )
* </pre>
*
* // where ( ((name like Rob%) or (status = NEW)) AND (id > 10) )
* }</pre>
*
* <p>
* Example of a nested disjunction.
* </p>
*
* <pre class="code">
* Query&lt;Customer&gt; q =
*
* <pre>{@code
* Query<Customer> q =
* Ebean.find(Customer.class)
* .where()
* .disjunction()
* .conjunction()
* .startsWith(&quot;name&quot;, &quot;r&quot;)
* .eq(&quot;anniversary&quot;, onAfter)
* .endJunction()
* .conjunction()
* .eq(&quot;status&quot;, Customer.Status.ACTIVE)
* .gt(&quot;id&quot;, 0)
* .endJunction()
* .order().asc(&quot;name&quot;);
*
* .or()
* .and()
* .startsWith("name", "r")
* .eq("anniversary", onAfter)
* .endJunction()
* .and()
* .eq("status", Customer.Status.ACTIVE)
* .gt("id", 0)
* .endJunction()
* .order().asc("name");
*
* q.findList();
* String s = q.getGeneratedSql();
*
*
* // this produces an expression like:
*
* ( name like ? and c.anniversary = ? ) or (c.status = ? and c.id &gt; ? )
*
* </pre>
* ( name like ? and c.anniversary = ? ) or (c.status = ? and c.id > ? )
*
* }</pre>
*/
public interface Junction<T> extends Expression, ExpressionList<T> {
/**
* The type of Junction used in full text expressions.
*/
enum Type {
/**
* AND group.
*/
AND(" and ", ""),
/**
* OR group.
*/
OR(" or ", ""),
/**
* NOT group.
*/
NOT(" and ", "not "),
/**
* Text search AND group.
*/
MUST("must", ""),
/**
* Text search NOT group.
*/
MUST_NOT("must_not", ""),
/**
* Text search OR group.
*/
SHOULD("should", "");
String prefix;
String literal;
Type(String literal, String prefix) {
this.literal = literal;
this.prefix = prefix;
}
/**
* Return the literal value for this type.
*/
public String literal() {
return literal;
}
/**
* Return the prefix value for this type.
*/
public String prefix() {
return prefix;
}
}
}
+58 -21
View File
@@ -1,15 +1,14 @@
package com.avaje.ebean;
import com.avaje.ebean.text.PathProperties;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.util.ClassUtil;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import org.jetbrains.annotations.Nullable;
import javax.persistence.MappedSuperclass;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
/**
* A MappedSuperclass base class that provides convenience methods for inserting, updating and
@@ -152,7 +151,7 @@ public abstract class Model {
* }</pre>
*/
public static EbeanServer db() {
return Ebean.getServer(null);
return Ebean.getDefaultServer();
}
/**
@@ -194,7 +193,31 @@ public abstract class Model {
public void markAsDirty() {
db().markAsDirty(this);
}
/**
* Mark the property as unset or 'not loaded'.
* <p>
* This would be used to specify a property that we did not wish to include in a stateless update.
* </p>
* <pre>{@code
*
* // populate an entity bean from JSON or whatever
* User user = ...;
*
* // mark the email property as 'unset' so that it is not
* // included in a 'stateless update'
* user.markPropertyUnset("email");
*
* user.update();
*
* }</pre>
*
* @param propertyName the name of the property on the bean to be marked as 'unset'
*/
public void markPropertyUnset(String propertyName) {
((EntityBean)this)._ebean_getIntercept().setPropertyLoaded(propertyName, false);
}
/**
* Insert or update this entity depending on its state.
*
@@ -227,12 +250,24 @@ public abstract class Model {
}
/**
* Delete this entity.
* Delete this bean.
* <p>
* This will return true if the bean was deleted successfully or JDBC batch is being used.
* </p>
* <p>
* If there is no current transaction one will be created and committed for
* you automatically.
* </p>
* <p>
* If the Bean does not have a version property (or loaded version property) and
* the bean does not exist then this returns false indicating that nothing was
* deleted. Note that, if JDBC batch mode is used then this always returns true.
* </p>
*
* @see EbeanServer#delete(Object)
*/
public void delete() {
db().delete(this);
public boolean delete() {
return db().delete(this);
}
/**
@@ -252,8 +287,8 @@ public abstract class Model {
/**
* Perform a delete using this entity against the specified server.
*/
public void delete(String server) {
db(server).delete(this);
public boolean delete(String server) {
return db(server).delete(this);
}
/**
@@ -442,6 +477,7 @@ public abstract class Model {
*
* }</pre>
*/
@SuppressWarnings("unchecked")
public Find() {
this.serverName = null;
this.type = (Class<T>)ClassUtil.getSecondArgumentType(getClass());
@@ -451,8 +487,8 @@ public abstract class Model {
* Construct passing the class literal type of the entity type.
*/
protected Find(String serverName, Class<T> type) {
this.type = type;
this.serverName = serverName;
this.type = type;
}
/**
@@ -514,6 +550,7 @@ public abstract class Model {
* <p>
* Equivalent to {@link EbeanServer#find(Class, Object)}
*/
@Nullable
public T byId(I id) {
return db().find(type, id);
}
@@ -550,10 +587,10 @@ public abstract class Model {
/**
* Creates a query applying the path properties to set the select and fetch clauses.
* <p>
* Equivalent to {@link Query#apply(com.avaje.ebean.text.PathProperties)}
* Equivalent to {@link Query#apply(FetchPath)}
*/
public Query<T> apply(PathProperties pathProperties) {
return db().find(type).apply(pathProperties);
public Query<T> apply(FetchPath fetchPath) {
return db().find(type).apply(fetchPath);
}
/**
@@ -835,10 +872,10 @@ public abstract class Model {
}
/**
* Create a query with explicit 'Autofetch' use.
* Create a query with explicit 'AutoTune' use.
*/
public Query<T> setAutofetch(boolean autofetch) {
return query().setAutofetch(autofetch);
public Query<T> setAutoTune(boolean autoTune) {
return query().setAutoTune(autoTune);
}
/**
+27 -2
View File
@@ -28,7 +28,7 @@ public final class OrderBy<T> implements Serializable {
* Create an empty OrderBy with no associated query.
*/
public OrderBy() {
this.list = new ArrayList<Property>(2);
this.list = new ArrayList<Property>(3);
}
private OrderBy(List<Property> list) {
@@ -52,7 +52,7 @@ public final class OrderBy<T> implements Serializable {
*/
public OrderBy(Query<T> query, String orderByClause) {
this.query = query;
this.list = new ArrayList<Property>(2);
this.list = new ArrayList<Property>(3);
parse(orderByClause);
}
@@ -83,6 +83,19 @@ public final class OrderBy<T> implements Serializable {
return query;
}
/**
* Return true if the property is known to be contained in the order by clause.
*/
public boolean containsProperty(String propertyName) {
for (int i = 0; i < list.size(); i++) {
if (propertyName.equals(list.get(i).getProperty())) {
return true;
}
}
return false;
}
/**
* Return a copy of this OrderBy with the path trimmed.
*/
@@ -185,6 +198,18 @@ public final class OrderBy<T> implements Serializable {
return list.hashCode();
}
/**
* Clear the orderBy removing any current order by properties.
* <p>
* This is intended to be used when some code creates a query with a
* 'default' order by clause and some other code may clear the 'default'
* order by clause and replace.
* </p>
*/
public void clear() {
list.clear();
}
/**
* A property and its ascending descending order.
*/
@@ -17,6 +17,33 @@ import java.util.concurrent.Future;
* limit the result set.
* </p>
*
*
* <h4>Example: typical use including total row count</h4>
* <pre>{@code
*
* // We want to find the first 50 new orders
* // ... so we don't really need setFirstRow(0)
*
* PagedList<Order> pagedList
* = ebeanServer.find(Order.class)
* .where().eq("status", Order.Status.NEW)
* .order().asc("id")
* .setFirstRow(0)
* .setMaxRows(50)
* .findPagedList();
*
* // Optional: initiate the loading of the total
* // row count in a background thread
* pagedList.loadRowCount();
*
* // fetch and return the list in the foreground thread
* List<Order> orders = pagedList.getList();
*
* // get the total row count (from the future)
* int totalRowCount = pagedList.getTotalRowCount();
*
* }</pre>
*
* <h4>Example: typical use including total row count</h4>
* <pre>{@code
*
@@ -156,9 +183,18 @@ public interface PagedList<T> {
/**
* Return the index position of this page. Zero based.
* <p>
* Note that if firstRows/maxRows is used rather than pageIndex/pageSize then
* this always returns 0.
* </p>
*/
int getPageIndex();
/**
* Return the page size used for this query. This is the same value as maxRows used by the query.
*/
int getPageSize();
/**
* Return true if there is a next page.
* <p>
@@ -0,0 +1,18 @@
package com.avaje.ebean;
import javax.persistence.PersistenceException;
/**
* Captures and wraps IOException's occurring during ElasticSearch processing etc.
*/
public class PersistenceIOException extends PersistenceException {
public PersistenceIOException(String msg, Exception cause) {
super(msg, cause);
}
public PersistenceIOException(Exception cause) {
super(cause);
}
}
@@ -34,7 +34,7 @@ class PrimaryServer {
/**
* Return the default server name.
*/
static synchronized String getPrimaryServerName() {
static synchronized String getDefaultServerName() {
getProperties();
return defaultServerName;
}
@@ -58,15 +58,18 @@ class PrimaryServer {
*/
private static String determineDefaultServerName() {
String defaultServerName = System.getProperty("datasource.default");
String defaultServerName = System.getenv("EBEAN_DB");
if (isEmpty(defaultServerName)) {
defaultServerName = System.getProperty("ebean.default.datasource");
}
if (isEmpty(defaultServerName)) {
defaultServerName = globalProperties.getProperty("datasource.default");
}
if (isEmpty(defaultServerName)) {
defaultServerName = globalProperties.getProperty("ebean.default.datasource");
defaultServerName = System.getProperty("datasource.default");
if (isEmpty(defaultServerName)) {
defaultServerName = System.getProperty("ebean.default.datasource");
if (isEmpty(defaultServerName)) {
defaultServerName = globalProperties.getProperty("datasource.default");
if (isEmpty(defaultServerName)) {
defaultServerName = globalProperties.getProperty("ebean.default.datasource");
}
}
}
}
return defaultServerName;
}
+192 -34
View File
@@ -1,8 +1,9 @@
package com.avaje.ebean;
import com.avaje.ebean.text.PathProperties;
import org.jetbrains.annotations.Nullable;
import java.io.Serializable;
import javax.persistence.NonUniqueResultException;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -65,9 +66,9 @@ import java.util.Set;
* ...
* }</pre>
*
* <h3>Autofetch</h3>
* <h3>AutoTune</h3>
* <p>
* Ebean has built in support for "Autofetch". This is a mechanism where a query
* Ebean has built in support for "AutoTune". This is a mechanism where a query
* can be automatically tuned based on profiling information that is collected.
* </p>
* <p>
@@ -76,7 +77,7 @@ import java.util.Set;
* more.
* </p>
* <p>
* It is expected that Autofetch will be the default approach for many queries
* It is expected that AutoTune will be the default approach for many queries
* in a system. It is possibly not as useful where the result of a query is sent
* to a remote client or where there is some requirement for "Read Consistency"
* guarantees.
@@ -272,7 +273,7 @@ import java.util.Set;
* @param <T>
* the type of Entity bean this query will fetch.
*/
public interface Query<T> extends Serializable {
public interface Query<T> {
/**
* Return the RawSql that was set to use for this query.
@@ -284,6 +285,27 @@ public interface Query<T> extends Serializable {
*/
Query<T> setRawSql(RawSql rawSql);
/**
* Perform an 'As of' query using history tables to return the object graph
* as of a time in the past.
* <p>
* To perform this query the DB must have underlying history tables.
* </p>
*
* @param asOf the date time in the past at which you want to view the data
*/
Query<T> asOf(Timestamp asOf);
/**
* Execute the query against the draft set of tables.
*/
Query<T> asDraft();
/**
* Execute the query including soft deleted rows.
*/
Query<T> includeSoftDeletes();
/**
* Cancel the query execution if supported by the underlying database and
* driver.
@@ -325,23 +347,23 @@ public interface Query<T> extends Serializable {
ExpressionFactory getExpressionFactory();
/**
* Returns true if this query was tuned by autoFetch.
* Returns true if this query was tuned by autoTune.
*/
boolean isAutofetchTuned();
boolean isAutoTuned();
/**
* Explicitly specify whether to use Autofetch for this query.
* Explicitly specify whether to use AutoTune for this query.
* <p>
* If you do not call this method on a query the "Implicit Autofetch mode" is
* used to determine if Autofetch should be used for a given query.
* If you do not call this method on a query the "Implicit AutoTune mode" is
* used to determine if AutoTune should be used for a given query.
* </p>
* <p>
* Autofetch can add additional fetch paths to the query and specify which
* AutoTune can add additional fetch paths to the query and specify which
* properties are included for each path. If you have explicitly defined some
* fetch paths Autofetch will not remove.
* fetch paths AutoTune will not remove them.
* </p>
*/
Query<T> setAutofetch(boolean autofetch);
Query<T> setAutoTune(boolean autoTune);
/**
* Set the default lazy loading batch size to use.
@@ -353,6 +375,16 @@ public interface Query<T> extends Serializable {
*/
Query<T> setLazyLoadBatchSize(int lazyLoadBatchSize);
/**
* Disable read auditing for this query.
* <p>
* This is intended to be used when the query is not a user initiated query and instead
* part of the internal processing in an application to load a cache or document store etc.
* In these cases we don't want the query to be part of read auditing.
* </p>
*/
Query<T> setDisableReadAuditing();
/**
* Explicitly set a comma delimited list of the properties to fetch on the
* 'main' root level entity bean (aka partial object). Note that '*' means all
@@ -483,15 +515,15 @@ public interface Query<T> extends Serializable {
*
* }</pre>
*/
Query<T> fetch(String path, FetchConfig joinConfig);
Query<T> fetch(String path, FetchConfig fetchConfig);
/**
* Apply the path properties replacing the select and fetch clauses.
* <p>
* This is typically used when the PathProperties is applied to both the query and the JSON output.
* This is typically used when the FetchPath is applied to both the query and the JSON output.
* </p>
*/
Query<T> apply(PathProperties pathProperties);
Query<T> apply(FetchPath fetchPath);
/**
* Execute the query returning the list of Id's.
@@ -520,19 +552,7 @@ public interface Query<T> extends Serializable {
*/
QueryIterator<T> findIterate();
/**
* This is deprecated in favor of #findEachWhile.
* <p>
* This is functionally exactly the same as #findEachWhile. It is
* replaced by findEachWhile because the method name is much better.
* </p>
*
* @param visitor
* the visitor used to process the queried beans.
*
* @deprecated
*/
void findVisit(QueryResultVisitor<T> visitor);
/**
* Execute the query processing the beans one at a time.
@@ -679,7 +699,7 @@ public interface Query<T> extends Serializable {
* Execute the query returning either a single bean or null (if no matching
* bean is found).
* <p>
* If more than 1 row is found for this query then a PersistenceException is
* If more than 1 row is found for this query then a NonUniqueResultException is
* thrown.
* </p>
* <p>
@@ -715,9 +735,47 @@ public interface Query<T> extends Serializable {
* List<OrderDetail> details = order.getDetails();
* ...
* }</pre>
*
* @throws NonUniqueResultException if more than one result was found
*/
@Nullable
T findUnique();
/**
* Return versions of a @History entity bean.
* <p>
* Note that this query will work against view based history implementations
* but not sql2011 standards based implementations that require a start and
* end timestamp to be specified.
* </p>
* <p>
* Generally this query is expected to be a find by id or unique predicates query.
* It will execute the query against the history returning the versions of the bean.
* </p>
*/
List<Version<T>> findVersions();
/**
* Return versions of a @History entity bean between the 2 timestamps.
* <p>
* Generally this query is expected to be a find by id or unique predicates query.
* It will execute the query against the history returning the versions of the bean.
* </p>
*/
List<Version<T>> findVersionsBetween(Timestamp start, Timestamp end);
/**
* Execute as a delete query deleting the 'root level' beans that match the predicates
* in the query.
* <p>
* Note that if the query includes joins then the generated delete statement may not be
* optimal depending on the database platform.
* </p>
*
* @return the number of beans/rows that were deleted.
*/
int delete();
/**
* Return the count of entities this query should return.
* <p>
@@ -762,7 +820,7 @@ public interface Query<T> extends Serializable {
FutureList<T> findFutureList();
/**
* Return a PagedList for this query.
* Return a PagedList for this query using pageIndex and pageSize.
* <p>
* The benefit of using this over just using the normal {@link Query#setFirstRow(int)} and
* {@link Query#setMaxRows(int)} is that it additionally wraps an optional call to
@@ -807,6 +865,36 @@ public interface Query<T> extends Serializable {
*/
PagedList<T> findPagedList(int pageIndex, int pageSize);
/**
* Return a PagedList for this query using firstRow and maxRows.
* <p>
* The benefit of using this over findList() is that it provides functionality to get the
* total row count etc.
* </p>
* <p>
* If maxRows is not set on the query prior to calling findPagedList() then a
* PersistenceException is thrown.
* </p>
*
* <pre>{@code
*
* PagedList<Order> pagedList = Ebean.find(Order.class)
* .setFirstRow(50)
* .setMaxRows(20)
* .findPagedList();
*
* // fetch the total row count in the background
* pagedList.loadRowCount();
*
* List<Order> orders = pagedList.getList();
* int totalRowCount = pagedList.getTotalRowCount();
*
* }</pre>
*
* @return The PagedList
*/
PagedList<T> findPagedList();
/**
* Set a named bind parameter. Named parameters have a colon to prefix the name.
*
@@ -878,6 +966,11 @@ public interface Query<T> extends Serializable {
*/
Query<T> setId(Object id);
/**
* Return the Id value.
*/
Object getId();
/**
* Add additional clause(s) to the where clause.
* <p>
@@ -948,6 +1041,27 @@ public interface Query<T> extends Serializable {
*/
ExpressionList<T> where();
/**
* Add Full text search expressions for Document store queries.
* <p>
* This is currently ElasticSearch only and provides the full text
* expressions such as Match and Multi-Match.
* </p>
* <p>
* This automatically makes this query a "Doc Store" query and will execute
* against the document store (ElasticSearch).
* </p>
* <p>
* Expressions added here are added to the "query" section of an ElasticSearch
* query rather than the "filter" section.
* </p>
* <p>
* Expressions added to the where() are added to the "filter" section of an
* ElasticSearch query.
* </p>
*/
ExpressionList<T> text();
/**
* This applies a filter on the 'many' property list rather than the root
* level objects.
@@ -1113,6 +1227,19 @@ public interface Query<T> extends Serializable {
/**
* Set whether this query uses DISTINCT.
* <p>
* The select() clause MUST be specified when setDistinct(true) is set. The reason for this is that
* generally ORM queries include the "id" property and this doesn't make sense for distinct queries.
* </p>
* <pre>{@code
*
* List<Customer> customers =
* Ebean.find(Customer.class)
* .setDistinct(true)
* .select("name")
* .findList();
*
* }</pre>
*/
Query<T> setDistinct(boolean isDistinct);
@@ -1123,8 +1250,8 @@ public interface Query<T> extends Serializable {
/**
* Set the first row to return for this query.
*
* @param firstRow
*
* @param firstRow the first row to include in the query result.
*/
Query<T> setFirstRow(int firstRow);
@@ -1178,6 +1305,14 @@ public interface Query<T> extends Serializable {
*/
Query<T> setUseQueryCache(boolean useQueryCache);
/**
* Set to true if this query should execute against the doc store.
* <p>
* When setting this you may also consider disabling lazy loading.
* </p>
*/
Query<T> setUseDocStore(boolean useDocStore);
/**
* When set to true when you want the returned beans to be read only.
*/
@@ -1235,4 +1370,27 @@ public interface Query<T> extends Serializable {
* Set root table alias.
*/
Query<T> alias(String alias);
/**
* Return the type of beans being queried.
*/
Class<T> getBeanType();
/**
* Set true if you want to disable lazy loading.
* <p>
* That is, once the object graph is returned further lazy loading is disabled.
* </p>
*/
Query<T> setDisableLazyLoading(boolean disableLazyLoading);
/**
* Returns the set of properties or paths that are unknown (do not map to known properties or paths).
* <p>
* Validate the query checking the where and orderBy expression paths to confirm if
* they represent valid properties or paths for the given bean type.
* </p>
*/
Set<String> validate();
}
@@ -1,49 +0,0 @@
package com.avaje.ebean;
/**
* Used to process a query result one bean at a time via a callback to this
* visitor.
* <p>
* If you wish to stop further processing return false from the accept method.
* </p>
* <p>
* Unlike findList() and findSet() using a QueryResultVisitor does not require
* all the beans in the query result to be held in memory at once. This makes
* QueryResultVisitor useful for processing large queries.
* </p>
*
* <pre class="code">
*
* Query&lt;Customer&gt; query = server.find(Customer.class)
* .fetch(&quot;contacts&quot;, new FetchConfig().query(2))
* .where().gt(&quot;id&quot;, 0)
* .orderBy(&quot;id&quot;)
* .setMaxRows(2);
*
* query.findVisit(new QueryResultVisitor&lt;Customer&gt;() {
*
* public boolean accept(Customer customer) {
* // do something with customer
* System.out.println(&quot;-- visit &quot; + customer);
* return true;
* }
* });
* </pre>
*
* @author rbygrave
*
* @param <T>
* the type of entity bean being queried.
*/
public interface QueryResultVisitor<T> {
/**
* Process the bean and return true if you want to continue processing more
* beans. Return false if you want to stop processing further.
*
* @param bean
* the entity bean to process
* @return true to continue processing or false to stop.
*/
boolean accept(T bean);
}
+90 -47
View File
@@ -206,6 +206,14 @@ public final class RawSql implements Serializable {
return sql;
}
/**
* Return the key;
*/
public Key getKey() {
boolean parsed = sql != null && sql.parsed;
String unParsedSql = (sql == null) ? "" : sql.unparsedSql;
return new Key(parsed, unParsedSql, columnMapping);
}
/**
* Return the resultSet if this is a ResultSet based RawSql.
@@ -221,16 +229,6 @@ public final class RawSql implements Serializable {
return columnMapping;
}
/**
* Return the hash for this query.
*/
public int queryHash() {
if (resultSet != null) {
return 31 * columnMapping.queryHash();
}
return 31 * sql.queryHash() + columnMapping.queryHash();
}
/**
* Represents the sql part of the query. For parsed RawSql the sql is broken
* up so that Ebean can insert extra WHERE and HAVING expressions into the
@@ -260,13 +258,10 @@ public final class RawSql implements Serializable {
private final boolean distinct;
private final int queryHashCode;
/**
* Construct for unparsed SQL.
*/
protected Sql(String unparsedSql) {
this.queryHashCode = unparsedSql.hashCode();
this.parsed = false;
this.unparsedSql = unparsedSql;
this.preFrom = null;
@@ -282,12 +277,11 @@ public final class RawSql implements Serializable {
/**
* Construct for parsed SQL.
*/
protected Sql(int queryHashCode, String preFrom, String preWhere, boolean andWhereExpr,
protected Sql(String unparsedSql, String preFrom, String preWhere, boolean andWhereExpr,
String preHaving, boolean andHavingExpr, String orderByPrefix, String orderBy, boolean distinct) {
this.queryHashCode = queryHashCode;
this.unparsedSql = unparsedSql;
this.parsed = true;
this.unparsedSql = null;
this.preFrom = preFrom;
this.preHaving = preHaving;
this.preWhere = preWhere;
@@ -298,13 +292,6 @@ public final class RawSql implements Serializable {
this.distinct = distinct;
}
/**
* Return a hash for this query.
*/
public int queryHash() {
return queryHashCode;
}
public String toString() {
if (!parsed) {
return "unparsed[" + unparsedSql + "]";
@@ -406,13 +393,10 @@ public final class RawSql implements Serializable {
private final boolean immutable;
private final int queryHashCode;
/**
* Construct from parsed sql where the columns have been identified.
*/
protected ColumnMapping(List<Column> columns) {
this.queryHashCode = 0;
this.immutable = false;
this.parsed = true;
this.propertyMap = null;
@@ -428,7 +412,6 @@ public final class RawSql implements Serializable {
* Construct for unparsed sql.
*/
protected ColumnMapping() {
this.queryHashCode = 0;
this.immutable = false;
this.parsed = false;
this.propertyMap = null;
@@ -443,17 +426,13 @@ public final class RawSql implements Serializable {
this.immutable = false;
this.parsed = false;
this.propertyMap = null;
//this.propertyColumnMap = null;
this.dbColumnMap = new LinkedHashMap<String, Column>();
int hc = 31;
int pos = 0;
for (String prop : propertyNames) {
hc = 31 * hc + prop.hashCode();
dbColumnMap.put(prop, new Column(pos++, prop, null, prop));
}
propertyColumnMap = dbColumnMap;
this.queryHashCode = hc;
}
/**
@@ -464,20 +443,35 @@ public final class RawSql implements Serializable {
this.parsed = parsed;
this.dbColumnMap = dbColumnMap;
int hc = ColumnMapping.class.getName().hashCode();
HashMap<String, Column> pcMap = new HashMap<String, Column>();
HashMap<String, String> pMap = new HashMap<String, String>();
for (Column c : dbColumnMap.values()) {
pMap.put(c.getPropertyName(), c.getDbColumn());
pcMap.put(c.getPropertyName(), c);
hc = 31 * hc + ((c.getPropertyName() == null) ? 0 : c.getPropertyName().hashCode());
hc = 31 * hc + ((c.getDbColumn() == null) ? 0 : c.getDbColumn().hashCode());
}
this.propertyMap = Collections.unmodifiableMap(pMap);
this.propertyColumnMap = Collections.unmodifiableMap(pcMap);
this.queryHashCode = hc;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ColumnMapping that = (ColumnMapping) o;
return dbColumnMap.equals(that.dbColumnMap);
}
@Override
public int hashCode() {
return dbColumnMap.hashCode();
}
/**
* Return true if the property is mapped.
*/
public boolean contains(String property) {
return this.propertyColumnMap.containsKey(property);
}
/**
@@ -514,16 +508,6 @@ public final class RawSql implements Serializable {
}
}
/**
* Return the query hash for this column mapping.
*/
public int queryHash() {
if (queryHashCode == 0) {
throw new RuntimeException("Bug: queryHashCode == 0");
}
return queryHashCode;
}
/**
* Returns true if the Columns where supplied by parsing the sql select
* clause.
@@ -578,6 +562,9 @@ public final class RawSql implements Serializable {
* <p>
* For example modify all mappings with table alias "c" to have the path prefix "customer".
* </p>
* <p>
* For the "Root type" you don't need to specify a tableAliasMapping.
* </p>
*/
public void tableAliasMapping(String tableAlias, String path) {
@@ -638,6 +625,27 @@ public final class RawSql implements Serializable {
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Column that = (Column) o;
if (indexPos != that.indexPos) return false;
if (!dbColumn.equals(that.dbColumn)) return false;
if (dbAlias != null ? !dbAlias.equals(that.dbAlias) : that.dbAlias != null) return false;
return propertyName != null ? propertyName.equals(that.propertyName) : that.propertyName == null;
}
@Override
public int hashCode() {
int result = indexPos;
result = 31 * result + dbColumn.hashCode();
result = 31 * result + (dbAlias != null ? dbAlias.hashCode() : 0);
result = 31 * result + (propertyName != null ? propertyName.hashCode() : 0);
return result;
}
public String toString() {
return dbColumn + "->" + propertyName;
}
@@ -689,4 +697,39 @@ public final class RawSql implements Serializable {
}
}
}
/**
* A key for the RawSql object using for the query plan.
*/
public static final class Key {
private final boolean parsed;
private final ColumnMapping columnMapping;
private final String unParsedSql;
Key(boolean parsed, String unParsedSql, ColumnMapping columnMapping) {
this.parsed = parsed;
this.unParsedSql = unParsedSql;
this.columnMapping = columnMapping;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Key that = (Key) o;
return parsed == that.parsed
&& columnMapping.equals(that.columnMapping)
&& unParsedSql.equals(that.unParsedSql);
}
@Override
public int hashCode() {
int result = (parsed ? 1 : 0);
result = 31 * result + columnMapping.hashCode();
result = 31 * result + unParsedSql.hashCode();
return result;
}
}
}
@@ -106,6 +106,9 @@ public class RawSqlBuilder {
* <p>
* For example modify all mappings with table alias "c" to have the path prefix "customer".
* </p>
* <p>
* For the "Root type" you don't need to specify a tableAliasMapping.
* </p>
*/
public RawSqlBuilder tableAliasMapping(String tableAlias, String path) {
columnMapping.tableAliasMapping(tableAlias, path);
+1 -1
View File
@@ -153,7 +153,7 @@ public interface SqlRow extends Serializable, Map<String, Object> {
/**
* Put all the values from t into this map.
*/
void putAll(Map<? extends String, ? extends Object> t);
void putAll(Map<? extends String, ?> t);
/**
* Return the size of the map.
+37 -2
View File
@@ -1,8 +1,9 @@
package com.avaje.ebean;
import com.avaje.ebean.annotation.DocStoreMode;
import com.avaje.ebean.config.DocStoreConfig;
import com.avaje.ebean.config.PersistBatch;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import javax.persistence.RollbackException;
import java.io.Closeable;
@@ -82,6 +83,29 @@ public interface Transaction extends Closeable {
*/
boolean isActive();
/**
* Set the behavior for document store updates on this transaction.
* <p>
* For example, set the mode to DocStoreEvent.IGNORE for this transaction and
* then any changes via this transaction are not sent to the doc store. This
* would be used when doing large bulk inserts into the database and we want
* to control how that is sent to the document store.
* </p>
*/
void setDocStoreMode(DocStoreMode mode);
/**
* Set the batch size to use for sending messages to the document store.
* <p>
* You might set this if you know the changes in this transaction result in especially large or
* especially small payloads and want to adjust the batch size to match.
* </p>
* <p>
* Setting this overrides the default of {@link DocStoreConfig#getBulkBatchSize()}
* </p>
*/
void setDocStoreBatchSize(int batchSize);
/**
* Explicitly turn off or on the cascading nature of save() and delete(). This
* gives the developer exact control over what beans are saved and deleted
@@ -97,6 +121,17 @@ public interface Transaction extends Closeable {
*/
void setPersistCascade(boolean persistCascade);
/**
* Set to true when you want all loaded properties to be included in the update
* (rather than just the changed properties).
* <p>
* You might set this when using JDBC batch in order to get multiple updates
* with slightly different sets of changed properties into the same statement
* and hence better JDBC batch performance.
* </p>
*/
void setUpdateAllLoadedProperties(boolean updateAllLoadedProperties);
/**
* Turn on or off statement batching. Statement batching can be transparent
* for drivers and databases that support getGeneratedKeys. Otherwise you may
@@ -279,7 +314,7 @@ public interface Transaction extends Closeable {
* <li>Transaction commit occurs</li>
* </ul>
*/
void flushBatch() throws PersistenceException, OptimisticLockException;
void flushBatch() throws PersistenceException;
/**
* Return the underlying Connection object.
+1 -1
View File
@@ -46,5 +46,5 @@ public enum TxType {
* If there is an existing transaction throws an Exception. Method runs
* without a transaction.
*/
NEVER;
NEVER
}
+18 -11
View File
@@ -5,10 +5,19 @@ package com.avaje.ebean;
*/
public class ValuePair {
private final Object newValue;
protected Object newValue;
private final Object oldValue;
protected Object oldValue;
/**
* Default constructor for JSON tools.
*/
public ValuePair() {
}
/**
* Construct with the pair of new and old values.
*/
public ValuePair(Object newValue, Object oldValue) {
this.newValue = newValue;
this.oldValue = oldValue;
@@ -27,21 +36,19 @@ public class ValuePair {
public Object getOldValue() {
return oldValue;
}
/**
* Return the new value.
* Set the new value.
*/
@Deprecated
public Object getValue1() {
return newValue;
public void setNewValue(Object newValue) {
this.newValue = newValue;
}
/**
* Return the old value.
* Set the old value.
*/
@Deprecated
public Object getValue2() {
return oldValue;
public void setOldValue(Object oldValue) {
this.oldValue = oldValue;
}
public String toString() {
+101
View File
@@ -0,0 +1,101 @@
package com.avaje.ebean;
import java.sql.Timestamp;
import java.util.Map;
/**
* Wraps a version of a @History bean.
*/
public class Version<T> {
/**
* The version of the bean.
*/
protected T bean;
/**
* The effective start date time of this version.
*/
protected Timestamp start;
/**
* The effective end date time of this version.
*/
protected Timestamp end;
/**
* The map of changed properties.
*/
protected Map<String, ValuePair> diff;
/**
* Construct with bean and an effective date time range.
*/
public Version(T bean, Timestamp start, Timestamp end) {
this.bean = bean;
this.start = start;
this.end = end;
}
/**
* Default constructor - useful for JSON tools such as Jackson.
*/
public Version() {
}
/**
* Return the bean instance for this version.
*/
public T getBean() {
return bean;
}
/**
* Set the bean instance for this version.
*/
public void setBean(T bean) {
this.bean = bean;
}
/**
* Return the effective start date time of this version.
*/
public Timestamp getStart() {
return start;
}
/**
* Set the effective start date time of this version.
*/
public void setStart(Timestamp start) {
this.start = start;
}
/**
* Return the effective end date time of this version.
*/
public Timestamp getEnd() {
return end;
}
/**
* Set the effective end date time of this version.
*/
public void setEnd(Timestamp end) {
this.end = end;
}
/**
* Set the map of differences from this bean to the prior version.
*/
public void setDiff(Map<String, ValuePair> diff) {
this.diff = diff;
}
/**
* Return the map of differences from this bean to the prior version.
*/
public Map<String, ValuePair> getDiff() {
return diff;
}
}
@@ -44,4 +44,12 @@ public @interface CacheTuning {
* </p>
*/
int maxSecsToLive() default 0;
/**
* The frequency (in seconds) that cache trimming should occur.
* <p>
* This is a hint for cache implementations that use background cache trimming.
* </p>
*/
int trimFrequency() default 0;
}
@@ -0,0 +1,34 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks an entity bean as being included in the change logging.
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ChangeLog {
/**
* Specify if inserts should be explicitly Included or Excluded.
* <p>
* If not defined explicitly then the server default behaviour defined
* on ServerConfig is used.
* </p>
*/
ChangeLogInsertMode inserts() default ChangeLogInsertMode.DEFAULT;
/**
* When specified only include update requests that have at least one
* of the given properties as a dirty property.
* <p>
* This provides a way to filter requests to include in the change log such that
* only updates that include at least one of the given properties is included
* in the change log.
* </p>
*/
String[] updatesThatInclude() default {};
}
@@ -0,0 +1,22 @@
package com.avaje.ebean.annotation;
/**
* The mode used to determine if inserts should be included or not for a given bean type.
*/
public enum ChangeLogInsertMode {
/**
* Use the default behaviour as defined on ServerConfig.
*/
DEFAULT,
/**
* Include inserts in the change log.
*/
INCLUDE,
/**
* Exclude inserts in the change log.
*/
EXCLUDE
}
@@ -9,6 +9,10 @@ import java.lang.annotation.Target;
* For a timestamp property that is set to the datetime when the entity is
* created/inserted.
* <p>
* This is effectively an alias for @WhenCreated which was added as it hints
* towards a better naming convention (WhenCreated, WhenModified).
* </p>
* <p>
* An alternative to using this annotation would be to use insertable=false,
* updateable=false with @Column and have the DB insert the current time
* (default value on the DB column is SYSTIME etc).
@@ -0,0 +1,19 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* A database table or column comment.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
public @interface DbComment {
/**
* The database table or column comment.
*/
String value();
}
@@ -0,0 +1,17 @@
package com.avaje.ebean.annotation;
/**
* Specify the DB storage type used to with <code>@DbEnumValue</code>.
*/
public enum DbEnumType {
/**
* Store values as database INTEGER.
*/
INTEGER,
/**
* Store values as database VARCHAR.
*/
VARCHAR
}
@@ -0,0 +1,44 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specify a method on an Enum that returns the value that should be stored in the DB.
* <p>
* This is the preferred option for mapping Enum's to DB values (preferred over the JPA
* standard @Enumerated and Ebean's @EnumValue annotations).
* </p>
* <h3>Example:</h3>
* <pre>{@code
*
* public enum Status {
* NEW("N"),
* ACTIVE("A"),
* INACTIVE("I");
*
* String dbValue;
* Status(String dbValue) {
* this.dbValue = dbValue;
* }
*
* @DbEnumValue
* public String getValue() {
* return dbValue;
* }
* }
*
* }</pre>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DbEnumValue {
/**
* Specify the database type used to store the values (VARCHAR or INTEGER).
*/
DbEnumType storage() default DbEnumType.VARCHAR;
}
@@ -0,0 +1,32 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used to indicate that a particular string property should be treated as a 'code' and not analysed for text searching.
* <p>
* By default all Id properties and all Enum properties are treated as 'code' and not analysed.
* </p>
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DocCode {
/**
* Set to true to have the property additionally stored separately from _source.
*/
boolean store() default false;
/**
* Set a boost value specific to this property.
*/
float boost() default 1;
/**
* Set a value to use instead of null.
*/
String nullValue() default "";
}
@@ -0,0 +1,24 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specify the entity type maps to a document store (like ElasticSearch).
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface DocMapping {
/**
* The property name the mapping applies to.
*/
String name();
/**
* Mapping options.
*/
DocProperty options();
}
@@ -0,0 +1,110 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specify the entity type maps to a document store (like ElasticSearch).
*/
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface DocProperty {
/**
* Set this to true to indicate that this property should be un-analysed.
*/
boolean code() default false;
/**
* Set this to true to get an additional un-analysed 'raw' field to use for sorting etc.
*/
boolean sortable() default false;
/**
* Set to true to have the property additionally stored separately from _source.
*/
boolean store() default false;
/**
* Set a boost value specific to this property.
*/
float boost() default 1;
/**
* Set a value to use instead of null.
*/
String nullValue() default "";
/**
* Set this to false to exclude this from the _all property.
*/
boolean includeInAll() default true;
/**
* The analyzer to use.
*/
String analyzer() default "";
/**
* The analyzer to use for searches.
*/
String searchAnalyzer() default "";
/**
* The index options for this property.
*/
Option options() default Option.DEFAULT;
/**
* Set this to false such that doc values are not stored separately for this property.
*/
boolean docValues() default true;
/**
* Set a copyTo field.
*/
String copyTo() default "";
/**
* Set to false to disable the field from indexing, it will only be get/set in _source.
*/
boolean enabled() default true;
/**
* Set to false such that norms are not stored.
*/
boolean norms() default true;
/**
* Index options for a property.
*/
enum Option {
/**
* Only index the doc number.
*/
DOCS,
/**
* Doc number and term frequencies are indexed.
*/
FREQS,
/**
* Doc number, term frequencies and term positions are indexed.
*/
POSITIONS,
/**
* Doc number, term frequencies, term positions and start/end offsets are indexed.
*/
OFFSETS,
/**
* Use the default which means analysed string properties use POSITIONS as the default and all other types use DOCS.
*/
DEFAULT
}
}
@@ -0,0 +1,34 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used to indicate that a particular string property should support sorting. What this typically means is that
* for ElasticSearch an additional 'raw' field is added that stores the un-analysed value. This un-analysed value
* can be used for sorting etc and the original field used for text searching.
* <p>
* For example, customer name and product name are good candidates for marking with @DocSortable.
* </p>
*/
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface DocSortable {
/**
* Set to true to have the property additionally stored separately from _source.
*/
boolean store() default false;
/**
* Set a boost value specific to this property.
*/
float boost() default 1;
/**
* Set a value to use instead of null.
*/
String nullValue() default "";
}
@@ -0,0 +1,88 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specify the entity type maps to a document store (like ElasticSearch).
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface DocStore {
/**
* A unique Id used when queuing reindex events.
*/
String queueId() default "";
/**
* The ElasticSearch index name. If left unspecified the short name of the bean type is used.
*/
String indexName() default "";
/**
* The ElasticSearch index type. If left unspecified the short name of the bean type is used.
*/
String indexType() default "";
/**
* The number of shards this index should use.
*/
int shards() default 0;
/**
* The number of replicas this index should use.
*/
int replicas() default 0;
/**
* Additional mapping that can be defined on the properties.
*/
DocMapping[] mapping() default {};
/**
* Specify the behavior when bean Insert, Update, Delete events occur.
*/
DocStoreMode persist() default DocStoreMode.DEFAULT;
/**
* Specify the behavior when bean Insert occurs.
*/
DocStoreMode insert() default DocStoreMode.DEFAULT;
/**
* Specify the behavior when bean Update occurs.
*/
DocStoreMode update() default DocStoreMode.DEFAULT;
/**
* Specify the behavior when bean Delete occurs.
*/
DocStoreMode delete() default DocStoreMode.DEFAULT;
/**
* Specify to include only some properties in the doc store document.
* <p>
* If this is left as default then all scalar properties are included,
* all @ManyToOne properties are included with just the nested id property
* and no @OneToMany properties are included.
* </p>
* <p>
* Note that typically DocStoreEmbedded is used on @ManyToOne and @OneToMany
* properties to indicate what part of the nested document should be included.
* </p>
*
* <h3>Example:</h3>
* <pre>{@code
*
* // only include the customer id and name
* @DocStore(doc = "id,name")
* @Entity @Table(name = "o_order")
* public class Customer {
*
* }</pre>
*/
String doc() default "";
}
@@ -0,0 +1,37 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specify the property is included in the parent document store index.
*
* <pre>{@code
*
*
* @DocStore
* @Entity @Table(name = "o_order")
* public class Order {
*
* ...
* // include some customer details including
* // nested billingAddress
* @DocStoreEmbedded(doc = "id,status,name,billingAddress(*,country(*)")
* @ManyToOne
* Customer customer;
*
*
* }</pre>
*/
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface DocStoreEmbedded {
/**
* The properties on the embedded bean to include in the index.
*/
String doc() default "";
}
@@ -0,0 +1,38 @@
package com.avaje.ebean.annotation;
/**
* Defines the behavior options when a Insert, Update or Delete event occurs
* on a bean with an associated ElasticSearch index.
* <p>
* For some indexes or some transactions it can be beneficial to queue the event
* for later processing rather than look to update ElasticSearch at that time.
* </p>
*/
public enum DocStoreMode {
/**
* Add the event to the queue for processing later (delaying the update to the document store).
*/
QUEUE,
/**
* Update the document store when transaction succeeds.
*/
UPDATE,
/**
* Ignore the event and not update the document store.
* <p>
* This can be used on a index or for a transaction where you want to have more
* manual programmatic control over the updating of the document store. Say you want to
* IGNORE on a particular transaction and instead manually queue a bulk update.
* </p>
*/
IGNORE,
/**
* The actual mode of QUEUE, UPDATE or IGNORE is set from the default configuration.
*/
DEFAULT
}
@@ -0,0 +1,19 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks a boolean property on a @Draftable bean that indicates if the bean instance is a 'draft' or 'live' bean.
* The property is transient and has no underlying DB column.
* <p>
* For beans returned from an <code>asDraft()</code> query this property will be set to true.
* </p>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Draft {
}
@@ -0,0 +1,20 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks a boolean property on a @Draftable bean that only exists on the 'draft' table
* and is used to detect when a draft has unpublished changes.
* <p>
* This property will automatically have it's value set to true when a draft is saved and
* automatically have it's value set to false when the bean is published.
* </p>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface DraftDirty {
}
@@ -0,0 +1,19 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks a property on a @Draftable bean that only exists on the 'draft' and not the 'live' table.
* <p>
* Typically this would be used on a property that is used as part of application 'workflow' such as
* a publish workflow status or when publish timestamp.
* </p>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface DraftOnly {
}
@@ -0,0 +1,19 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks a property on a @Draftable bean that is set to null on the 'draft bean' on publish.
* <p>
* This is expected to be put on properties that get 'reset' or 'cleared' after a publish.
* These properties might represent a publish comment or publish timestamp.
* </p>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface DraftReset {
}
@@ -0,0 +1,29 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used to indicate an entity bean that has 'draftable' support.
* <p>
* This means that a second set of tables is created to hold draft versions of
* the rows and that these can then be published which effectively copies/transfers
* the values from the 'draft' table to the 'live' table.
* </p>
* <p>
* Ebean Query supports 'find as draft' which builds the resulting object graph using
* the draft tables. This object graph is typically edited, approved in some application
* specific manor and then published.
* </p>
* <p>
* EbeanServer has a publish method which transfers/copies the draft object graph to
* the 'live' tables.
* </p>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Draftable {
}
@@ -0,0 +1,20 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used to indicate an entity bean that has 'draftable' support but it not a 'top level'
* (or root level) bean but instead child related to another @Draftable entity bean.
* <p>
* Relationships to @DraftableElements (@OneToMany, @ManyToMany etc) are automatically
* deemed to have Cascade.ALL for save and delete (as well as orphan removal mode).
* </p>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DraftableElement {
}
@@ -25,7 +25,7 @@ import java.lang.annotation.Target;
* }</pre>
* <p>
* This is an alternative to using the JPA standard approach or Ebean's
* {@link EnumMapping} annotation.
* {@link DbEnumValue} annotation.
* </p>
* <p>
* Note that if all the EnumValue values are parsable as Integers then Ebean
@@ -0,0 +1,19 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks an entity bean as having history support.
* <p>
* In Postgres for example this means there is an associated history table which is
* typically automatically populated via database triggers.
* </p>
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface History {
}
@@ -0,0 +1,25 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks a property as being excluded from history.
* <p>
* This means the property values are not maintained in the history table. Typically this
* would be placed on relatively large properties (Clobs, Blobs, large varchar columns etc)
* that are considered not interesting enough to maintain history on excluding them reduces
* underlying database costs.
* </p>
* <p>
* When placed on a ManyToMany this means that the intersection table does not have history
* support.
* </p>
*/
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface HistoryExclude {
}
@@ -10,15 +10,24 @@ import java.lang.annotation.Target;
*
* @author rvbiljouw
*/
@Target({ElementType.FIELD})
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Index {
/**
* Name of the index
*
* @return index name
* Name of the index. If left blank a name is derived using the built in naming convention.
*/
String value() default "";
String name() default "";
/**
* If set true indicates this is a unique index.
*/
boolean unique() default false;
/**
* When placed on the class (rather than field) you can specify the columns
* to include in the index in order.
*/
String[] columnNames() default {};
}
@@ -0,0 +1,32 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Similar to Jackson JsonIgnore but provides the option to just ignore serialize or deserialize.
* <p>
* This provides the same features as Expose but from the opposite perspective which is probably
* more common and more familiar to Jackson users.
* </p>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface JsonIgnore {
/**
* If {@code true}, the field marked with this annotation is written out in the JSON while
* serializing. If {@code false}, the field marked with this annotation is skipped from the
* serialized output. Defaults to {@code false}.
*/
boolean serialize() default false;
/**
* If {@code true}, the field marked with this annotation is deserialized from the JSON.
* If {@code false}, the field marked with this annotation is skipped during deserialization.
* Defaults to {@code false}.
*/
boolean deserialize() default false;
}
@@ -6,12 +6,10 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Deprecated - please use @DbHstore instead.
* @see DbHstore
* Marks an entity bean as being included in read auditing.
*/
@Deprecated
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ColumnHstore {
public @interface ReadAudit {
}
}
@@ -0,0 +1,25 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used to indicate a property on an entity bean used to control 'soft delete'
* (also known as 'logical delete').
* <p>
* The property should be of type boolean.
* </p>
* <pre>{@code
*
* @SoftDelete
* boolean deleted;
*
* }</pre>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SoftDelete {
}
@@ -8,6 +8,10 @@ import java.lang.annotation.Target;
/**
* For a timestamp property that is set to the datetime when the entity was last
* updated.
* <p>
* This is effectively an alias for @WhenModified which was added as it hints
* towards a better naming convention (WhenCreated, WhenModified).
* </p>
*/
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@@ -0,0 +1,38 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* For a timestamp property that is set to the datetime when the entity is
* created/inserted.
* <p>
* This is effectively an alias for @CreatedTimestamp and added to hint
* towards a better naming convention (WhenCreated, WhenModified).
* </p>
* <p>
* An alternative to using this annotation would be to use insertable=false,
* updateable=false with @Column and have the DB insert the current time
* (default value on the DB column is SYSTIME etc).
* </p>
* <p>
* The downside to this approach is that the inserted entity does not have the
* timestamp value after the insert has occurred. You need to fetch the entity
* back to get the inserted timestamp if you want to used it.
* </p>
*
* <h3>Example:</h3>
* <pre>{@code
*
* @WhenCreated
* Timestamp whenCreated;
*
* }</pre>
*/
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface WhenCreated {
}
@@ -0,0 +1,19 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* For a timestamp property that is set to the datetime when the entity was last modified.
* <p>
* This is effectively an alias for @UpdatedTimestamp and added to hint
* towards a better naming convention (WhenCreated, WhenModified).
* </p>
*/
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface WhenModified {
}
@@ -0,0 +1,29 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Mapped onto a entity bean property that represents the user id of
* who created the entity>
* <p>
* To use this annotation you need to implement CurrentUserProvider.
* The type of the bean property should match the type returned by
* CurrentUserProvider.
*</p>
* <h3>Example:</h3>
* <pre>{@code
*
* @WhoCreated
* String whoCreated;
*
* }</pre>
*/
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface WhoCreated {
}
@@ -0,0 +1,29 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Mapped onto a entity bean property that represents the user id of
* who last modified the entity>
* <p>
* To use this annotation you need to implement CurrentUserProvider.
* The type of the bean property should match the type returned by
* CurrentUserProvider.
* </p>
*
* <h3>Example:</h3>
* <pre>{@code
*
* @WhoModified
* String whoModified;
*
* }</pre>
*/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface WhoModified {
}
@@ -31,6 +31,21 @@ public interface BeanCollection<E> extends Serializable {
ALL
}
/**
* Load bean from another collection.
*/
void loadFrom(BeanCollection<?> other);
/**
* Add a bean to the list/set with modifyListen notification.
*/
void addBean(E bean);
/**
* Remove a bean to the list/set with modifyListen notification.
*/
void removeBean(E bean);
/**
* Reset the collection back to an empty state ready for reloading.
* <p>
@@ -115,6 +130,11 @@ public interface BeanCollection<E> extends Serializable {
*/
void internalAdd(Object bean);
/**
* Add the bean with a check to see if it is already contained.
*/
void internalAddWithCheck(Object bean);
/**
* Return the number of elements in the List Set or Map.
*/
@@ -12,5 +12,5 @@ public interface BeanCollectionAdd {
/**
* Add a loaded bean to the collection.
*/
void addBean(EntityBean bean);
void addEntityBean(EntityBean bean);
}
@@ -6,7 +6,7 @@ import java.util.Arrays;
/**
* Represent the call stack (stack trace elements).
* <p>
* Used with a query to identify a CallStackQuery for AutoFetch automatic query
* Used with a query to identify a CallStackQuery for AutoTune automatic query
* tuning.
* </p>
* <p>
@@ -26,16 +26,12 @@ public final class CallStack implements Serializable {
private final StackTraceElement[] callStack;
public CallStack(StackTraceElement[] callStack) {
public CallStack(StackTraceElement[] callStack, int zeroHash, int pathHash) {
this.callStack = callStack;
this.zeroHash = enc(callStack[0].hashCode());
int hc = 0;
for (int i = 1; i < callStack.length; i++) {
hc = 31 * hc + callStack[i].hashCode();
}
this.pathHash = enc(hc);
this.zeroHash = enc(zeroHash);
this.pathHash = enc(pathHash);
}
public int hashCode() {
int hc = 0;
for (int i = 0; i < callStack.length; i++) {
@@ -87,8 +83,19 @@ public final class CallStack implements Serializable {
return zeroHash + ":" + pathHash + ":" + callStack[0];
}
/**
* Return the call stack lines appended with the given newLine string.
*/
public String description(String newLine) {
StringBuilder sb = new StringBuilder(400);
for (int i = 0; i < callStack.length; i++) {
sb.append(callStack[i].toString()).append(newLine);
}
return sb.toString();
}
public String getOriginKey(int queryHash) {
return zeroHash + "." + enc(queryHash) + "." + pathHash;
return enc(queryHash)+ "." + zeroHash + "." + pathHash;
}
private static final int radix = 1 << 6;
@@ -73,16 +73,6 @@ public interface EntityBean extends Serializable {
*/
EntityBeanIntercept _ebean_intercept();
/**
* Create a copy of this entity bean.
* <p>
* This occurs when a bean is changed. The copy represents the bean as it was
* initially (oldValues) before any changes where made. This is used for
* optimistic concurrency control.
* </p>
*/
Object _ebean_createCopy();
/**
* Set the value of a field of an entity bean of this type.
* <p>
@@ -1,5 +1,10 @@
package com.avaje.ebean.bean;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.ValuePair;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceException;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
@@ -11,12 +16,6 @@ import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceException;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.ValuePair;
/**
* This is the object added to every entity bean using byte code enhancement.
* <p>
@@ -45,7 +44,7 @@ public final class EntityBeanIntercept implements Serializable {
/**
* The actual entity bean that 'owns' this intercept.
*/
private EntityBean owner;
private final EntityBean owner;
private EntityBean embeddedOwner;
private int embeddedOwnerIndex;
@@ -72,7 +71,7 @@ public final class EntityBeanIntercept implements Serializable {
/**
* Used when a bean is partially filled.
*/
private boolean[] loadedProps;
private final boolean[] loadedProps;
private boolean fullyLoadedBean;
@@ -92,6 +91,8 @@ public final class EntityBeanIntercept implements Serializable {
private int lazyLoadProperty = -1;
private Object ownerId;
/**
* Create a intercept with a given entity.
* <p>
@@ -218,6 +219,18 @@ public final class EntityBeanIntercept implements Serializable {
this.fullyLoadedBean = fullyLoadedBean;
}
/**
* Check each property to see if the bean is partially loaded.
*/
public boolean isPartial() {
for (int i = 0; i < loadedProps.length; i++) {
if (!loadedProps[i]) {
return true;
}
}
return false;
}
/**
* Return true if this bean has been directly modified (it has oldValues) or
* if any embedded beans are either new or dirty (and hence need saving).
@@ -342,18 +355,11 @@ public final class EntityBeanIntercept implements Serializable {
}
/**
* Check if the lazy load succeeded. If not then mark this bean as having
* failed lazy loading due to the underlying row being deleted.
* <p>
* We mark the bean this way rather than immediately fail as we might be batch
* lazy loading and this bean might not be used by the client code at all.
* Instead we will fail as soon as the client code tries to use this bean.
* </p>
* Set lazy load failure flag.
*/
public void checkLazyLoadFailure() {
if (lazyLoadProperty != -1) {
this.lazyLoadFailure = true;
}
public void setLazyLoadFailure(Object ownerId) {
this.lazyLoadFailure = true;
this.ownerId = ownerId;
}
/**
@@ -449,7 +455,18 @@ public final class EntityBeanIntercept implements Serializable {
public int getPropertyLength() {
return owner._ebean_getPropertyNames().length;
}
/**
* Set the loaded state of the property given it's name.
*/
public void setPropertyLoaded(String propertyName, boolean loaded) {
int position = findProperty(propertyName);
if (position == -1) {
throw new IllegalArgumentException("Property "+propertyName+" not found");
}
loadedProps[position] = loaded;
}
/**
* Set the property to be treated as unloaded. Used for properties initialised in default
* constructor.
@@ -464,7 +481,7 @@ public final class EntityBeanIntercept implements Serializable {
public void setLoadedProperty(int propertyIndex) {
loadedProps[propertyIndex] = true;
}
/**
* Return true if the property is loaded.
*/
@@ -496,7 +513,7 @@ public final class EntityBeanIntercept implements Serializable {
setDirty(true);
}
private void setChangedProperty(int propertyIndex) {
public void setChangedProperty(int propertyIndex) {
if (changedProps == null) {
changedProps = new boolean[owner._ebean_getPropertyNames().length];
}
@@ -555,6 +572,23 @@ public final class EntityBeanIntercept implements Serializable {
return props;
}
/**
* Return the array of flags indicating the dirty properties.
*/
public boolean[] getDirtyProperties() {
int len = getPropertyLength();
boolean[] dirties = new boolean[len];
for (int i = 0; i < len; i++) {
if (changedProps != null && changedProps[i]) {
dirties[i] = true;
} else if (embeddedDirty != null && embeddedDirty[i]) {
// an embedded property has been changed - recurse
dirties[i] = true;
}
}
return dirties;
}
/**
* Return the set of dirty properties.
*/
@@ -581,7 +615,29 @@ public final class EntityBeanIntercept implements Serializable {
}
}
}
/**
* Return true if any of the given property names are dirty.
*/
public boolean hasDirtyProperty(Set<String> propertyNames) {
String[] names = owner._ebean_getPropertyNames();
int len = getPropertyLength();
for (int i = 0; i < len; i++) {
if (changedProps != null && changedProps[i]) {
// the property has been changed on this bean
if (propertyNames.contains(names[i])) {
return true;
}
} else if (embeddedDirty != null && embeddedDirty[i]) {
if (propertyNames.contains(names[i])) {
return true;
}
}
}
return false;
}
/**
* Return a map of dirty properties with their new and old values.
*/
@@ -608,7 +664,7 @@ public final class EntityBeanIntercept implements Serializable {
} else if (embeddedDirty != null && embeddedDirty[i]) {
// an embedded property has been changed - recurse
EntityBean embeddedBean = (EntityBean)owner._ebean_getField(i);
embeddedBean._ebean_getIntercept().addDirtyPropertyValues(dirtyValues, getProperty(i)+".");
embeddedBean._ebean_getIntercept().addDirtyPropertyValues(dirtyValues, getProperty(i) + ".");
}
}
}
@@ -638,6 +694,20 @@ public final class EntityBeanIntercept implements Serializable {
return hash;
}
/**
* Return a loaded property hash.
*/
public int getLoadedPropertyHash() {
int hash = 37;
int len = getPropertyLength();
for (int i = 0; i < len; i++) {
if (isLoadedProperty(i)) {
hash = hash * 31 + (i+1);
}
}
return hash;
}
/**
* Return the set of property names for changed properties.
*/
@@ -701,7 +771,7 @@ public final class EntityBeanIntercept implements Serializable {
if (lazyLoadFailure) {
// failed when batch lazy loaded by another bean in the batch
throw new EntityNotFoundException("Bean has been deleted - lazy loading failed");
throw new EntityNotFoundException("Lazy loading failed on type:" + owner.getClass().getName() + " id:" + ownerId + " - Bean has been deleted");
}
if (lazyLoadProperty == -1) {
@@ -716,7 +786,7 @@ public final class EntityBeanIntercept implements Serializable {
if (lazyLoadFailure) {
// failed when lazy loading this bean
throw new EntityNotFoundException("Bean has been deleted - lazy loading failed");
throw new EntityNotFoundException("Lazy loading failed on type:" + owner.getClass().getName() + " id:" + ownerId + " - Bean has been deleted.");
}
// bean should be loaded and intercepting now. setLoaded() has
@@ -877,7 +947,7 @@ public final class EntityBeanIntercept implements Serializable {
} else {
return null;
}
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
}
/**
@@ -892,7 +962,7 @@ public final class EntityBeanIntercept implements Serializable {
} else {
return null;
}
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Integer.valueOf(oldValue), Integer.valueOf(newValue));
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
}
/**
@@ -908,7 +978,7 @@ public final class EntityBeanIntercept implements Serializable {
return null;
}
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Long.valueOf(oldValue), Long.valueOf(newValue));
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
}
/**
@@ -923,7 +993,7 @@ public final class EntityBeanIntercept implements Serializable {
} else {
return null;
}
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Double.valueOf(oldValue), Double.valueOf(newValue));
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
}
/**
@@ -938,7 +1008,7 @@ public final class EntityBeanIntercept implements Serializable {
} else {
return null;
}
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Float.valueOf(oldValue), Float.valueOf(newValue));
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
}
/**
@@ -953,7 +1023,7 @@ public final class EntityBeanIntercept implements Serializable {
} else {
return null;
}
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Short.valueOf(oldValue), Short.valueOf(newValue));
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
}
/**
@@ -968,7 +1038,7 @@ public final class EntityBeanIntercept implements Serializable {
} else {
return null;
}
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Character.valueOf(oldValue), Character.valueOf(newValue));
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
}
/**
@@ -983,7 +1053,7 @@ public final class EntityBeanIntercept implements Serializable {
} else {
return null;
}
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Byte.valueOf(oldValue), Byte.valueOf(newValue));
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
}
/**
@@ -1,13 +1,13 @@
package com.avaje.ebean.bean;
import java.lang.ref.WeakReference;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* Collects profile information for a bean (or reference/proxy bean) at a given
* AutoFetchNode.
* Collects profile information for a bean (or reference/proxy bean) at a given node.
* <p>
* The AutoFetchNode identifies the location of the bean in the object graph.
* The node identifies the location of the bean in the object graph.
* </p>
* <p>
* It has to use a weak reference so as to ensure that it does not stop the
@@ -29,7 +29,7 @@ public final class NodeUsageCollector {
/**
* The properties used at this profile point.
*/
private final HashSet<String> used = new HashSet<String>();
private final Set<String> used = new LinkedHashSet<String>();
/**
* set to true if the bean is modified (setter called)
@@ -105,7 +105,7 @@ public final class NodeUsageCollector {
/**
* Return the set of used properties.
*/
public HashSet<String> getUsed() {
public Set<String> getUsed() {
return used;
}
@@ -9,7 +9,7 @@ public interface NodeUsageListener {
* Collect node usage "profiling" information.
* <p>
* This is the properties that are used for a given bean in the object graph.
* This information is used by autoFetch to tune queries.
* This information is used by autoTune to tune queries.
* </p>
*/
void collectNodeUsage(NodeUsageCollector collector);
@@ -82,6 +82,7 @@ public final class ObjectGraphNode implements Serializable {
}
ObjectGraphNode e = (ObjectGraphNode) obj;
//noinspection StringEquality
return ((e.path == path) || (e.path != null && e.path.equals(path)))
&& e.originQueryPoint.equals(originQueryPoint);
}
@@ -9,7 +9,7 @@ import java.io.Serializable;
* The call stack is included so that the query can have different tuned fetches
* for each unique call stack. For example, a query to fetch a customer could be
* called by three different methods and each can be treated as a separate
* origin point (and autoFetch can tune each one separately).
* origin point (and autoTune can tune each one separately).
* </p>
*/
public final class ObjectGraphOrigin implements Serializable {
@@ -10,31 +10,31 @@ package com.avaje.ebean.bean;
public interface PersistenceContext {
/**
* Put the entity bean into the PersistanceContext.
* Put the entity bean into the PersistenceContext.
*/
void put(Object id, Object bean);
void put(Class<?> rootType, Object id, Object bean);
/**
* Put the entity bean into the PersistanceContext if one is not already
* Put the entity bean into the PersistenceContext if one is not already
* present (for this id).
* <p>
* Returns an existing entity bean (if one is already there) and otherwise
* returns null.
* </p>
*/
Object putIfAbsent(Object id, Object bean);
Object putIfAbsent(Class<?> rootType, Object id, Object bean);
/**
* Return an object given its type and unique id.
*/
Object get(Class<?> beanType, Object uid);
Object get(Class<?> rootType, Object uid);
/**
* Get the bean from the persistence context also checked to see if it had
* been previously deleted (if so then you also can't hit the L2 cache to
* fetch the bean for this particular persistence context).
*/
WithOption getWithOption(Class<?> beanType, Object uid);
WithOption getWithOption(Class<?> rootType, Object uid);
/**
* Clear all the references.
@@ -44,22 +44,22 @@ public interface PersistenceContext {
/**
* Clear all the references for a given type of entity bean.
*/
void clear(Class<?> beanType);
void clear(Class<?> rootType);
/**
* Clear the reference to a specific entity bean.
*/
void clear(Class<?> beanType, Object uid);
void clear(Class<?> rootType, Object uid);
/**
* Clear the reference as a result of an entity being deleted.
*/
void deleted(Class<?> beanType, Object id);
void deleted(Class<?> rootType, Object id);
/**
* Return the number of beans of the given type in the persistence context.
*/
int size(Class<?> beanType);
int size(Class<?> rootType);
/**
* Wrapper on a bean to also indicate if a bean has been deleted.
@@ -74,12 +74,12 @@ public interface PersistenceContext {
* The bean was previously deleted from this persistence context (can't hit
* L2 cache).
*/
public static WithOption DELETED = new WithOption(true);
public static final WithOption DELETED = new WithOption();
private final boolean deleted;
private final Object bean;
private WithOption(boolean deleted) {
private WithOption() {
this.deleted = true;
this.bean = null;
}
@@ -0,0 +1,21 @@
package com.avaje.ebean.bean;
import javax.persistence.Entity;
/**
* Utility to find the root bean type.
*/
public class PersistenceContextUtil {
/**
* Find and return the root bean type for the given class.
*/
public static Class<?> root(Class<?> beanType) {
Class<?> parent = beanType.getSuperclass();
while (parent != null && parent.isAnnotationPresent(Entity.class)) {
beanType = parent;
parent = parent.getSuperclass();
}
return beanType;
}
}
-6
View File
@@ -48,12 +48,6 @@ public interface ServerCache {
*/
Object put(Object id, Object value);
/**
* Put the value in the cache but only if a matching value is not already in
* the cache.
*/
Object putIfAbsent(Object id, Object value);
/**
* Remove a entry from the cache given its id.
*/
+24 -5
View File
@@ -10,6 +10,7 @@ public class ServerCacheOptions {
private int maxSize;
private int maxIdleSecs;
private int maxSecsToLive;
private int trimFrequency;
/**
* Construct with no set options.
@@ -25,15 +26,17 @@ public class ServerCacheOptions {
this.maxSize = cacheTuning.maxSize();
this.maxIdleSecs = cacheTuning.maxIdleSecs();
this.maxSecsToLive = cacheTuning.maxSecsToLive();
this.trimFrequency = cacheTuning.trimFrequency();
}
/**
* Create merging default options with the deployment specified ones.
*/
public ServerCacheOptions(ServerCacheOptions d) {
this.maxSize = d.getMaxSize();
this.maxIdleSecs = d.getMaxIdleSecs();
this.maxSecsToLive = d.getMaxIdleSecs();
public ServerCacheOptions(ServerCacheOptions defaults) {
this.maxSize = defaults.getMaxSize();
this.maxIdleSecs = defaults.getMaxIdleSecs();
this.maxSecsToLive = defaults.getMaxIdleSecs();
this.trimFrequency = defaults.getTrimFrequency();
}
/**
@@ -50,6 +53,9 @@ public class ServerCacheOptions {
if (maxSecsToLive == 0) {
maxSecsToLive = defaults.getMaxSecsToLive();
}
if (trimFrequency == 0) {
trimFrequency = defaults.getTrimFrequency();
}
}
/**
@@ -61,7 +67,7 @@ public class ServerCacheOptions {
copy.maxSize = maxSize;
copy.maxIdleSecs = maxIdleSecs;
copy.maxSecsToLive = maxSecsToLive;
copy.trimFrequency = trimFrequency;
return copy;
}
@@ -107,4 +113,17 @@ public class ServerCacheOptions {
this.maxSecsToLive = maxSecsToLive;
}
/**
* Return the trim frequency in seconds.
*/
public int getTrimFrequency() {
return trimFrequency;
}
/**
* Set the trim frequency in seconds.
*/
public void setTrimFrequency(int trimFrequency) {
this.trimFrequency = trimFrequency;
}
}
+177 -24
View File
@@ -5,9 +5,9 @@ package com.avaje.ebean.cache;
* <p>
* These can be monitored to review the effectiveness of a particular cache.
* </p>
*
* @author rbygrave
*
* <p>
* Depending on the cache implementation not all the statistics may be collected.
* </p>
*/
public class ServerCacheStatistics {
@@ -17,21 +17,64 @@ public class ServerCacheStatistics {
protected int size;
protected int hitCount;
protected long hitCount;
protected int missCount;
protected long missCount;
protected long insertCount;
protected long updateCount;
protected long removeCount;
protected long clearCount;
protected long evictionRunCount;
protected long evictionRunMicros;
protected long evictByIdle;
protected long evictByTTL;
protected long evictByLRU;
public String toString() {
StringBuilder sb = new StringBuilder();
//noinspection StringBufferReplaceableByString
StringBuilder sb = new StringBuilder(80);
sb.append(cacheName);
sb.append(" maxSize:").append(maxSize);
sb.append(" size:").append(size);
sb.append(" hitRatio:").append(getHitRatio());
sb.append(" hitCount:").append(hitCount);
sb.append(" missCount:").append(missCount);
sb.append(" maxSize:").append(maxSize);
sb.append(" hit:").append(hitCount);
sb.append(" miss:").append(missCount);
sb.append(" insert:").append(insertCount);
sb.append(" update:").append(updateCount);
sb.append(" remove:").append(removeCount);
sb.append(" clear:").append(clearCount);
sb.append(" evictByIdle:").append(evictByIdle);
sb.append(" evictByTTL:").append(evictByTTL);
sb.append(" evictByLRU:").append(evictByLRU);
sb.append(" evictionRunCount:").append(evictionRunCount);
sb.append(" evictionRunMicros:").append(evictionRunMicros);
return sb.toString();
}
/**
* Returns an int from 0 to 100 (percentage) for the hit ratio.
* <p>
* A hit ratio of 100 means every get request against the cache hits an entry.
* </p>
*/
public int getHitRatio() {
long totalCount = hitCount + missCount;
if (totalCount == 0) {
return 0;
} else {
return (int)(hitCount * 100 / totalCount);
}
}
/**
* Return the name of the cache.
*/
@@ -49,28 +92,28 @@ public class ServerCacheStatistics {
/**
* Return the hit count. The number of successful gets.
*/
public int getHitCount() {
public long getHitCount() {
return hitCount;
}
/**
* Set the hit count.
*/
public void setHitCount(int hitCount) {
public void setHitCount(long hitCount) {
this.hitCount = hitCount;
}
/**
* Return the miss count. The number of gets that returned null.
*/
public int getMissCount() {
public long getMissCount() {
return missCount;
}
/**
* Set the miss count.
*/
public void setMissCount(int missCount) {
public void setMissCount(long missCount) {
this.missCount = missCount;
}
@@ -107,18 +150,128 @@ public class ServerCacheStatistics {
}
/**
* Returns an int from 0 to 100 (percentage) for the hit ratio.
* <p>
* A hit ratio of 100 means every get request against the cache hits an entry.
* </p>
* Set the put insert count.
*/
public int getHitRatio() {
int totalCount = hitCount + missCount;
if (totalCount == 0) {
return 0;
} else {
return hitCount * 100 / totalCount;
}
public void setInsertCount(long insertCount) {
this.insertCount = insertCount;
}
/**
* Return the put insert count.
*/
public long getInsertCount() {
return insertCount;
}
/**
* Set the put update count.
*/
public void setUpdateCount(long updateCount) {
this.updateCount = updateCount;
}
/**
* Return the put update count.
*/
public long getUpdateCount() {
return updateCount;
}
/**
* Set the remove count.
*/
public void setRemoveCount(long removeCount) {
this.removeCount = removeCount;
}
/**
* Return the remove count.
*/
public long getRemoveCount() {
return removeCount;
}
/**
* Set the clear count.
*/
public void setClearCount(long clearCount) {
this.clearCount = clearCount;
}
/**
* Return the clear count.
*/
public long getClearCount() {
return clearCount;
}
/**
* Set the eviction run count.
*/
public void setEvictionRunCount(long evictCount) {
this.evictionRunCount = evictCount;
}
/**
* Return the eviction run count.
*/
public long getEvictionRunCount() {
return evictionRunCount;
}
/**
* Set the eviction run time in micros.
*/
public void setEvictionRunMicros(long evictionRunMicros) {
this.evictionRunMicros = evictionRunMicros;
}
/**
* Return the eviction run time in micros.
*/
public long getEvictionRunMicros() {
return evictionRunMicros;
}
/**
* Set the count of entries evicted due to idle time.
*/
public void setEvictByIdle(long evictByIdle) {
this.evictByIdle = evictByIdle;
}
/**
* Return the count of entries evicted due to idle time.
*/
public long getEvictByIdle() {
return evictByIdle;
}
/**
* Set the count of entries evicted due to time to live.
*/
public void setEvictByTTL(long evictByTTL) {
this.evictByTTL = evictByTTL;
}
/**
* Return the count of entries evicted due to time to live.
*/
public long getEvictByTTL() {
return evictByTTL;
}
/**
* Set the count of entries evicted due to time least recently used.
*/
public void setEvictByLRU(long evictByLRU) {
this.evictByLRU = evictByLRU;
}
/**
* Return the count of entries evicted due to time least recently used.
*/
public long getEvictByLRU() {
return evictByLRU;
}
}
@@ -1,5 +1,10 @@
package com.avaje.ebean.common;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollectionAdd;
import com.avaje.ebean.bean.BeanCollectionLoader;
import com.avaje.ebean.bean.EntityBean;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
@@ -8,17 +13,13 @@ import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import com.avaje.ebean.bean.BeanCollectionAdd;
import com.avaje.ebean.bean.BeanCollectionLoader;
import com.avaje.ebean.bean.EntityBean;
/**
* List capable of lazy loading.
*/
public final class BeanList<E> extends AbstractBeanCollection<E> implements List<E>, BeanCollectionAdd {
private static final long serialVersionUID = 1L;
/**
* The underlying List implementation.
*/
@@ -60,10 +61,19 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
}
@SuppressWarnings("unchecked")
public void addBean(EntityBean bean) {
public void addEntityBean(EntityBean bean) {
list.add((E) bean);
}
@Override
@SuppressWarnings("unchecked")
public void loadFrom(BeanCollection<?> other) {
if (list == null) {
list = new ArrayList<E>();
}
list.addAll((Collection<? extends E>) other.getActualDetails());
}
@SuppressWarnings("unchecked")
public void internalAdd(Object bean) {
if (list == null) {
@@ -74,6 +84,13 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
}
}
@Override
public void internalAddWithCheck(Object bean) {
if (list == null || !list.contains(bean)) {
internalAdd(bean);
}
}
public boolean checkEmptyLazyLoad() {
if (list == null) {
list = new ArrayList<E>();
@@ -99,11 +116,11 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
private void initAsUntouched() {
init(false);
}
private void init() {
init(true);
}
private void init(boolean setTouched) {
synchronized (this) {
if (list == null) {
@@ -134,7 +151,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
public Collection<E> getActualDetails() {
return list;
}
@Override
public Collection<?> getActualEntries() {
return list;
@@ -206,6 +223,11 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
list.add(index, element);
}
@Override
public void addBean(E bean) {
add(bean);
}
public boolean add(E o) {
checkReadOnly();
init();
@@ -319,6 +341,13 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
return list.listIterator(index);
}
@Override
public void removeBean(E bean) {
if (list.remove(bean)) {
getModifyHolder().modifyRemoval(bean);
}
}
public E remove(int index) {
checkReadOnly();
init();
@@ -343,41 +372,41 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
return list.remove(o);
}
public boolean removeAll(Collection<?> c) {
public boolean removeAll(Collection<?> beans) {
checkReadOnly();
init();
if (modifyRemoveListening) {
boolean changed = false;
Iterator<?> it = c.iterator();
while (it.hasNext()) {
Object o = it.next();
if (list.remove(o)) {
modifyRemoval(o);
for (Object bean : beans) {
if (list.remove(bean)) {
// register this bean as having been removed
modifyRemoval(bean);
changed = true;
}
}
return changed;
}
return list.removeAll(c);
return list.removeAll(beans);
}
public boolean retainAll(Collection<?> c) {
public boolean retainAll(Collection<?> retainBeans) {
checkReadOnly();
init();
if (modifyRemoveListening) {
boolean changed = false;
Iterator<E> it = list.iterator();
while (it.hasNext()) {
Object o = it.next();
if (!c.contains(o)) {
Object bean = it.next();
if (!retainBeans.contains(bean)) {
// removing this bean
it.remove();
modifyRemoval(o);
modifyRemoval(bean);
changed = true;
}
}
return changed;
}
return list.retainAll(c);
return list.retainAll(retainBeans);
}
public E set(int index, E element) {
@@ -415,6 +444,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
public <T> T[] toArray(T[] a) {
init();
//noinspection SuspiciousToArrayCall
return list.toArray(a);
}
@@ -1,15 +1,15 @@
package com.avaje.ebean.common;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollectionLoader;
import com.avaje.ebean.bean.EntityBean;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import com.avaje.ebean.bean.BeanCollectionLoader;
import com.avaje.ebean.bean.EntityBean;
/**
* Map capable of lazy loading.
*/
@@ -52,6 +52,14 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
return !touched && (map == null || map.isEmpty());
}
@Override
@SuppressWarnings("unchecked")
public void loadFrom(BeanCollection<?> other) {
BeanMap<K,E> otherMap = (BeanMap<K,E>)other;
internalPutNull();
map.putAll(otherMap.getActualMap());
}
public void internalPutNull() {
if (map == null) {
map = new LinkedHashMap<K, E>();
@@ -67,7 +75,18 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
map.put((K) key, (E) bean);
}
}
public void internalPutWithCheck(Object key, Object bean) {
if (map == null || !map.containsKey(key)) {
internalPut(key, bean);
}
}
@Override
public void internalAddWithCheck(Object bean) {
throw new RuntimeException("Not allowed for map");
}
public void internalAdd(Object bean) {
throw new RuntimeException("Not allowed for map");
}
@@ -148,8 +167,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
public Collection<E> getActualDetails() {
return map.values();
}
/**
* Returns the map entrySet.
* <p>
@@ -159,7 +177,6 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
*/
public Collection<?> getActualEntries() {
return map.entrySet();
}
public String toString() {
@@ -195,9 +212,9 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
checkReadOnly();
initClear();
if (modifyRemoveListening) {
for (K key : map.keySet()) {
E o = map.remove(key);
modifyRemoval(o);
// add all beans to the removal list
for (E bean : map.values()) {
modifyRemoval(bean);
}
}
map.clear();
@@ -249,27 +266,40 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
checkReadOnly();
init();
if (modifyListening) {
Object o = map.put(key, value);
modifyAddition(value);
modifyRemoval(o);
Object oldBean = map.put(key, value);
if (value != oldBean) {
// register the add of the new and the removal of the old
modifyAddition(value);
modifyRemoval(oldBean);
}
}
return map.put(key, value);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void putAll(Map<? extends K, ? extends E> t) {
public void putAll(Map<? extends K, ? extends E> puts) {
checkReadOnly();
init();
if (modifyListening) {
Iterator it = t.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
Object o = map.put((K) entry.getKey(), (E) entry.getValue());
modifyAddition((E) entry.getValue());
modifyRemoval(o);
for (Entry<? extends K, ? extends E> entry : puts.entrySet()) {
Object oldBean = map.put(entry.getKey(), entry.getValue());
if (entry.getValue() != oldBean) {
modifyAddition(entry.getValue());
modifyRemoval(oldBean);
}
}
}
map.putAll(t);
map.putAll(puts);
}
@Override
public void addBean(E bean) {
throw new IllegalStateException("Method not allowed on Map. Please use List instead.");
}
@Override
public void removeBean(E bean) {
throw new IllegalStateException("Method not allowed on Map. Please use List instead.");
}
public E remove(Object key) {
@@ -1,15 +1,16 @@
package com.avaje.ebean.common;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollectionAdd;
import com.avaje.ebean.bean.BeanCollectionLoader;
import com.avaje.ebean.bean.EntityBean;
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import com.avaje.ebean.bean.BeanCollectionAdd;
import com.avaje.ebean.bean.BeanCollectionLoader;
import com.avaje.ebean.bean.EntityBean;
/**
* Set capable of lazy loading.
*/
@@ -53,10 +54,26 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
}
@SuppressWarnings("unchecked")
public void addBean(EntityBean bean) {
public void addEntityBean(EntityBean bean) {
set.add((E) bean);
}
@Override
@SuppressWarnings("unchecked")
public void loadFrom(BeanCollection<?> other) {
if (set == null) {
set = new LinkedHashSet<E>();
}
set.addAll((Collection<? extends E>) other.getActualDetails());
}
@Override
public void internalAddWithCheck(Object bean) {
if (set == null || !set.contains(bean)) {
internalAdd(bean);
}
}
@SuppressWarnings("unchecked")
public void internalAdd(Object bean) {
if (set == null) {
@@ -107,11 +124,11 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
private void initAsUntouched() {
init(false);
}
private void init() {
init(true);
}
private void init(boolean setTouched) {
synchronized (this) {
if (set == null) {
@@ -174,6 +191,18 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
return set.hashCode();
}
@Override
public void addBean(E bean) {
add(bean);
}
@Override
public void removeBean(E bean) {
if (set.remove(bean)) {
getModifyHolder().modifyRemoval(bean);
}
}
// -----------------------------------------------------//
// proxy method for map
// -----------------------------------------------------//
@@ -192,32 +221,29 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
return set.add(o);
}
public boolean addAll(Collection<? extends E> c) {
public boolean addAll(Collection<? extends E> addCollection) {
checkReadOnly();
init();
if (modifyAddListening) {
boolean changed = false;
Iterator<? extends E> it = c.iterator();
while (it.hasNext()) {
E o = it.next();
if (set.add(o)) {
modifyAddition(o);
for (E bean : addCollection) {
if (set.add(bean)) {
// register the addition of the bean
modifyAddition(bean);
changed = true;
}
}
return changed;
}
return set.addAll(c);
return set.addAll(addCollection);
}
public void clear() {
checkReadOnly();
initClear();
if (modifyRemoveListening) {
Iterator<E> it = set.iterator();
while (it.hasNext()) {
E e = it.next();
modifyRemoval(e);
for (E bean : set) {
modifyRemoval(bean);
}
}
set.clear();
@@ -262,41 +288,40 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
return set.remove(o);
}
public boolean removeAll(Collection<?> c) {
public boolean removeAll(Collection<?> beans) {
checkReadOnly();
init();
if (modifyRemoveListening) {
boolean changed = false;
Iterator<?> it = c.iterator();
while (it.hasNext()) {
Object o = it.next();
if (set.remove(o)) {
modifyRemoval(o);
for (Object bean : beans) {
if (set.remove(bean)) {
modifyRemoval(bean);
changed = true;
}
}
return changed;
}
return set.removeAll(c);
return set.removeAll(beans);
}
public boolean retainAll(Collection<?> c) {
public boolean retainAll(Collection<?> beans) {
checkReadOnly();
init();
if (modifyRemoveListening) {
boolean changed = false;
Iterator<?> it = set.iterator();
while (it.hasNext()) {
Object o = it.next();
if (!c.contains(o)) {
Object bean = it.next();
if (!beans.contains(bean)) {
// not retaining this bean so add it to the removal list
it.remove();
modifyRemoval(o);
modifyRemoval(bean);
changed = true;
}
}
return changed;
}
return set.retainAll(c);
return set.retainAll(beans);
}
public int size() {
@@ -311,6 +336,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
public <T> T[] toArray(T[] a) {
init();
//noinspection SuspiciousToArrayCall
return set.toArray(a);
}
@@ -40,9 +40,7 @@ class ModifyCollection<E> implements Collection<E> {
public boolean addAll(Collection<? extends E> collection) {
boolean changed = false;
Iterator<? extends E> it = collection.iterator();
while (it.hasNext()) {
E o = it.next();
for (E o : collection) {
if (c.add(o)) {
owner.modifyAddition(o);
changed = true;
@@ -51,27 +49,33 @@ class ModifyCollection<E> implements Collection<E> {
return changed;
}
@Override
public void clear() {
c.clear();
}
@Override
public boolean contains(Object o) {
return c.contains(o);
}
@Override
public boolean containsAll(Collection<?> collection) {
return c.containsAll(collection);
}
@Override
public boolean isEmpty() {
return c.isEmpty();
}
@Override
public Iterator<E> iterator() {
Iterator<E> it = c.iterator();
return new ModifyIterator<E>(owner, it);
}
@Override
public boolean remove(Object o) {
if (c.remove(o)) {
owner.modifyRemoval(o);
@@ -80,42 +84,47 @@ class ModifyCollection<E> implements Collection<E> {
return false;
}
@Override
public boolean removeAll(Collection<?> collection) {
boolean changed = false;
Iterator<?> it = collection.iterator();
while (it.hasNext()) {
Object o = (Object) it.next();
if (c.remove(o)) {
owner.modifyRemoval(o);
for (Object bean : collection) {
if (c.remove(bean)) {
owner.modifyRemoval(bean);
changed = true;
}
}
return changed;
}
@Override
public boolean retainAll(Collection<?> collection) {
boolean changed = false;
Iterator<?> it = c.iterator();
while (it.hasNext()) {
Object o = (Object) it.next();
if (!collection.contains(o)) {
Object bean = it.next();
if (!collection.contains(bean)) {
// not retaining this bean so add to removals
it.remove();
owner.modifyRemoval(o);
owner.modifyRemoval(bean);
changed = true;
}
}
return changed;
}
@Override
public int size() {
return c.size();
}
@Override
public Object[] toArray() {
return c.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
//noinspection SuspiciousToArrayCall
return c.toArray(a);
}
@@ -58,7 +58,7 @@ class ModifyHolder<E> implements Serializable {
void modifyRemoval(Object bean) {
if (bean != null) {
// If it is to be added then just remove the addition
if (!modifyAdditions.remove((E) bean)) {
if (!modifyAdditions.remove(bean)) {
modifyDeletions.add((E) bean);
}
}
@@ -1,7 +1,6 @@
package com.avaje.ebean.common;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
@@ -39,12 +38,10 @@ class ModifyList<E> extends ModifyCollection<E> implements List<E> {
owner.modifyAddition(element);
}
public boolean addAll(int index, Collection<? extends E> co) {
if (list.addAll(index, co)) {
Iterator<? extends E> it = co.iterator();
while (it.hasNext()) {
E o = it.next();
owner.modifyAddition(o);
public boolean addAll(int index, Collection<? extends E> addCollection) {
if (list.addAll(index, addCollection)) {
for (E bean : addCollection) {
owner.modifyAddition(bean);
}
return true;
}
@@ -67,9 +67,7 @@ class ModifyListIterator<E> implements ListIterator<E> {
}
public void set(E o) {
if (last == null) {
// in theory this is not allowed
} else {
if (last != null) {
owner.modifyRemoval(last);
owner.modifyAddition(o);
}
@@ -1,12 +1,10 @@
package com.avaje.ebean.config;
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
import javax.persistence.Inheritance;
import javax.persistence.Table;
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Provides some base implementation for NamingConventions.
*
@@ -14,31 +12,39 @@ import org.slf4j.LoggerFactory;
*/
public abstract class AbstractNamingConvention implements NamingConvention {
/** The Constant logger. */
private static final Logger logger = LoggerFactory.getLogger(AbstractNamingConvention.class);
/** The Constant DEFAULT_SEQ_FORMAT. */
/**
* The Constant DEFAULT_SEQ_FORMAT.
*/
public static final String DEFAULT_SEQ_FORMAT = "{table}_seq";
/** Sequence Format that includes the Primary Key column */
/**
* Sequence Format that includes the Primary Key column
*/
public static final String TABLE_PKCOLUMN_SEQ_FORMAT = "{table}_{column}_seq";
/** The catalog. */
/**
* The catalog.
*/
private String catalog;
/** The schema. */
/**
* The schema.
*/
private String schema;
/** The sequence format. */
/**
* The sequence format.
*/
private String sequenceFormat;
/** The database platform. */
/**
* The database platform.
*/
protected DatabasePlatform databasePlatform;
/** The max length of constraint names. */
protected int maxConstraintNameLength;
/** Used to trim off extra prefix for M2M. */
/**
* Used to trim off extra prefix for M2M.
*/
protected int rhsPrefixLength = 3;
protected boolean useForeignKeyPrefix;
@@ -62,8 +68,7 @@ public abstract class AbstractNamingConvention implements NamingConvention {
}
/**
* Construct with the default sequence format ("{table}_seq") and
* useForeignKeyPrefix as true.
* Construct with the default sequence format ("{table}_seq") and useForeignKeyPrefix as true.
*/
public AbstractNamingConvention() {
this(DEFAULT_SEQ_FORMAT);
@@ -71,9 +76,6 @@ public abstract class AbstractNamingConvention implements NamingConvention {
public void setDatabasePlatform(DatabasePlatform databasePlatform) {
this.databasePlatform = databasePlatform;
this.maxConstraintNameLength = databasePlatform.getDbDdlSyntax().getMaxConstraintNameLength();
logger.trace("Using maxConstraintNameLength of " + maxConstraintNameLength);
}
public String getSequenceName(String tableName, String pkColumn) {
@@ -218,11 +220,11 @@ public abstract class AbstractNamingConvention implements NamingConvention {
}
buffer.append(rhsTableName);
int maxConstraintNameLength = databasePlatform.getDbDdlSyntax().getMaxConstraintNameLength();
int maxTableNameLength = databasePlatform.getMaxTableNameLength();
// maxConstraintNameLength is used as the max table name length.
if (buffer.length() > maxConstraintNameLength) {
buffer.setLength(maxConstraintNameLength);
if (buffer.length() > maxTableNameLength) {
buffer.setLength(maxTableNameLength);
}
return new TableName(lhsTable.getCatalog(), lhsTable.getSchema(), buffer.toString());
@@ -239,7 +241,7 @@ public abstract class AbstractNamingConvention implements NamingConvention {
if (t != null && !isEmpty(t.name())) {
// Note: empty catalog and schema are converted to null
// Only need to convert quoted identifiers from annotations
return new TableName(quoteIdentifiers(t.catalog()), quoteIdentifiers(t.schema()), quoteIdentifiers(t.name()));
return new TableName(quoteIdentifiers(t.catalog()), quoteIdentifiers(t.schema()), quoteIdentifiers(t.name()));
}
// No annotation
@@ -272,10 +274,7 @@ public abstract class AbstractNamingConvention implements NamingConvention {
* Checks string is null or empty .
*/
protected boolean isEmpty(String s) {
if (s == null || s.trim().length() == 0) {
return true;
}
return false;
return s == null || s.trim().length() == 0;
}
/**
@@ -0,0 +1,254 @@
package com.avaje.ebean.config;
/**
* Defines the AutoTune behaviour for a EbeanServer.
*/
public class AutoTuneConfig {
private AutoTuneMode mode = AutoTuneMode.DEFAULT_ON;
private String queryTuningFile = "ebean-autotune.xml";
private boolean queryTuning;
private boolean queryTuningAddVersion;
private boolean profiling;
private String profilingFile = "ebean-profiling";
private int profilingBase = 5;
private double profilingRate = 0.01;
private int profilingUpdateFrequency;
private int garbageCollectionWait = 100;
private boolean skipGarbageCollectionOnShutdown;
private boolean skipProfileReportingOnShutdown;
public AutoTuneConfig() {
}
/**
* Return the name of the file that holds the query tuning information.
*/
public String getQueryTuningFile() {
return queryTuningFile;
}
/**
* Set the name of the file that holds the query tuning information.
*/
public void setQueryTuningFile(String queryTuningFile) {
this.queryTuningFile = queryTuningFile;
}
/**
* Return the name of the file that profiling information is written to.
*/
public String getProfilingFile() {
return profilingFile;
}
/**
* Set the name of the file that profiling information is written to.
*/
public void setProfilingFile(String profilingFile) {
this.profilingFile = profilingFile;
}
/**
* Return the frequency in seconds the profiling should be collected and automatically applied to the tuning.
*/
public int getProfilingUpdateFrequency() {
return profilingUpdateFrequency;
}
/**
* Set the frequency in seconds the profiling should be collected and automatically applied to the tuning.
*/
public void setProfilingUpdateFrequency(int profilingUpdateFrequency) {
this.profilingUpdateFrequency = profilingUpdateFrequency;
}
/**
* Return the mode used when autoTune has not been explicit defined on a
* query.
*/
public AutoTuneMode getMode() {
return mode;
}
/**
* Set the mode used when autoTune has not been explicit defined on a query.
*/
public void setMode(AutoTuneMode mode) {
this.mode = mode;
}
/**
* Return true if the queries are being tuned.
*/
public boolean isQueryTuning() {
return queryTuning;
}
/**
* Set to true if the queries should be tuned by autoTune.
*/
public void setQueryTuning(boolean queryTuning) {
this.queryTuning = queryTuning;
}
/**
* Return true if the version property should be added when the query is
* tuned.
* <p>
* If this is false then the version property will be added when profiling
* detects that the bean is possibly going to be modified.
* </p>
*/
public boolean isQueryTuningAddVersion() {
return queryTuningAddVersion;
}
/**
* Set to true to force the version property to be always added by the query
* tuning.
* <p>
* If this is false then the version property will be added when profiling
* detects that the bean is possibly going to be modified.
* </p>
* <p>
* Generally this is not expected to be turned on.
* </p>
*/
public void setQueryTuningAddVersion(boolean queryTuningAddVersion) {
this.queryTuningAddVersion = queryTuningAddVersion;
}
/**
* Return true if profiling information should be collected.
*/
public boolean isProfiling() {
return profiling;
}
/**
* Set to true if profiling information should be collected.
* <p>
* The profiling information is collected and then used to generate the tuned
* queries for autoTune.
* </p>
*/
public void setProfiling(boolean profiling) {
this.profiling = profiling;
}
/**
* Return the base number of queries to profile before changing to profile
* only a percentage of following queries (profileRate).
*/
public int getProfilingBase() {
return profilingBase;
}
/**
* Set the based number of queries to profile.
*/
public void setProfilingBase(int profilingBase) {
this.profilingBase = profilingBase;
}
/**
* Return the rate (%) of queries to be profiled after the 'base' amount of
* profiling.
*/
public double getProfilingRate() {
return profilingRate;
}
/**
* Set the rate (%) of queries to be profiled after the 'base' amount of
* profiling.
*/
public void setProfilingRate(double profilingRate) {
this.profilingRate = profilingRate;
}
/**
* Return the time in millis to wait after a system gc to collect profiling
* information.
* <p>
* The profiling information is collected on object finalise. As such we
* generally don't want to trigger GC (let the JVM do its thing) but on
* shutdown the autoTune manager will trigger System.gc() and then wait
* (default 100 millis) to hopefully collect profiling information -
* especially for short run unit tests.
* </p>
*/
public int getGarbageCollectionWait() {
return garbageCollectionWait;
}
/**
* Set the time in millis to wait after a System.gc() to collect profiling information.
*/
public void setGarbageCollectionWait(int garbageCollectionWait) {
this.garbageCollectionWait = garbageCollectionWait;
}
/**
* Return true if triggering garbage collection should be skipped on shutdown.
* You might set this when System.GC() slows a application shutdown too much.
*/
public boolean isSkipGarbageCollectionOnShutdown() {
return skipGarbageCollectionOnShutdown;
}
/**
* Set to true if triggering garbage collection should be skipped on shutdown.
* You might set this when System.GC() slows a application shutdown too much.
*/
public void setSkipGarbageCollectionOnShutdown(boolean skipGarbageCollectionOnShutdown) {
this.skipGarbageCollectionOnShutdown = skipGarbageCollectionOnShutdown;
}
/**
* Return true if profile reporting should be skipped on shutdown.
*/
public boolean isSkipProfileReportingOnShutdown() {
return skipProfileReportingOnShutdown;
}
/**
* Set to true if profile reporting should be skipped on shutdown.
*/
public void setSkipProfileReportingOnShutdown(boolean skipProfileReportingOnShutdown) {
this.skipProfileReportingOnShutdown = skipProfileReportingOnShutdown;
}
/**
* Load the settings from the properties file.
*/
public void loadSettings(PropertiesWrapper p) {
queryTuning = p.getBoolean("autoTune.queryTuning", queryTuning);
queryTuningAddVersion = p.getBoolean("autoTune.queryTuningAddVersion", queryTuningAddVersion);
queryTuningFile = p.get("autoTune.queryTuningFile", queryTuningFile);
skipGarbageCollectionOnShutdown = p.getBoolean("autoTune.skipGarbageCollectionOnShutdown", skipGarbageCollectionOnShutdown);
skipProfileReportingOnShutdown = p.getBoolean("autoTune.skipProfileReportingOnShutdown", skipProfileReportingOnShutdown);
mode = p.getEnum(AutoTuneMode.class, "autoTune.mode", mode);
profiling = p.getBoolean("autoTune.profiling", profiling);
profilingBase = p.getInt("autoTune.profilingBase", profilingBase);
profilingRate = p.getDouble("autoTune.profilingRate", profilingRate);
profilingFile = p.get("autoTune.profilingFile", profilingFile);
profilingUpdateFrequency = p.getInt("autoTune.profilingUpdateFrequency", profilingUpdateFrequency);
}
}
@@ -0,0 +1,32 @@
package com.avaje.ebean.config;
import com.avaje.ebean.Query;
/**
* The mode for determining if AutoTune will be used for a given query when
* {@link Query#setAutoTune(boolean)} has not been explicitly set on a query.
* <p>
* The explicit control of {@link Query#setAutoTune(boolean)} will always take
* precedence. This mode is used when this has not been explicitly set on a
* query.
* </p>
*/
public enum AutoTuneMode {
/**
* Don't implicitly use AutoTune. Must explicitly turn it on.
*/
DEFAULT_OFF,
/**
* Use AutoTune implicitly. Must explicitly turn it off.
*/
DEFAULT_ON,
/**
* Implicitly use AutoTune if the query has not got either select() or join()
* defined.
*/
DEFAULT_ONIFEMPTY
}
@@ -1,245 +0,0 @@
package com.avaje.ebean.config;
/**
* Defines the Autofetch behaviour for a EbeanServer.
*/
public class AutofetchConfig {
private AutofetchMode mode = AutofetchMode.DEFAULT_ONIFEMPTY;
private boolean queryTuning = false;
private boolean queryTuningAddVersion = false;
private boolean profiling = false;
private int profilingMin = 1;
private int profilingBase = 10;
private double profilingRate = 0.05;
private String logDirectory;
private int profileUpdateFrequency = 60;
private int garbageCollectionWait = 100;
private boolean garbageCollectionOnShutdown;
public AutofetchConfig() {
}
/**
* Return the mode used when autofetch has not been explicit defined on a
* query.
*/
public AutofetchMode getMode() {
return mode;
}
/**
* Set the mode used when autofetch has not been explicit defined on a query.
*/
public void setMode(AutofetchMode mode) {
this.mode = mode;
}
/**
* Return true if the queries are being tuned.
*/
public boolean isQueryTuning() {
return queryTuning;
}
/**
* Set to true if the queries should be tuned by autofetch.
*/
public void setQueryTuning(boolean queryTuning) {
this.queryTuning = queryTuning;
}
/**
* Return true if the version property should be added when the query is
* tuned.
* <p>
* If this is false then the version property will be added when profiling
* detects that the bean is possibly going to be modified.
* </p>
*/
public boolean isQueryTuningAddVersion() {
return queryTuningAddVersion;
}
/**
* Set to true to force the version property to be always added by the query
* tuning.
* <p>
* If this is false then the version property will be added when profiling
* detects that the bean is possibly going to be modified.
* </p>
*/
public void setQueryTuningAddVersion(boolean queryTuningAddVersion) {
this.queryTuningAddVersion = queryTuningAddVersion;
}
/**
* Return true if profiling information should be collected.
*/
public boolean isProfiling() {
return profiling;
}
/**
* Set to true if profiling information should be collected.
* <p>
* The profiling information is collected and then used to generate the tuned
* queries for autofetch.
* </p>
*/
public void setProfiling(boolean profiling) {
this.profiling = profiling;
}
/**
* Return the minimum number of queries to profile before autofetch will start
* tuning the queries.
*/
public int getProfilingMin() {
return profilingMin;
}
/**
* Set the minimum number of queries to profile before autofetch will start
* tuning the queries.
*/
public void setProfilingMin(int profilingMin) {
this.profilingMin = profilingMin;
}
/**
* Return the base number of queries to profile before changing to profile
* only a percentage of following queries (profileRate).
*/
public int getProfilingBase() {
return profilingBase;
}
/**
* Set the based number of queries to profile.
*/
public void setProfilingBase(int profilingBase) {
this.profilingBase = profilingBase;
}
/**
* Return the rate (%) of queries to be profiled after the 'base' amount of
* profiling.
*/
public double getProfilingRate() {
return profilingRate;
}
/**
* Set the rate (%) of queries to be profiled after the 'base' amount of
* profiling.
*/
public void setProfilingRate(double profilingRate) {
this.profilingRate = profilingRate;
}
/**
* Return the log directory to put the autofetch log.
*/
public String getLogDirectory() {
return logDirectory;
}
/**
* Set the directory to put the autofetch log in.
*/
public void setLogDirectory(String logDirectory) {
this.logDirectory = logDirectory;
}
/**
* Return the frequency in seconds to update the autofetch tuned queries from
* the profiled information.
*/
public int getProfileUpdateFrequency() {
return profileUpdateFrequency;
}
/**
* Set the frequency in seconds to update the autofetch tuned queries from the
* profiled information.
*/
public void setProfileUpdateFrequency(int profileUpdateFrequency) {
this.profileUpdateFrequency = profileUpdateFrequency;
}
/**
* Return the time in millis to wait after a system gc to collect profiling
* information.
* <p>
* The profiling information is collected on object finalise. As such we
* generally don't want to trigger GC (let the JVM do its thing) but on
* shutdown the autofetch manager will trigger System.gc() and then wait
* (default 100 millis) to hopefully collect profiling information -
* especially for short run unit tests.
* </p>
*/
public int getGarbageCollectionWait() {
return garbageCollectionWait;
}
/**
* Set the time in millis to wait after a System.gc() to collect profiling
* information.
*/
public void setGarbageCollectionWait(int garbageCollectionWait) {
this.garbageCollectionWait = garbageCollectionWait;
}
/**
* Return true if GC should be trigger on shutdown.
* <p>
* Autofetch profiling information is collected as part of garbage collection.
* </p>
*/
public boolean isGarbageCollectionOnShutdown() {
return garbageCollectionOnShutdown;
}
/**
* Set to true if you want GC to trigger on shutdown.
* <p>
* This would be done if you want to try and collect Autofetch profiling information
* on shutdown.
* </p>
*/
public void setGarbageCollectionOnShutdown(boolean garbageCollectionOnShutdown) {
this.garbageCollectionOnShutdown = garbageCollectionOnShutdown;
}
/**
* Load the settings from the properties file.
*/
public void loadSettings(PropertiesWrapper p) {
logDirectory = p.get("autofetch.logDirectory", logDirectory);
queryTuning = p.getBoolean("autofetch.querytuning", queryTuning);
queryTuningAddVersion = p.getBoolean("autofetch.queryTuningAddVersion", queryTuningAddVersion);
garbageCollectionOnShutdown = p.getBoolean("autofetch.garbageCollectionOnShutdown", garbageCollectionOnShutdown);
profiling = p.getBoolean("autofetch.profiling", profiling);
mode = p.getEnum(AutofetchMode.class, "autofetch.implicitmode", mode);
profilingMin = p.getInt("autofetch.profiling.min", profilingMin);
profilingBase = p.getInt("autofetch.profiling.base", profilingBase);
profilingRate = p.getDouble("autofetch.profiling.rate", profilingRate);
profileUpdateFrequency = p.getInt("autofetch.profiling.updatefrequency", profileUpdateFrequency);
}
}
@@ -1,32 +0,0 @@
package com.avaje.ebean.config;
import com.avaje.ebean.Query;
/**
* The mode for determining if Autofetch will be used for a given query when
* {@link Query#setAutofetch(boolean)} has not been explicitly set on a query.
* <p>
* The explicit control of {@link Query#setAutofetch(boolean)} will always take
* precedence. This mode is used when this has not been explicitly set on a
* query.
* </p>
*/
public enum AutofetchMode {
/**
* Don't implicitly use Autofetch. Must explicitly turn it on.
*/
DEFAULT_OFF,
/**
* Use Autofetch implicitly. Must explicitly turn it off.
*/
DEFAULT_ON,
/**
* Implicitly use Autofetch if the query has not got either select() or join()
* defined.
*/
DEFAULT_ONIFEMPTY
}
@@ -0,0 +1,153 @@
package com.avaje.ebean.config;
/**
* Helper to find classes taking into account the context class loader.
*/
public class ClassLoadConfig {
protected final ClassLoaderContext context;
/**
* Construct with the default classLoader search with context classLoader first.
*/
public ClassLoadConfig() {
this(null);
}
/**
* Specify the classLoader to use for class detection and new instance creation.
*/
public ClassLoadConfig(ClassLoader classLoader) {
this.context = new ClassLoaderContext(classLoader);
}
/**
* Return true if the Java.time types are available and should be supported.
*/
public boolean isJavaTimePresent() {
return isPresent("java.time.LocalDate");
}
/**
* Return true if the Joda types are available and should be supported.
*/
public boolean isJodaTimePresent() {
return isPresent("org.joda.time.LocalDateTime");
}
/**
* Return true if javax validation annotations like Size and NotNull are present.
*/
public boolean isJavaxValidationAnnotationsPresent() {
return isPresent("javax.validation.constraints.NotNull");
}
/**
* Return true if Jackson annotations like JsonIgnore are present.
*/
public boolean isJacksonAnnotationsPresent() {
return isPresent("com.fasterxml.jackson.annotation.JsonIgnore");
}
/**
* Return true if Jackson ObjectMapper is present.
*/
public boolean isJacksonObjectMapperPresent() {
return isPresent("com.fasterxml.jackson.databind.ObjectMapper");
}
/**
* Return a new instance of the class using the default constructor.
*/
public Object newInstance(String className) {
try {
Class<?> cls = forName(className);
return cls.newInstance();
} catch (Exception e) {
throw new IllegalArgumentException("Error constructing " + className, e);
}
}
/**
* Return true if the given class is present.
*/
protected boolean isPresent(String className) {
try {
forName(className);
return true;
} catch (Throwable ex) {
// Class or one of its dependencies is not present...
return false;
}
}
/**
* Load a class taking into account a context class loader (if present).
*/
protected Class<?> forName(String name) throws ClassNotFoundException {
return context.forName(name);
}
/**
* Return the classLoader to use for service loading etc.
*/
public ClassLoader getClassLoader() {
return context.getClassLoader();
}
/**
* Wraps the preferred, caller and context class loaders.
*/
protected class ClassLoaderContext {
/**
* Optional - if set only use this classLoader (no fallback).
*/
protected final ClassLoader preferredLoader;
protected final ClassLoader contextLoader;
protected final ClassLoader callerLoader;
ClassLoaderContext(ClassLoader preferredLoader) {
this.preferredLoader = preferredLoader;
this.callerLoader = ServerConfig.class.getClassLoader();
this.contextLoader = contextLoader();
}
ClassLoader contextLoader() {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
return (loader != null) ? loader: callerLoader;
}
Class<?> forName(String name) throws ClassNotFoundException {
if (preferredLoader != null) {
// only use the explicitly set classLoader
return classForName(name, preferredLoader);
}
try {
// try the context loader first
return classForName(name, contextLoader);
} catch (ClassNotFoundException e) {
if (callerLoader == contextLoader) {
throw e;
} else {
// fallback to the caller classLoader
return classForName(name, callerLoader);
}
}
}
Class<?> classForName(String name, ClassLoader classLoader) throws ClassNotFoundException {
return Class.forName(name, true, classLoader);
}
ClassLoader getClassLoader() {
return preferredLoader != null ? preferredLoader : contextLoader;
}
}
}
@@ -0,0 +1,16 @@
package com.avaje.ebean.config;
/**
* Provides the current user in order to support 'Who created', 'Who modified' and other audit features.
*/
public interface CurrentUserProvider {
/**
* Return the current user id.
* <p>
* The type returned should match the type of the properties annotated
* with @WhoCreated and @WhoModified. These are typically String, Long or UUID.
* </p>
*/
Object currentUser();
}
@@ -507,8 +507,7 @@ public class DataSourceConfig {
String customProperties = properties.get("customProperties", null);
if (customProperties != null && customProperties.length() > 0) {
Map<String, String> custProps = StringHelper.delimitedToMap(customProperties, ";", "=");
this.customProperties = custProps;
this.customProperties = StringHelper.delimitedToMap(customProperties, ";", "=");
}
}

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