Compare commits

..
Author SHA1 Message Date
Rob Bygrave f815415eb0 [maven-release-plugin] prepare release ebean-9.1.2 2016-11-16 00:24:44 +13:00
Rob Bygrave cf81d1699b Modify scm in pom 2016-11-16 00:23:54 +13:00
Rob Bygrave de9576835c #872 - test models for DDL check constraint issue (not reproduced) 2016-11-15 23:27:08 +13:00
Rob Bygrave 632cf10096 #878 - @AttributeOverride (not wrapped in @AttributeOverrides) is not applied 2016-11-15 22:48:36 +13:00
Rob Bygrave d2b6d06da5 Merge branch 'master' of github.com:ebean-orm/ebean 2016-11-15 22:13:09 +13:00
Rob Bygrave b41f3e9d1f #877 - DBMigration Generates wrong ddl for UUID type 2016-11-15 22:12:54 +13:00
Rob BygraveandGitHub 8357d9c7e7 Merge pull request #876 from ksperling/batching-exception-safety
Batching exception safety: Fix test
2016-11-14 15:28:36 +13:00
Karsten Sperling 97f1834c4d Batching exception safety: Update test to reflect real world scenario more closely (and actually fail before the change) 2016-11-14 12:48:58 +13:00
Rob Bygrave 01f551a951 #875 - Changes to support ElasticSearch 5.x 2016-11-12 01:05:13 +13:00
Rob Bygrave 482d454fc3 #875 - Changes to support ElasticSearch 5.x 2016-11-11 23:43:13 +13:00
Rob Bygrave 2953418683 No effective change - add .editorconfig 2016-11-11 17:14:12 +13:00
Rob Bygrave 5c142a61f6 No effective change - add javadoc 2016-11-11 17:11:15 +13:00
Rob BygraveandGitHub 74626184b2 Merge pull request #873 from ksperling/batching-exception-safety
Batching exception safety
2016-11-11 17:06:29 +13:00
Karsten Sperling 8661e1fd3f Reset batch on rollback 2016-11-09 10:58:57 +13:00
Karsten Sperling 9569b1b0d5 Added test for exception safety when using batchOnCascade 2016-11-09 10:58:57 +13:00
Rob BygraveandGitHub 3eb9bc1d16 Merge pull request #870 from 0xbaadf00d/feature/use-foreach
Replace "for" with "foreach"
2016-11-08 23:42:12 +13:00
Thibault Meyer ec6a8f5ea2 Replace "for" with "foreach" 2016-11-08 09:06:13 +01:00
Rob Bygrave d6ba567763 [maven-release-plugin] prepare for next development iteration 2016-11-08 00:32:47 +13:00
Rob Bygrave 6826fe1015 [maven-release-plugin] prepare release ebean-9.1.1 2016-11-08 00:32:38 +13:00
Rob Bygrave e67860cbe3 Merge branch 'master' of https://github.com/ebean-orm/ebean 2016-11-08 00:27:40 +13:00
Rob Bygrave b41238ddbb No effective change - modify TestHistoryInsert for more wait time and logging (PG test failing sometimes in CI) 2016-11-08 00:25:13 +13:00
Rob BygraveandGitHub c0b1c3d3ee Merge pull request #868 from 0xbaadf00d/feature/array-copy-performance
Use "Collection.addAll(...)" rather than manually copying arrays
2016-11-08 00:16:33 +13:00
Rob Bygrave ae69fcb80a #862 - ENH: Change ServerConfig such that if H2 ... no using createOnly = true in case the test EbeanServer instance is created for each test (and hence we need to drop if the same in memory db is used) 2016-11-08 00:10:15 +13:00
Rob Bygrave 6c4c33f1f3 No effective change - reduce logging in test (for CI) 2016-11-08 00:03:15 +13:00
Rob Bygrave 2986290947 Refactor - change use of 31 prime in various hash to 92821 2016-11-07 23:57:51 +13:00
Rob Bygrave 376cb9ebcb #869 - Clash on bind hash value for query cache with consecutive values of "01","20" and "02", "10" 2016-11-07 23:47:29 +13:00
Rob Bygrave 5cf5629232 #869 - Test for ... Clash on bind hash value for query cache with consecutive values of "01","20" and "02", "10" 2016-11-07 23:46:28 +13:00
Thibault Meyer 98aa5e9da9 Use "Collection.addAll(...)" rather than manually copying arrays 2016-11-07 11:07:37 +01:00
Rob BygraveandGitHub ed1df5bcbb Merge pull request #864 from 0xbaadf00d/feature/redundant-local-var
Remove redundant local variables
2016-11-07 22:14:59 +13:00
Thibault Meyer 6704ccc6a7 Merge branch 'master' into feature/redundant-local-var 2016-11-07 10:11:03 +01:00
Thibault Meyer 5f35e3c944 Remove redundant local variables 2016-11-07 10:03:50 +01:00
Rob Bygrave 0893972115 Fix for running CI tests as Postgres (where we need to explicitly turn on DDL generation and running for the tests). 2016-11-07 22:00:33 +13:00
Rob Bygrave 7a8d1b85a9 #866 - Fix RawSql mapping such that it automatically maps foreign key columns 2016-11-07 21:57:03 +13:00
Rob Bygrave 686593e9e8 No effective change - tidy up test Order entity bean 2016-11-07 21:36:19 +13:00
Rob Bygrave d05b593432 #862 - ENH: Change ServerConfig such that if H2 is the DataSource/DatabasePlatform then automatically it sets up for testing (ddl generation) 2016-11-07 19:50:05 +13:00
Rob Bygrave b581c893ec No effective change - tidy up test conversation User entity bean 2016-11-07 19:47:34 +13:00
Rob Bygrave 63f852475d #863 - @Enumerated(EnumType.STRING) DayOfWeek day; ... incorrectly maps to SQL Integer type 2016-11-07 17:15:47 +13:00
Rob BygraveandGitHub 51364763fb Merge pull request #860 from 0xbaadf00d/feature/replace-anonymous-classes
Replace anonymous classes with lambda expressions
2016-11-07 13:02:33 +13:00
Rob BygraveandGitHub ea408fd4c7 Merge pull request #861 from 0xbaadf00d/feature/coding-style
Remove redundant "public" modifier for interface methods
2016-11-07 12:58:23 +13:00
Thibault Meyer 8dc521ca8b Remove redundant "public" modifier for interface methods 2016-11-06 11:48:59 +01:00
Thibault Meyer 6680e2ea75 Replace anonymous classes with lambda expressions 2016-11-06 11:17:53 +01:00
Rob BygraveandGitHub da30df3b2b Merge pull request #858 from 0xbaadf00d/feature/deprecated-api-usage
Deprecated API usage - Modify ScalarTypeJodaLocalTime to use toDateTimeToday().getMillis()
2016-11-06 22:59:32 +13:00
Rob BygraveandGitHub d12ea89388 Merge pull request #854 from 0xbaadf00d/feature/explicit-type-to-diamond
Replace explicit type with <>
2016-11-06 22:54:24 +13:00
Thibault Meyer e0931e41e5 Remove deprecated API usage 2016-11-06 10:50:31 +01:00
Rob BygraveandGitHub c98d258127 Merge pull request #857 from 0xbaadf00d/feature/boxing-unboxing
Remove unnecessary boxing and unboxing
2016-11-06 22:43:33 +13:00
Rob BygraveandGitHub a4922a5b1d Merge pull request #856 from 0xbaadf00d/feature/identical-catch
Change identical 'catch' statements
2016-11-06 22:42:13 +13:00
Rob BygraveandGitHub edb2a69f6e Merge pull request #853 from 0xbaadf00d/fix/javadoc-error
Javadoc error
2016-11-06 22:40:52 +13:00
Thibault Meyer b94f852b67 Remove unnecessary boxing and unboxing 2016-11-06 10:29:42 +01:00
Thibault Meyer a8778ef14c Change identical 'catch' statements 2016-11-06 10:26:13 +01:00
Rob Bygrave cbfce0d14d #855 - Fix @Aggregation lazy loading and base select issue 2016-11-06 22:18:23 +13:00
Thibault Meyer abb25d397a Fix comments 2016-11-06 10:03:33 +01:00
Thibault Meyer 969a3c8b8d Replace explicit type with <> 2016-11-06 10:00:12 +01:00
Rob Bygrave 2a6d38eef2 #852 - javax.persistence.PersistenceException: No ScalarType registered for class Foo$1 ... where Foo is an Enum where individual instances override a method (example below). 2016-11-06 20:33:56 +13:00
Rob Bygrave d84080fb76 Refactor - clean up DefaultTypeManager, diamond operator and access modifiers only 2016-11-06 19:45:46 +13:00
Rob Bygrave 54d7a6fb42 Refactor - clean up docstore api mapping, diamond operator only 2016-11-05 23:04:33 +13:00
Rob Bygrave e5356e7118 Refactor - tidy up in com.avaje.ebeaninternal util, no effective change 2016-11-05 23:01:03 +13:00
Rob Bygrave e83556cada Refactor - clean up OrmQueryDetailParser, remove unused sections 2016-11-05 22:51:51 +13:00
Rob Bygrave 201a2826ab Refactor - tidy up in com.avaje.ebeaninternal.server.querydefn, no effective change 2016-11-05 22:46:43 +13:00
Rob Bygrave 670bac52f8 Refactor - tidy up in com.avaje.ebeaninternal.server.query, no effective change 2016-11-05 22:32:36 +13:00
Rob Bygrave 77e3346d9e Refactor - clean up CQueryPlan, CQueryPlanStats 2016-11-05 15:11:17 +13:00
Rob Bygrave 4663162f95 Refactor - no effective chang - Add SpiQuery getOriginKey() 2016-11-05 14:48:03 +13:00
Rob BygraveandGitHub 83a3ef43bd Merge pull request #851 from FOCONIS/fix/javawarnings
FIX some java warnings / rawtypes
2016-11-05 09:23:07 +13:00
Roland Praml 3701b314a0 FIX some java warnings / rawtypes 2016-11-04 12:19:38 +01:00
Rob Bygrave fad8358a9d Bump to java8-parent, update to Java8 LongAdder 2016-11-04 20:04:25 +13:00
Rob Bygrave 78c4dbb44d [maven-release-plugin] prepare for next development iteration 2016-11-04 19:19:11 +13:00
Rob Bygrave 9c74520a4b [maven-release-plugin] prepare release ebean-8.8.1 2016-11-04 19:19:02 +13:00
Rob Bygrave c911c710d5 Bump pom to 8.8.1-SNAPSHOT 2016-11-04 01:17:08 +13:00
Rob Bygrave f08dd01035 #836 - ENH: Add support for @DbArray even for H2 db 2016-11-04 01:16:32 +13:00
Rob Bygrave a1b4af2716 Refactor - no effective change - remove un-required callback from PersistExecute to PersistRequestBean 2016-11-03 23:42:43 +13:00
Rob Bygrave 8c500c5836 #846 - Add soft delete related callbacks 2016-11-03 23:27:39 +13:00
Rob Bygrave c1d6cc7b75 Refactor - no real change - tighter access on SqlTreeNodeBean 2016-11-03 23:18:14 +13:00
Rob Bygrave d6fe16ffda Change permissions on travis scripts 2016-11-03 23:14:14 +13:00
Rob Bygrave d0230491e5 #99 - ENH (419) : Simplify aggregation queries - part 2 2016-11-03 23:06:54 +13:00
Rob Bygrave 3526f71f0a #99 - ENH (419) : Simplify aggregation queries 2016-11-02 22:10:22 +13:00
Rob Bygrave 18f943ab2b [maven-release-plugin] prepare for next development iteration 2016-10-31 21:59:39 +13:00
Rob Bygrave 03ff53c7af [maven-release-plugin] prepare release ebean-8.7.1 2016-10-31 21:59:30 +13:00
Rob Bygrave c20d111ea2 Bump version to 8.7.1-SNAPSHOT 2016-10-31 21:58:43 +13:00
Rob Bygrave 920fa73d11 #837 - ENH: Support using @HistoryExclude on normal properties (other than @ManyToMany) 2016-10-31 21:57:16 +13:00
Rob Bygrave cd62686337 #845 - Fix EQL parsing to support the 'inverse' form - e.g. where 'Rob' eq firstName (where the path is on the RHS rather than LHS) 2016-10-31 21:32:29 +13:00
Rob Bygrave e9ad459fa5 #843 - Change ServerConfig name to default to "db" (prior default was null) and defaultServer to true 2016-10-31 20:40:26 +13:00
Rob Bygrave ea5e9fa75a #842 - For @DbJson map the type Map<String, ?> (using the wildcard) ... the same as Map<String, Object> 2016-10-31 20:15:23 +13:00
Rob BygraveandGitHub d44460e180 Merge pull request #841 from FOCONIS/bugfix/softdelete-calls-wrong-lifecycle-method
Bugfix/softdelete calls wrong lifecycle method
2016-10-27 10:17:29 +13:00
Roland Praml 0e5ebf3fea FIX: softDeleting an entity calls now preUpdate/postUpdate 2016-10-26 15:47:54 +02:00
Roland Praml 42d35f8ec6 FIX: removed trailing commas in logs 2016-10-26 15:45:10 +02:00
Rob Bygrave 7f52e466e0 [maven-release-plugin] prepare for next development iteration 2016-10-25 22:23:13 +13:00
Rob Bygrave 861a8a4ee5 [maven-release-plugin] prepare release ebean-8.6.1 2016-10-25 22:23:04 +13:00
Rob Bygrave abe2f76d5c Bump pom to 8.6.1-SNAPSHOT 2016-10-25 22:22:16 +13:00
Rob Bygrave d0f75a940c #239 - Support Geometric types of Postgres, Also adding LineString, MultiLineString and MultiPoint 2016-10-25 22:19:33 +13:00
Rob Bygrave 44ad78b5e0 #239 - Support Geometric types of Postgres 2016-10-21 02:45:06 +13:00
Rob Bygrave 967b4de784 #239 - Support Geometric types of Postgres 2016-10-21 02:42:25 +13:00
Rob Bygrave ea45201905 [maven-release-plugin] prepare for next development iteration 2016-10-17 20:58:19 +13:00
Rob Bygrave 938f4ec9c2 [maven-release-plugin] prepare release ebean-8.5.1 2016-10-17 20:58:10 +13:00
Rob Bygrave 99bd2972d0 Bump pom version to 8.5.1-SNAPSHOT 2016-10-17 20:57:26 +13:00
Rob Bygrave deac291951 #835 - A query that includes a fetch() of a many that is @SoftDelete where all the rows are soft deleted returns incorrect results 2016-10-17 20:52:18 +13:00
Rob Bygrave 3161e24677 #835 - Tests for - A query that includes a fetch() of a many that is @SoftDelete where all the rows are soft deleted returns incorrect results 2016-10-17 20:51:22 +13:00
Rob Bygrave 37804bd083 Modify tests to avoid MySql keyword (mod) for column names 2016-10-17 20:50:48 +13:00
Rob Bygrave 0a2a987695 Modify tests to avoid Oracle keywords for column names 2016-10-15 17:03:32 +13:00
Rob Bygrave 4a085cb819 #834 - Oracle DDL for drop index and drop constraints incorrectly includes "if exits" 2016-10-15 17:02:44 +13:00
Rob Bygrave 67469ef4d3 No effective change - change Line endings to CR (from CRLF) 2016-10-15 14:39:20 +13:00
Rob Bygrave c3f43d503f #832 - Refactor: Change generated SQL to use "left join" rather than "left outer join" - change tests 2016-10-15 14:37:36 +13:00
Rob Bygrave 9158f46bb3 #832 - Refactor: Change generated SQL to use "left join" rather than "left outer join" 2016-10-15 14:36:11 +13:00
Rob Bygrave b3bfa88eb5 [maven-release-plugin] prepare for next development iteration 2016-10-15 01:14:29 +13:00
Rob Bygrave 185dec9c02 [maven-release-plugin] prepare release ebean-8.4.2 2016-10-15 01:14:18 +13:00
Rob Bygrave 20634233ca Update tests only - handle MySql specifics (boolean literal, lack of order by nulls last) 2016-10-15 00:55:09 +13:00
Rob Bygrave 7c9dda586e No effective change - format only 2016-10-14 23:49:00 +13:00
Rob BygraveandGitHub 3ca0f7b776 Merge pull request #828 from FOCONIS/feature/postconstruct
Feature/postconstruct
2016-10-14 23:44:45 +13:00
Rob Bygrave 85caca48de No effective change - add tests for naming convention on m2m columns 2016-10-14 23:29:50 +13:00
Rob Bygrave ff85a51994 No effective change - format only 2016-10-14 23:29:27 +13:00
Rob BygraveandGitHub 6dc3038d0d Merge pull request #830 from lvffilho/master
Add NamingConvention support to ManyToMany columns
2016-10-14 23:27:32 +13:00
Rob BygraveandGitHub c0fcb77f3d Merge pull request #829 from kdazzle/patch-1
Remove outdated findPageList(int, int) javadocs
2016-10-14 23:17:42 +13:00
Rob Bygrave da5d5296b6 #831 - EQL query language parser needs to throw exception on invalid query ... "find ..." - remove unhelpful tests 2016-10-14 21:09:23 +13:00
Rob Bygrave f04ab28c3f #831 - EQL query language parser needs to throw exception on invalid query ... "find ..." 2016-10-14 21:08:23 +13:00
Rob Bygrave d6cd41f8d2 #831 - EQL query language parser needs to throw exception on invalid query ... "find ..." - tests 2016-10-14 21:07:31 +13:00
Rob Bygrave 504a209a78 Merge branch 'master' of https://github.com/ebean-orm/ebean 2016-10-14 20:24:13 +13:00
Rob Bygrave 9f98b5333d Update tests - for asserts trim column alias from generated SQL if necessary (to support generating without column alias) 2016-10-14 20:23:36 +13:00
Eddie Mc Greal 2a600adbcf Added tests for EQL - syntactically incorrect und named parameter on LHS of comparison operator 2016-10-12 19:42:31 +02:00
Luiz Filho 9ce6007330 Add NamingConvention support to ManyToMany columns 2016-10-07 16:46:40 -03:00
Kyle ValadeandGitHub 7780dd6272 Remove outdated findPageList(int, int) javadocs
The class no longer supports that type of call
2016-10-07 12:26:06 -04:00
Roland Praml b01ddea781 FIX: fixed non-deterministic failing TestHistoryInsert testcase 2016-10-05 21:51:42 +02:00
Roland Praml b848587cd3 ADD: Testcases for PostConstruct 2016-10-05 21:51:04 +02:00
Roland Praml fe7e929a99 Refactor: Removed duplicate code from BootupClasses - use generics. 2016-10-05 21:50:22 +02:00
Roland Praml 3ee0b0224e ENH: Support for javax.annotation.PostConstruct. BeanPostConstructListener will be informed when an entity-bean is constructed/created to perform dependency-injection (e.g. Spring-Autowire) 2016-10-05 21:48:11 +02:00
Roland Praml 169eba4296 No effective code change - fixed commets 2016-10-05 21:39:44 +02:00
Robin Bygrave 91d3279061 [maven-release-plugin] prepare for next development iteration 2016-10-03 23:40:32 +13:00
Robin Bygrave b4b7c631da [maven-release-plugin] prepare release ebean-8.4.1 2016-10-03 23:40:22 +13:00
Robin Bygrave 4f98ca5d91 #821 - CQueryIteratorSimple not working with consecutive calls to hasNext() - ie. without matching calls to next() 2016-10-03 23:36:03 +13:00
Robin Bygrave 014a9aef6f #826 - Remove deprecated methods - migrate findRowCount() to findCount() & findFutureRowCount() to findFutureCount() 2016-10-03 22:31:33 +13:00
Robin Bygrave f21c33df7b Bump pom to 8.4.1-SNAPSHOT 2016-10-03 22:16:52 +13:00
Robin Bygrave f1eb494e0d #824 - Refactor com.avaje.ebean.config.dbplatform DbType & DbPlatformType - handle logical and plaform ddl conversion 2016-10-03 22:04:37 +13:00
Robin Bygrave d26203db1f #824 - Refactor com.avaje.ebean.config.dbplatform DbType & DbPlatformType - support custom DbType mapping options 2016-10-03 20:52:53 +13:00
Robin Bygrave abfe58fb06 #824 - Refactor com.avaje.ebean.config.dbplatform DbType & DbPlatformType - no effective change, tidy. 2016-09-23 00:27:39 +12:00
Robin Bygrave d0ad5f6c48 #824 - Refactor com.avaje.ebean.config.dbplatform DbType & DbPlatformType 2016-09-23 00:17:51 +12:00
Robin Bygrave bc4a246f33 [maven-release-plugin] prepare for next development iteration 2016-09-22 22:25:14 +12:00
Robin Bygrave 61f590944b [maven-release-plugin] prepare release ebean-8.3.1 2016-09-22 22:25:05 +12:00
Robin Bygrave 223e53416d Bump pom version to 8.3.1-SNAPSHOT 2016-09-22 22:24:17 +12:00
Robin Bygrave a3143b1cf6 #822 - EbeanServer.getBeanId(entity) does not trigger jdbc batch flush - when bean inserted with jdbc batch mode 2016-09-22 21:25:22 +12:00
Robin Bygrave bd3e7c8035 #823 - Remove deprecated API from PagedList 2016-09-22 21:02:28 +12:00
Robin Bygrave b753ce3a73 #820 - #718 Removed PagedList.getPageIndex() - Can it be added back? 2016-09-22 20:57:17 +12:00
Robin Bygrave a0f2ebe448 [maven-release-plugin] prepare for next development iteration 2016-09-01 21:08:23 +12:00
Robin Bygrave 7e7810602e [maven-release-plugin] prepare release ebean-8.2.3 2016-09-01 21:08:09 +12:00
Robin Bygrave d218fff374 #819 - Fix for bug in @ManyToOne relations with enabled soft-deletes 2016-08-31 23:03:00 +12:00
Rob BygraveandGitHub a0e927d353 Merge pull request #819 from FOCONIS/test-softdelete
ADD: testcase for bug in @ManyToOne relations with enabled soft-deletes
2016-08-31 22:05:46 +12:00
Robin Bygrave 51a58d4993 No effective change - remove whitespace in test 2016-08-31 20:57:24 +12:00
Roland Praml b9f0ee7ac0 ADD: testcase for https://groups.google.com/forum/#!topic/ebean/WKbGmROoIRA 2016-08-31 09:48:11 +02:00
Roland Praml 4f3b461f8e FIX: TestHistoryInsert / TestNewTypes failing nondeterministic 2016-08-30 09:14:22 +02:00
Roland Praml adfe5f0305 FIX: Bean did not get dirty when modified with ExpressionPath.pathSet 2016-08-30 09:13:44 +02:00
Robin Bygrave 1796c8b9bc #817 - SqlRow getBoolean() does not treat numeric 1 value as true (with MySql and other DB's without native boolean type) - Fix test for PG 2016-08-29 21:50:14 +12:00
Robin Bygrave 4bad4358f0 Merge branch 'master' of https://github.com/ebean-orm/ebean 2016-08-29 21:06:55 +12:00
Robin Bygrave 92665ebc3b Refactor - tidy of DefaultSqlRow - no logical change 2016-08-29 21:06:31 +12:00
Robin Bygrave 59670d0303 #817 - SqlRow getBoolean() does not treat numeric 1 value as true (with MySql and other DB's without native boolean type) 2016-08-29 20:54:49 +12:00
Robin Bygrave 244275fd72 #816 - Error saving circular relationships (when generated Id values) 2016-08-25 22:44:22 +12:00
Robin Bygrave d1e2176a5a [maven-release-plugin] prepare for next development iteration 2016-08-24 22:53:15 +12:00
Robin Bygrave 43968e70b8 [maven-release-plugin] prepare release ebean-8.2.2 2016-08-24 22:53:02 +12:00
Robin Bygrave 0aa3bd3c97 Update README 2016-08-24 22:52:02 +12:00
Robin Bygrave 2d85a9a20c Update README 2016-08-24 22:45:14 +12:00
Robin Bygrave 157dfcfeb6 #815 - ENH: When loading ebean-autotune.xml also look in resources (if not found as file) 2016-08-24 22:19:46 +12:00
Robin Bygrave 2b7c204072 No effective change - adjust tests for deleting OneToOne - Tire to Wheel 2016-08-24 21:32:10 +12:00
Robin Bygrave be731feb6b No effective change - adjust tests for H2 error vs Postgres truncate with oversized varchar input 2016-08-23 20:01:11 +12:00
Robin Bygrave da15d0b2c6 No effective change - format javadoc 2016-08-23 20:00:07 +12:00
Rob BygraveandGitHub 9c5fd496c1 Merge pull request #814 from FOCONIS/master
ENHANCEMENT: multiple indices & meta-annotation support similar to spring-framework
2016-08-23 19:43:04 +12:00
Roland Praml 5075ea32b4 Merge branch 'master' of github.com:FOCONIS/avaje-ebeanorm 2016-08-23 09:27:28 +02:00
Roland Praml f5c8d8896f Used @Repeatable feature from JDK8 for @Indices 2016-08-23 09:27:12 +02:00
Roland Praml 32fdff9f11 Used @Repeatable feature from JDK8 for @Indices 2016-08-22 10:00:13 +02:00
Roland Praml 87f6964995 Ignored tests that make problems with Postgres 2016-08-22 09:34:45 +02:00
Roland Praml b45226dd41 Merge remote-tracking branch 'ebean/master' 2016-08-16 11:06:47 +02:00
Roland Praml 992c40d362 no effective code change - fix indentions 2016-08-16 11:06:01 +02:00
Rob BygraveandGitHub 9144d60948 Merge pull request #813 from zhangshifeng/fix-artifactId
Update README.md and pom.xml for artifactId change
2016-08-13 11:23:04 +12:00
zhangshifeng 6396143d49 Update README.md and pom.xml for artifactId change 2016-08-12 17:20:29 +08:00
Robin Bygrave ce045ca0fe No effective change - remove unused methods (from ImportedId) 2016-08-11 20:22:35 +12:00
Robin Bygrave d722d34072 [maven-release-plugin] prepare for next development iteration 2016-08-05 13:53:23 +12:00
Robin Bygrave 2cc4c2c265 [maven-release-plugin] prepare release ebean-8.2.1 2016-08-05 13:53:03 +12:00
Robin Bygrave 0a830841c4 Bump pom to 8.2.1-SNAPSHOT 2016-08-05 13:52:09 +12:00
Robin Bygrave c427009b93 #812 - Remove deprecated includeSoftDeletes() ... migrate to setIncludeSoftDeletes() 2016-08-05 13:47:32 +12:00
Robin Bygrave 7f42d045ac No effective change - javadoc typo 2016-08-05 13:29:28 +12:00
Robin Bygrave 43afaf1344 #811 - ENH: Restore findIterate() as alternative to findEach / findEachWhile 2016-08-05 13:01:42 +12:00
Robin Bygrave 6c182ecaa5 #810 - ENH: Add transaction.isRollbackOnly() 2016-08-05 12:14:58 +12:00
Robin Bygrave fdb839f90e #809 - Add test / example showing ... transaction.setPersistCascade(false) and transaction.commitAndContinue(); 2016-08-05 11:20:12 +12:00
Robin Bygrave 16be213faf #808 - ENH: Add Transaction commitAndContinue() ... 2016-08-05 10:39:17 +12:00
Robin Bygrave 3344f0ddb0 Refactor - remove unused method JdbcTransaction.notifyQueryOnly(). 2016-08-04 23:25:50 +12:00
Robin Bygrave 479ac38537 #807 - Deprecate TransactionEventListener ... migrate to TransactionCallback 2016-08-04 23:17:57 +12:00
Robin Bygrave e30ad80f5f #806 - Deprecate OnQueryOnly.CLOSE ... 2016-08-04 23:02:26 +12:00
Robin Bygrave 08e46d6bf3 #805 - ENH: Add BeanState.resetForInsert() ... This resets bean state such that a save() results in an insert 2016-08-04 22:49:07 +12:00
Robin Bygrave 876476fdc1 #804 - Remove API - findMap(property, type) ... migrate to query.setMapKey() 2016-08-04 20:30:18 +12:00
Robin Bygrave 81de83a6e7 #803 - Fix generics on findMap() to ... <K> Map<K, T> findMap(); 2016-08-04 20:23:11 +12:00
Robin Bygrave b5b221ffb1 No effective change - remove unused constructors 2016-08-04 17:32:18 +12:00
Robin Bygrave 3c6eab6c85 #802 - Find generics on findIds() - refactor internals of find ids to use find single attribute 2016-08-04 17:28:41 +12:00
Robin Bygrave 1be30f1671 #125 - ENH: Add support for query returning a List of single Attribute type 2016-08-04 16:41:50 +12:00
Robin Bygrave 9a5cb242ce No effective change - remove commented out line from pom 2016-08-04 13:56:09 +12:00
Robin Bygrave ea69cae4a3 [maven-release-plugin] prepare for next development iteration 2016-08-03 16:24:43 +12:00
Robin Bygrave 629fb7a433 [maven-release-plugin] prepare release ebean-8.1.1 2016-08-03 16:24:23 +12:00
Robin Bygrave 4ff10da739 #801 - Change maven groupId ... to org.avaje.ebean, artifactId to ebean 2016-08-03 16:23:26 +12:00
Robin Bygrave 9472592a50 [maven-release-plugin] prepare for next development iteration 2016-08-03 00:40:37 +12:00
Robin Bygrave f42682ca90 [maven-release-plugin] prepare release avaje-ebeanorm-8.1.1 2016-08-03 00:40:18 +12:00
Robin Bygrave 5dc296e644 #798 - Add @Transactional based test 2016-08-03 00:38:58 +12:00
Robin Bygrave 380660913f No effective change - javadoc update on Query 2016-08-02 23:42:00 +12:00
Robin Bygrave d08ac6973e #800 - ENH: Add query.fetchQuery() and query.fetchLazy() ... as nicer alternatives to FetchConfig use 2016-08-02 23:33:02 +12:00
Robin Bygrave 9d23c1d56e #800 - ENH: Add query.fetchQuery() and query.fetchLazy() ... as nicer alternatives to FetchConfig use 2016-08-02 23:30:26 +12:00
Robin Bygrave b5d6c5f70b #800 - ENH: Add query.fetchQuery() and query.fetchLazy() ... as nicer alternatives to FetchConfig use 2016-08-02 23:30:04 +12:00
Robin Bygrave 3657d05774 #798 - ENH: Add support for transparent full JDBC batch. Via enhancement agent 8.1.1 ... 2016-08-02 21:41:13 +12:00
Robin Bygrave 2de8ae777d Merge branch 'wip/getterCallback' 2016-08-02 21:34:41 +12:00
Robin Bygrave 16950a5641 [maven-release-plugin] prepare for next development iteration 2016-08-02 21:32:08 +12:00
Robin Bygrave ad992d07ce [maven-release-plugin] prepare release avaje-ebeanorm-7.21.2 2016-08-02 21:31:47 +12:00
Robin Bygrave cbcec8f5ea No effective change - tidy 2016-08-02 20:32:59 +12:00
Robin Bygrave 6e2148d20b #799 - Query.fetch(path) when converted to query join default to batchSize 10 rather than 100 2016-08-02 20:19:38 +12:00
Robin Bygrave ca1c0a08f3 No effective change - remove whitespace on DLoadBeanContext 2016-08-02 20:14:46 +12:00
Robin Bygrave baa6fc355e No effective change - javadoc update on FetchConfig 2016-08-02 20:14:07 +12:00
Robin Bygrave dacdc26902 #798 - ENH: Add support for transparent full JDBC batch. Via enhancement agent 8.1.1 intercept bean getter to automatically flush the JDBC batch buffer. 2016-08-02 16:16:34 +12:00
Robin Bygrave 48edf64013 No effective change - typo in javadoc 2016-08-02 11:10:19 +12:00
Robin Bygrave e2ee6e8e98 No effective change - update tests with EBasicVer new constructor 2016-08-02 11:06:09 +12:00
Robin Bygrave e6e6a28245 No effective change - tidy asserts on TestQueryDistinct (AssertJ string contains etc) 2016-08-01 22:53:47 +12:00
Rob BygraveandGitHub 82a695a98a Merge pull request #797 from backslash47/master
Add check for distinct query when adding id attribute to order clause in paging query
2016-08-01 22:47:34 +12:00
Matus Zamborsky cdad31bd8a Added test for distinct paging query 2016-08-01 12:20:50 +02:00
Matus Zamborsky 4d16cf9caa Add check for distinct query when adding id attribute to order clause in paging query 2016-08-01 10:13:05 +02:00
Robin Bygrave 84a86cad0e #794 - Refactor - tidy code, remove unused mimetypes properties 2016-07-31 23:34:55 +12:00
Robin Bygrave dfdf87fa2d #794 - Refactor - tidy code, javadoc tidy 2016-07-31 23:33:29 +12:00
Robin Bygrave ee0615caec #794 - Refactor - tidy code, use uppercase L for Long literal 2016-07-31 23:33:07 +12:00
Robin Bygrave 79b8395f8f #794 - Refactor - tidy code, simplify if 2016-07-31 23:32:37 +12:00
Robin Bygrave 87c479cd95 #794 - Refactor - tidy code, remove unused imports 2016-07-31 23:24:30 +12:00
Robin Bygrave abbdda810a #794 - Refactor - tidy code, remove unused method arguments 2016-07-31 23:23:57 +12:00
Robin Bygrave e621900de9 #794 - Refactor - tidy code, remove unused method arguments 2016-07-31 23:23:43 +12:00
Robin Bygrave 76b33511e1 #793 - com.avaje.ebean.event.changelog.BeanChange not keeping passed id value 2016-07-31 23:14:08 +12:00
Robin Bygrave 77deab5cf0 #792 - Change Logging Rollback message on org.avaje.ebean.TXN from INFO level to DEBUG level 2016-07-31 22:52:48 +12:00
Robin Bygrave 4a9f8cef0e No effective change - rename SpiQuery method for m2mIncludeJoin and simplify OrmQueryPlanKey to associated intersection table name 2016-07-31 22:49:10 +12:00
Robin Bygrave 4d1340c16c No effective change - rename SpiQuery method for m2mIncludeJoin and simplify OrmQueryPlanKey to associated intersection table name 2016-07-31 22:46:07 +12:00
Robin Bygrave 74c6c71301 [maven-release-plugin] prepare for next development iteration 2016-07-31 21:28:17 +12:00
Robin Bygrave 0f0028eb1f [maven-release-plugin] prepare release avaje-ebeanorm-7.21.1 2016-07-31 21:27:58 +12:00
Robin Bygrave b4a1d52067 #791 - ENH: Add transaction.setRollbackOnly() ... (and Ebean.setRollbackOnly()) 2016-07-31 21:24:31 +12:00
Robin Bygrave d82148248c No effective change - javadoc tidy 2016-07-31 20:55:34 +12:00
Robin Bygrave dc7c854432 #788 - Deprecate findRowCount() ... add findCount(). Effectively renaming findRowCount() to findCount() 2016-07-31 19:06:21 +12:00
Robin Bygrave 7c83010df1 #788 - Deprecate findRowCount() ... add findCount(). Effectively renaming findRowCount() to findCount() 2016-07-31 16:39:23 +12:00
Robin Bygrave ed41e58073 Bump pom version to 7.21.1-SNAPSHOT 2016-07-31 16:01:00 +12:00
Robin Bygrave 5bab9eb648 #790 - DB Migration with multiple platforms (and no maven H2 dependency) gives: java.lang.NoClassDefFoundError: org/h2/api/Trigger 2016-07-31 15:59:54 +12:00
Robin Bygrave 5ce8eb6046 No effective change - remove unused methods 2016-07-31 15:02:05 +12:00
Robin Bygrave 56fee2ea9b #789 - findCount() ... with where raw(...) expression that includes a "many" produces incorrect SQL 2016-07-31 14:57:12 +12:00
Roland Praml 84f32c2ace ENH: support for multiple indices added 2016-07-30 16:06:01 +02:00
Roland Praml 85288a0652 Added a testcase that checks if meta-annotations are recognized 2016-07-30 13:13:54 +02:00
Roland Praml 3183287833 ENH: meta-annotation support similar to spring.
See http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-meta-annotations for detailed explanation
2016-07-30 12:44:14 +02:00
Robin Bygrave 780ee7c7c0 [maven-release-plugin] prepare for next development iteration 2016-07-25 23:37:18 +12:00
Robin Bygrave 2bac7bf84d [maven-release-plugin] prepare release avaje-ebeanorm-7.20.1 2016-07-25 23:36:58 +12:00
Robin Bygrave 499862438d Bump pom to 7.20.1-SNAPSHOT 2016-07-25 23:36:12 +12:00
Robin Bygrave 4ad0b7cf66 #786 - Bump avaje-dbmigration to 1.2.1 ... which uses autoCommit true when running drop-all ddl 2016-07-25 23:34:17 +12:00
Robin Bygrave 6108ef484b #782 - History Many-To-Many Lazy-Loads fail 2016-07-25 23:31:02 +12:00
Robin Bygrave b763f4c875 #783 - HistoryExclude Many-to-Many Query-Generation Error 2016-07-25 23:29:33 +12:00
Robin Bygrave ca7285b2ad #783 - tests for ... HistoryExclude Many-to-Many Query-Generation Error 2016-07-25 23:28:45 +12:00
Robin Bygrave 75b639bc15 #782 - tests for ... History Many-To-Many Lazy-Loads fail 2016-07-25 23:22:33 +12:00
Robin Bygrave 1a7c4dac3f #1 - Change DdlGenerator.runScript() so that it uses connection.setAutoCommit(true) for drop ddl - when expectErrors is true 2016-07-25 23:03:00 +12:00
Robin Bygrave 6828fa1786 #784 - DDL DB Migration - Add @ManyToOne does not generate Foreign key and index ddl statements in migration script 2016-07-25 20:44:15 +12:00
Robin Bygrave ba7e729ae1 #785 - Bump avaje-classpath-scanner-api dependency to 2.2 for Windows fixes to classpath-scanner 2016-07-25 11:39:41 +12:00
Rob BygraveandGitHub c3fba72a24 Merge pull request #781 from FOCONIS/master
FIX: PathTests - on Windows
2016-07-25 11:14:23 +12:00
Robin Bygrave ff401cfc72 [maven-release-plugin] prepare for next development iteration 2016-07-20 00:03:20 +12:00
Robin Bygrave 7902276296 [maven-release-plugin] prepare release avaje-ebeanorm-7.19.1 2016-07-20 00:02:59 +12:00
Robin Bygrave 95f7a85aa1 Bump version to 7.19.1-SNAPSHOT 2016-07-20 00:02:08 +12:00
Roland Praml cf9eb4ed97 FIX: PathTests - they fail on windows machine, because the OS translates "/tmp" to "c:\tmp". bumped classpath-canner to current API version 2016-07-19 13:25:53 +02:00
Robin Bygrave b5cb04a6ed #780 - Remove ServerConfig registerJmxMBeans ... as it is no longer used 2016-07-18 09:22:22 +12:00
Robin Bygrave 5a9193f732 #779 - Refactor - Tidy internals of DefaultOrmQuery, remove unused String query property. 2016-07-15 23:51:27 +12:00
Robin Bygrave 55584f09d5 #778 - ENH: Add support for loading named queries from ebean.xml 2016-07-15 23:33:09 +12:00
Robin Bygrave 05eb0bfc55 #777 - ENH: Add support for @NamedQuery and @NamedQueries 2016-07-15 23:15:18 +12:00
Robin Bygrave cf13119b49 #776 - Remove ServerConfig.cacheWarmingDelay ... as it is no longer used 2016-07-15 20:51:22 +12:00
Robin Bygrave e0eff149b5 #775 - Change DefaultBackgroundExecutor to use JDK cached thread pool (rather than configure min/max size etc) 2016-07-15 20:48:41 +12:00
Robin Bygrave 474c2d5595 EQL - Add / expose via EbeanServer.createQuery(type, eql) method 2016-07-13 16:40:52 +12:00
Robin Bygrave e58cec8bdd EQL - parsing order by clause 2016-07-13 15:28:06 +12:00
Robin Bygrave 9dd82c0dd7 EQL - parsing limit offset clause 2016-07-13 14:30:12 +12:00
Robin Bygrave 49d3cc91e4 EQL - parsing select clause with distinct option 2016-07-13 14:07:59 +12:00
Robin Bygrave a8c2fc2ed5 EQL - parsing select clause 2016-07-13 13:55:56 +12:00
Robin Bygrave 45d7e3cafd EQL - parsing fetch clause with lazy/query option 2016-07-13 13:04:38 +12:00
Robin Bygrave be6754bd06 EQL - parsing fetch clause 2016-07-13 11:01:44 +12:00
Robin Bygrave 83c16ad1c6 EQL - parsing IN expressions with named parameters 2016-07-13 10:12:15 +12:00
Robin Bygrave 3f8b389999 EQL - parsing BETWEEN property expressions 2016-07-13 09:48:58 +12:00
Robin Bygrave b4b6a13e75 EQL - parsing BETWEEN expressions 2016-07-13 09:30:00 +12:00
Robin Bygrave 3fad4aae2f EQL - parsing IN expressions 2016-07-12 23:29:34 +12:00
Robin Bygrave ceab95e6c2 EQL - Simplify nested query where expressions after parsing 2016-07-12 22:51:02 +12:00
Robin Bygrave 84b37fb014 EQL Named parameter support for Like and ieq 2016-07-12 21:56:43 +12:00
Robin Bygrave 1a1c432c2a Initial add of SpiNamedParam 2016-07-12 20:45:33 +12:00
Robin Bygrave 86faa947af No effective change - tidy tests 2016-07-12 16:22:18 +12:00
Robin Bygrave 6b54b6ef46 Refactor BeanPropertyAssocOne findByParentIds use of raw expression 2016-07-12 16:11:51 +12:00
Robin Bygrave d8dfd66af3 Refactor BeanPropertyAssocMany findByParentIds use of raw expression 2016-07-12 16:01:32 +12:00
Robin Bygrave 675c51b8c1 Add IEQ support 2016-07-12 15:22:04 +12:00
Robin Bygrave 3cd7ecaa4a Merge branch 'wip/eql1' into wip/eql2 2016-07-12 15:05:00 +12:00
Robin Bygrave 1b322955ee [maven-release-plugin] prepare for next development iteration 2016-07-11 21:31:44 +12:00
Robin Bygrave 8115c5e230 [maven-release-plugin] prepare release avaje-ebeanorm-7.18.1 2016-07-11 21:31:25 +12:00
Robin Bygrave ad180c5531 No effective change - reduce test logging 2016-07-11 21:27:34 +12:00
Robin Bygrave b454f46dd4 Bump pom to 7.18.1-SNAPSHOT 2016-07-11 21:27:06 +12:00
Robin Bygrave 8a853b28f3 #772 - DB Migration DDL - alter table add column ... needs type conversion when using multiple platforms. e.g. varchar(20) ... convert to varchar2(20) for Oracle 2016-07-11 21:25:58 +12:00
Robin Bygrave a1be7ba5dd #771 - DB Migration DDL when using multiple platforms ... destination into sub directories rather than file suffix 2016-07-11 21:17:12 +12:00
Robin Bygrave 3914516793 #770 - DB Migration DDL generation run offline when using multiple platforms 2016-07-11 20:20:26 +12:00
Robin Bygrave 8c5854f77c #770 - DB Migration DDL generation run offline when using multiple platforms 2016-07-11 20:14:29 +12:00
Robin Bygrave 0bc5b94eae #770 - DB Migration DDL generation run offline when using multiple platforms 2016-07-11 20:08:26 +12:00
Robin Bygrave 12fa287f35 #769 - DB Migration DDL generation for UUID type when generating multiple platforms 2016-07-11 19:54:50 +12:00
Robin Bygrave 2991cb9ad1 #768 - Query.setDisableLazyLoading(true) ... not disabling lazy loading on @ManyToOne reference bean 2016-07-11 15:09:59 +12:00
Robin Bygrave 3b7f5496a8 #767 - Query.setDisableLazyLoading(true) ... not disabling lazy loading on @OneToMany 2016-07-11 12:28:31 +12:00
Robin Bygrave 4be703ff6e #767 - Query.setDisableLazyLoading(true) ... not disabling lazy loading on @OneToMany 2016-07-11 11:58:02 +12:00
Robin Bygrave d2c5765ac1 No effective change - tidy comments 2016-07-11 11:24:57 +12:00
Robin Bygrave aaf256b9be #766 - RawSql should automatically map column alias with underscore to camelCase ... so item_total should automatically map to bean property itemTotal 2016-07-08 23:44:11 +12:00
Robin Bygrave c7c6410cd9 #765 - ENH: Add ebean.xml with support for named RawSql, also adds EbeanServer.createNamedQuery() 2016-07-08 22:35:04 +12:00
Robin Bygrave 2c3c23725a No effective change - reformat code 2016-07-08 15:37:26 +12:00
Robin Bygrave 92069c0319 #764 - NPE on BeanDescriptorManager.processViewInvalidation(BeanDescriptorManager.java:385) 2016-07-08 15:34:43 +12:00
Robin Bygrave 630ad66ff1 #763 - Internal Code cleanup - remove redundant null checking etc 2016-07-08 15:01:39 +12:00
Robin Bygrave b732b390c7 [maven-release-plugin] prepare for next development iteration 2016-07-07 21:51:15 +12:00
Robin Bygrave 8c62fcdcb2 [maven-release-plugin] prepare release avaje-ebeanorm-7.17.1 2016-07-07 21:50:53 +12:00
Robin Bygrave e458f577fe No effective change - reduce logging for BeanDescriptorManager entity count message from INFO to DEBUG 2016-07-07 21:49:43 +12:00
Robin Bygrave 23434bab8c Bump pom to 7.17.1-SNAPSHOT 2016-07-07 21:45:40 +12:00
Robin Bygrave c47b5a1595 #762 - Change H2 Platform to IDENTITY (from SEQUENCE) with version 1.4.192 2016-07-07 21:43:15 +12:00
Robin Bygrave 411846347b #762 - Change H2 Platform to IDENTITY (from SEQUENCE) with version 1.4.192 2016-07-07 21:33:19 +12:00
Robin Bygrave 3722d19424 #761 - Change default for persistBatchOnCascade to be platform specific rather than NONE 2016-07-07 21:19:08 +12:00
Robin Bygrave 04a7310e5d [maven-release-plugin] prepare for next development iteration 2016-07-06 12:27:45 +12:00
Robin Bygrave 3490e90f03 [maven-release-plugin] prepare release avaje-ebeanorm-7.16.3 2016-07-06 12:27:26 +12:00
Robin Bygrave d89817a5c5 #760 - Change @Transactional(batchSize=100) ... to imply batch mode (remove need to also specify batch=PersistBatch.ALL) 2016-07-06 12:26:18 +12:00
Robin Bygrave db1ba5f20e #759 - Use default value of 100 for JDBC buffer fetchSize for findEach() / findEachWhile() - Add global defaults ServerConfig jdbcFetchSizeFindEach, jdbcFetchSizeFindList 2016-07-04 21:56:33 +12:00
Robin Bygrave 4f9a9a5094 No effective change - remove unused method 2016-06-30 14:45:06 +12:00
Robin Bygrave 1c6ac1289d #758 - DDL - @Index(unique=true) on field/property not creating unique index 2016-06-30 13:59:38 +12:00
Robin Bygrave b96be84106 Merge branch 'master' of github.com:ebean-orm/avaje-ebeanorm 2016-06-30 05:38:32 +12:00
Robin Bygrave 3c40293183 #757 - Reduce logging of Commit message of org.avaje.ebean.TXN from INFO to DEBUG 2016-06-30 05:38:16 +12:00
Rob BygraveandGitHub a9a6031986 Merge pull request #755 from MatthewMerrill/patch-1
Javadoc typo in SqlUpdate
2016-06-28 09:32:27 +12:00
Robin Bygrave b82085da42 [maven-release-plugin] prepare for next development iteration 2016-06-28 07:13:26 +12:00
Robin Bygrave 9a17a7752c [maven-release-plugin] prepare release avaje-ebeanorm-7.16.2 2016-06-28 07:13:06 +12:00
Robin Bygrave 92474c2b24 #754 - Logging output for bind log of UpdateQuery does not include bind values for set clause ... 2016-06-28 07:10:59 +12:00
Robin Bygrave 9a00b9df0e #753 - @History "as of" query errors when executed a second time - invalid bind parameter 2016-06-28 07:04:39 +12:00
Robin Bygrave 697f67c14a #753 - @History "as of" query errors when executed a second time - invalid bind parameter 2016-06-28 06:46:16 +12:00
Matthew MerrillandGitHub 2c34bc1636 Example code typo
Change "there where" to "there were" and added space between modify count and next word.
2016-06-27 09:07:45 -07:00
Robin Bygrave 1f9ccf1c8b [maven-release-plugin] prepare for next development iteration 2016-06-23 21:39:03 +12:00
Robin Bygrave a1f10b8704 [maven-release-plugin] prepare release avaje-ebeanorm-7.16.1 2016-06-23 21:38:42 +12:00
Robin Bygrave 3c21950b91 Bump pom to 7.16.1-SNAPSHOT 2016-06-23 21:36:57 +12:00
Robin Bygrave 3b45308ac7 Merge branch 'DevFactory-release/collection-isempty-1' 2016-06-23 13:40:23 +12:00
Robin Bygrave 00e69e1b5d No effective change - remove extra whitespace 2016-06-23 13:39:34 +12:00
Robin Bygrave 11b3f7a813 Merge branch 'release/collection-isempty-1' of https://github.com/DevFactory/avaje-ebeanorm into DevFactory-release/collection-isempty-1
Conflicts:
	src/main/java/com/avaje/ebeaninternal/server/query/DefaultDbSqlContext.java
2016-06-23 13:24:58 +12:00
Robin Bygrave 2185c8a886 #752 - Refactor: SQL generation for @History support with Postgres, MySql (views/triggers based) such that it more closely aligns with SQL 2011 based SQL 2016-06-23 11:33:01 +12:00
Robin Bygrave f8bda05b37 #751 - @History with @ManyToMany ... intersection table not getting associated history support 2016-06-23 11:05:16 +12:00
Artyom Melnikov 0a3b819991 Fixing squid:S1155 - Collection.isEmpty() should be used to test for emptiness 2016-06-22 13:43:15 +03:00
Rob BygraveandGitHub 5c8b1eb3bb Merge pull request #748 from yuqiyi/master
fix DeployBeanDescriptor.java of the method setView
2016-06-22 22:21:52 +12:00
yuqiyi 824f6dcc7e fix DeployBeanDescriptor.java of the method setView 2016-06-22 18:11:37 +08:00
Robin Bygrave 06e23b85ad #747 - @History findVersionsBetween query with Oracle has incorrect ordering 2016-06-22 20:16:35 +12:00
Robin Bygrave 09219c759b [maven-release-plugin] prepare for next development iteration 2016-06-20 22:57:36 +12:00
Robin Bygrave b861038568 [maven-release-plugin] prepare release avaje-ebeanorm-7.15.1 2016-06-20 22:57:16 +12:00
Robin Bygrave bfd8445bcd Bump pom to 7.15.1-SNAPSHOT 2016-06-20 22:56:04 +12:00
Robin Bygrave c30e3bf78c #746 - SqlQuery with named parameter and limit/offset gives SQL exception 2016-06-20 22:54:08 +12:00
Robin Bygrave c793d6652f #745 - ElasticSearch - internally translate where().id.eq(42) ... to where().setId(42) 2016-06-20 22:29:38 +12:00
Robin Bygrave d12e55c20b #744 - ElasticSearch - isEmpty() expression needs to have outer not:{} negation to work as per .. 2016-06-20 21:32:05 +12:00
Robin Bygrave 3477f590dd #743 - Fix issue with ElasticSearch nested path query with multiple nested path expressions 2016-06-20 20:57:45 +12:00
Robin Bygrave 6bbf93aba8 No effective change - extract private constant in DefaultExpressionList 2016-06-20 13:14:28 +12:00
Robin Bygrave 42d02cc521 [maven-release-plugin] prepare for next development iteration 2016-06-17 22:27:25 +12:00
Robin Bygrave 9ea58572de [maven-release-plugin] prepare release avaje-ebeanorm-7.14.1 2016-06-17 22:27:04 +12:00
Robin Bygrave 35d82c9104 Bump pom to 7.14.1-SNAPSHOT 2016-06-17 22:26:06 +12:00
Robin Bygrave 31aae38616 #742 - ENH: DocStoreConfig ... read System properties for isGenerateMapping(), isDropCreate() and isCreate() 2016-06-17 22:25:11 +12:00
Robin Bygrave f144b53651 #741 - ENH: Add DocumentStore indexSettings() method ... for setting ElasticSearch refresh_interval 2016-06-17 22:21:22 +12:00
Robin Bygrave f47cd7e7c2 Add extra-dll.xml example for .... ENH: For @Index add support for index types (like Postgres GIN) #707 ... 2016-06-17 15:04:12 +12:00
Robin Bygrave 8765cb8356 No effective change - reformat code 2016-06-17 13:24:49 +12:00
Robin Bygrave 30abe75a96 Travis - enable caching .m2 2016-06-17 13:19:01 +12:00
Robin Bygrave 164e6c71c1 Travis - stop caching .m2 2016-06-17 13:15:42 +12:00
Robin Bygrave dfa6353850 #740 - ClassCastException: java.util.ArrayList cannot be cast to com.avaje.ebean.bean.BeanCollection at com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany.resetMany(BeanPropertyAssocMany.java:273) 2016-06-17 12:30:57 +12:00
Robin Bygrave d88ff2a3b2 #739 - UpdateQuery with idEq() expression gives wrong update statement (still has table alias) 2016-06-17 11:34:47 +12:00
Robin Bygrave 713ae75464 No effective change - reformat 2016-06-17 11:03:47 +12:00
Rob BygraveandGitHub 710fb0e947 Merge pull request #738 from DevFactory/staging/using-isempty-fix-1
Refactor: Use Collection.isEmpty() instead of size() comparison to 0 etc
2016-06-15 20:55:02 +12:00
Rob BygraveandGitHub cb0cf97f3f Merge pull request #736 from DevFactory/staging/make-public-static-fields-constant-fix-1
Updating "public static" fields to add final modifier
2016-06-15 20:46:37 +12:00
Artyom Melnikov 07edb2c81f Using Collection.isEmpty() to test for emptiness 2016-06-14 15:21:23 +03:00
Artyom Melnikov 066effa5bf "public static" fields should be constant 2016-06-14 14:18:18 +03:00
Robin Bygrave bb5ca6c56e Bump agent in pom to 4.11.1 2016-06-14 22:24:50 +12:00
Robin Bygrave a64a020e36 #734 - Add ServerConfig.skipCacheAfterWrite & transaction.setSkipCache(boolean) ... to control L2 Bean cache use during transaction 2016-06-10 17:59:37 +12:00
Robin Bygrave c24ee53462 [maven-release-plugin] prepare for next development iteration 2016-06-08 14:40:18 +12:00
Robin Bygrave 06e4bdca0e [maven-release-plugin] prepare release avaje-ebeanorm-7.13.1 2016-06-08 14:39:56 +12:00
Robin Bygrave 3dbf35aca4 Bump pom version to 7.13.1-SNAPSHOT 2016-06-08 14:38:47 +12:00
Robin Bygrave cd56b3ca3c #726 - L2 cache returns stale data -> change such that when using "local L2 caching" the changes to L2 cache propagate in foreground 2016-06-08 14:38:08 +12:00
Robin Bygrave 353175626d #733 - RawSqlBuilder.columnMapping() not working using DB column alias ... java.lang.IllegalArgumentException: DB Column [detail_count] not found in mapping. 2016-06-07 17:10:37 +12:00
Robin Bygrave 1a3acb86df #732 - NPE in ScalarTypeArrayList.read(ScalarTypeArrayList.java:89) ... 2016-06-03 08:09:04 +12:00
Robin Bygrave 1304646cce #731 - ENH: Add support for using ebean.mf manifest file for finding/defining packages to search for entities 2016-06-02 17:35:06 +12:00
Robin Bygrave b3828572fd No effective change - javadoc for ServerConfig 2016-06-02 14:08:00 +12:00
Robin Bygrave eddd48f8ad #730 - Remove unused ServerConfig.classPathReaderClassName ... as replaced by org.avaje.classpath.scanner.ClassPathScanner plugin (in 7.8.1) 2016-06-02 14:03:30 +12:00
Robin Bygrave 9797502ef2 #729 - Remove unused ServerConfig.addJar(...); serverConfig.setJars(...); ... as "search jars" is no longer used in classpath scanning (since 7.8.1) 2016-06-02 13:55:14 +12:00
Robin Bygrave daba7a11b4 No effective change - remove unused code (old ClassPathReader etc) 2016-06-01 20:53:07 +12:00
Robin Bygrave 92caf69cb3 #728 - Remove Query.where(String) ... migrate to where().raw(...) 2016-06-01 19:54:02 +12:00
Robin Bygrave a954f8e9e1 EQL - initial 2016-06-01 17:27:35 +12:00
Robin Bygrave 71f70c01ae #727 - ENH: Add endOr(), endAnd(), endNot() ... to ExpressionList as synonym for endJunction() 2016-06-01 16:03:30 +12:00
Robin Bygrave 74d7652044 [maven-release-plugin] prepare for next development iteration 2016-05-30 17:28:05 +12:00
Robin Bygrave d7ee748f31 [maven-release-plugin] prepare release avaje-ebeanorm-7.12.2 2016-05-30 17:27:43 +12:00
Robin Bygrave 2442eb017a #725 - L2 cache not updating CacheManyId's entry when Lazy loading on a ToMany relationship, after a prior update, when other ToMany is a vanilla type (like ArrayList) 2016-05-30 17:01:20 +12:00
Robin Bygrave 37ea56ad11 #724 - NPE when using L2 caching configured with @Cache with queryCaching=true and beanCaching=false 2016-05-30 16:56:04 +12:00
Robin Bygrave 067a8b784c No effective change - add test with where().raw() containing disjunction etc 2016-05-24 09:28:29 +12:00
Robin Bygrave b18922df79 [maven-release-plugin] prepare for next development iteration 2016-05-23 22:34:46 +12:00
Robin Bygrave 70cce1094e [maven-release-plugin] prepare release avaje-ebeanorm-7.12.1 2016-05-23 22:34:24 +12:00
Robin Bygrave 44c69dec72 Bump pom to 7.12.1-SNAPSHOT 2016-05-23 22:33:10 +12:00
Robin Bygrave 6c7074e288 #120 - ENH: Add support for using where() on bulk Update statements 2016-05-23 22:24:07 +12:00
Robin Bygrave 1c162b9b18 #723 - Breaking API - Change BeanPersistListener to return void rather than boolean for inserted(), updated() and deleted() 2016-05-23 10:31:24 +12:00
Robin Bygrave 676f0d7a24 #722 - NotifyOfCommit failed. L2 Cache potentially not notified. - NullPointerException at BeanDescriptorCacheHelp.java:299 2016-05-22 20:20:23 +12:00
Robin Bygrave 46e674db57 #721 - Remove EbeanServer saveManyToManyAssociations() and deleteManyToManyAssociations() 2016-05-20 23:42:02 +12:00
Robin Bygrave 0e1aacdeee #720 - Remove EbeanServer saveAssociation(Object ownerBean, String propertyName); ... migrate to just save the bean 2016-05-20 23:24:37 +12:00
Robin Bygrave 7268890332 #719 - Remove deprecated Query.includeSoftDeletes() ... migrate to setIncludeSoftDeletes() 2016-05-20 23:08:28 +12:00
Robin Bygrave b2a3f0c99b #718 - Remove findPagedList(pageIndex, pageSize) ... migrate to setFirstRows().setMaxRows().findPagedList() 2016-05-20 23:04:35 +12:00
Robin Bygrave 662be92a16 #717 - Remove findIterate() ... migrate to findEach() or findEachWhile() 2016-05-20 22:38:07 +12:00
Robin Bygrave 11d623cb69 #716 - Remove createNamedQuery() and createQuery(Class<T> beanType, String query) ... use criteria API, query beans and RawSql 2016-05-20 22:13:58 +12:00
Robin Bygrave a20822a9e1 #715 - isNull() expression on @OneToMany or @ManyToMany produces incorrect SQL - should translate this to be same as isEmpty() and result in exists subquery 2016-05-20 17:53:11 +12:00
Rob Bygrave 0510304c0f Merge pull request #714 from VictorJimenezKwast/master
Added tests for query isNull expressions
2016-05-20 15:39:32 +12:00
Victor Jimenez Kwast fb2488e3b8 Added tests for query isNull expressions 2016-05-20 00:21:33 +02:00
Robin Bygrave 5959dcc7db [maven-release-plugin] prepare for next development iteration 2016-05-19 22:47:42 +12:00
Robin Bygrave 3656091d1f [maven-release-plugin] prepare release avaje-ebeanorm-7.11.4 2016-05-19 22:47:24 +12:00
Robin Bygrave 5122ea4b4d #416 - RawSql issue with inheritance - PersistenceException: Inheritance type for discriminator value 2016-05-19 22:44:55 +12:00
Robin Bygrave db8dd48e53 #513 - Column Constraint for Enum types should cover all Enum values in an inheritance hierachy 2016-05-19 20:55:16 +12:00
Robin Bygrave 4606c7c99f No effective change - format and imports 2016-05-19 19:58:00 +12:00
Robin Bygrave e3a7c3040b #540 - Add tests for ... RawSqlBuilder columnMapping is confused by commas in COALESCE (actually fixed in 6.14.1) 2016-05-19 09:35:39 +12:00
Robin Bygrave cb51ea4238 #713 - DB Migration - When change is from Not Null to Null ... this migration is duplicated in subsequent migration generation 2016-05-18 21:04:36 +12:00
Robin Bygrave a1a48dac2c #712 - Refactor: Rename DbMigrationConfig dbUser to dbUsername 2016-05-18 20:50:18 +12:00
Robin Bygrave b8d9273152 No effective change - reduce logging in logback-test.xml 2016-05-18 17:29:39 +12:00
Robin Bygrave 026f0e161f #711 - Refactor: Extract DB Migration runner as separate module (called avaje-dbmigration) 2016-05-18 17:27:54 +12:00
Robin Bygrave 75a2633590 #710 - Behavior change - query with invalid fetch path (without properties) now throws PersistenceException 2016-05-18 12:34:16 +12:00
Robin Bygrave 362ceea79b #709 - Refactor: BeanCollection internals, rename method isEmptyAndUntouched() to isSkipSave(), remove 'touched' flag 2016-05-18 11:19:01 +12:00
Robin Bygrave 1c9b974427 #708 - Refactor - Remove BeanCollectionTouched interface 2016-05-18 10:13:03 +12:00
Robin Bygrave f181e3946f No effective change - format code 2016-05-18 09:36:26 +12:00
Robin Bygrave 6df145b4fa No effective change - format code 2016-05-18 09:35:26 +12:00
Robin Bygrave a4cb116d4f No effective change - format code 2016-05-18 09:34:20 +12:00
Robin Bygrave 3161664d58 No effective change - additional test for constructor enhancement (from agent https://github.com/ebean-orm/avaje-ebeanorm-agent/issues/31) 2016-05-17 16:41:58 +12:00
Robin Bygrave 4b3f63f6e0 Update pom - update agent version to 4.10.1 2016-05-17 16:40:51 +12:00
Robin Bygrave d89b1b0367 #511 Add Test (that is clearer with better asserts) 2016-05-17 08:19:13 +12:00
Robin Bygrave 17433bb70b [maven-release-plugin] prepare for next development iteration 2016-05-16 16:58:02 +12:00
Robin Bygrave fb6ea92ae9 [maven-release-plugin] prepare release avaje-ebeanorm-7.11.3 2016-05-16 16:57:39 +12:00
Robin Bygrave 08b0a6350d #706 - NPE when using @DbArray with null values 2016-05-16 16:54:18 +12:00
Robin Bygrave bd330b4c0e No effective change - additional tests for @DbArray inserting nulls 2016-05-16 16:30:41 +12:00
Robin Bygrave ec234f1f39 #568 - ENH: Add ability to turn of getGeneratedKeys with @Transactional annotation (Also needs agent update) 2016-05-16 15:50:11 +12:00
Robin Bygrave dd28b28095 #704 - Update javadoc for @Cache and @Query.setUseCache() 2016-05-13 16:30:43 +12:00
Robin Bygrave 2a5be6db3d No effective change - sys out for CI server - fix PG like clause in test 2016-05-13 16:23:19 +12:00
Robin Bygrave 545f40703e No effective change - sys out for CI server 2016-05-13 16:18:17 +12:00
Robin Bygrave 35d0481644 No effective change - sys out for CI server 2016-05-13 16:05:13 +12:00
Robin Bygrave 2282ff3c6e #704 - Internal refactor to use excludeBeanCache in DefaultOrmQuery 2016-05-13 15:57:20 +12:00
Robin Bygrave d1d4bf1da8 #704 - Internal refactor to use excludeBeanCache in DefaultOrmQuery 2016-05-13 15:56:45 +12:00
Robin Bygrave 8c6653605d #704 - Update tests for 704 removing the use of Query.setUseCache(true) which is redundant 2016-05-13 14:31:03 +12:00
Robin Bygrave e344b5c0a1 #703 - Refactor - When batch lazy loading hits the L2 bean cache and misses initially, it checks that initial bean again (and should skip the second attempt) 2016-05-13 14:12:28 +12:00
Robin Bygrave 0e5859716b #702 - IllegalStateException: No bean cache enabled error ... when updating bean that is not using caching (but is related to a bean with @Cache) 2016-05-13 12:52:27 +12:00
Robin Bygrave 90a794fca5 No effective change - sys out for CI server - add ReadAuditQueryPlan equals/hashCode for CI issue 2016-05-13 11:06:26 +12:00
Robin Bygrave 1d6e480402 No effective change - sys out for CI server 2016-05-13 10:55:36 +12:00
Robin Bygrave 54706302df #701 - DB Migration - incorrect alter column DDL when removing not null constraint (Postgres specific) 2016-05-13 09:07:43 +12:00
Robin Bygrave 4a59cf4c3d No effective change - sys out for CI server 2016-05-12 21:31:15 +12:00
Robin Bygrave 8cb8f9eabf #278 - SqlQuery setFirstRow fail - modify SQL using LIMIT/OFFSET etc to support firstRows/maxRows 2016-05-12 20:59:52 +12:00
Robin Bygrave 58a36e6b67 No effective change - cleanup comment 2016-05-12 19:07:52 +12:00
Robin Bygrave 064d282f7b [maven-release-plugin] prepare for next development iteration 2016-05-12 17:43:22 +12:00
Robin Bygrave e83ec42bbc [maven-release-plugin] prepare release avaje-ebeanorm-7.11.2 2016-05-12 17:43:03 +12:00
Robin Bygrave 409720d854 #700 - Postgres ARRAY and JSON expressions cast Long to ::integer rather than ::bigint 2016-05-12 17:38:15 +12:00
Robin Bygrave 1d8bb8c800 #700 - Postgres ARRAY and JSON expressions cast Long to ::integer rather than ::bigint 2016-05-12 17:22:40 +12:00
Robin Bygrave ad3b9b2f84 No effective change - sys out for CI server 2016-05-12 17:09:55 +12:00
Robin Bygrave b8ecbd507e #522 - DDL - DB migration diff does not include DDL to add comment 2016-05-12 16:52:22 +12:00
Robin Bygrave 45453bbcd8 No effective change - include the search packages in the classpath scan INFO logging message 2016-05-12 16:17:33 +12:00
Robin Bygrave 44dfab2ace No effective change - sys out for CI server 2016-05-12 14:47:35 +12:00
Robin Bygrave 4ab5cdf841 #698 - History DDL generation for Postgres does not respect non-public schema 2016-05-12 14:32:38 +12:00
Robin Bygrave b384cb4043 #699 - DB Migration not generating sql to alter check constraints 2016-05-12 13:44:30 +12:00
Robin Bygrave 2a323f2256 #697 - Refactor - tidy objectMapper detection in DefaultTypeManager 2016-05-10 13:00:04 +12:00
Robin Bygrave 8cfba1015f No effective change - remove incorrect comment 2016-05-10 11:17:04 +12:00
Robin Bygrave bd6ff5d855 [maven-release-plugin] prepare for next development iteration 2016-05-10 00:04:08 +12:00
Robin Bygrave 7256c3ef90 [maven-release-plugin] prepare release avaje-ebeanorm-7.11.1 2016-05-10 00:03:47 +12:00
Robin Bygrave 17042a9faf #696 - ENH: Add fallback for @DbHstore ... fallback to JSON storage in VARCHAR 2016-05-09 23:24:13 +12:00
Robin Bygrave b197d8a637 #695 - ENH: Add @DbArray for storing scalar types (UUID, Long, String) to Postgres ARRAY type 2016-05-09 22:38:51 +12:00
Robin Bygrave 2bb39b02d0 No effective change - javadoc on Query.setIncludeSoftDeletes() 2016-05-09 10:00:37 +12:00
Robin Bygrave 654e12422d [maven-release-plugin] prepare for next development iteration 2016-05-06 17:22:12 +12:00
Robin Bygrave 82d24b300a [maven-release-plugin] prepare release avaje-ebeanorm-7.10.1 2016-05-06 17:21:50 +12:00
Robin Bygrave f69a22736d Bump pom to 7.10.1 SNAPSHOT 2016-05-06 17:21:02 +12:00
Robin Bygrave 6b19b6410c No effective change - change test to look for sql 2016-05-06 17:15:30 +12:00
Robin Bygrave 7f546afdca No effective change - test await on l2 cache statistics 2016-05-06 17:07:02 +12:00
Robin Bygrave 4e9e11ac34 #668 - ENH: Add ability to register a custom IdGenerator 2016-05-06 17:01:15 +12:00
Robin Bygrave 036092d470 #694 - Refactor - Rename IdGenerator to PlatformIdGenerator ... with a view to support customer Id generators 2016-05-06 14:50:50 +12:00
Robin Bygrave 2b602f6e51 #570 - ENH: Add ability to configure eBean to use true "ilike" expression 2016-05-06 14:26:08 +12:00
Robin Bygrave 2797f6bbcc No effective change - Add test for undo of soft deleted bean 2016-05-06 13:38:09 +12:00
Robin Bygrave e9e1a975f9 No effective change - @DbJsonB use in test 2016-05-06 13:28:26 +12:00
Robin Bygrave 13f7d37e76 #542 - ENH: @DbJson fields are auto serialized and deserialized to specified classes. 2016-05-06 13:20:51 +12:00
Robin Bygrave deb6ce23d7 #693 - ENH: ... support @DbJson with Set<String> and Set<Long> support 2016-05-05 21:34:29 +12:00
Robin Bygrave 2c95d9dc9a #693 - ENH: Add support for mapping @DbJson to list of scalar types like List<String> 2016-05-05 16:36:16 +12:00
Robin Bygrave 8c86976e68 No effective change - variable names 2016-05-05 16:15:25 +12:00
Robin Bygrave c1ca02d871 No effective change - variable names 2016-05-05 16:14:58 +12:00
Robin Bygrave 0508b0254f #692 - MigrationVersion parses version "0.1.1-SNAPSHOT" as "0.1" 2016-05-05 08:31:31 +12:00
Robin Bygrave 45e488cadb Merge remote-tracking branch 'origin/master' 2016-05-04 15:09:24 +12:00
Robin Bygrave 23731072b7 Updates for example running db migration 2016-05-04 12:14:05 +12:00
Robin Bygrave dc230af60b No effective change - add test for explicit deleted = true property use 2016-05-04 10:50:30 +12:00
Rob Bygrave 622258c82c Update ISSUE_TEMPLATE.md 2016-05-04 10:46:04 +12:00
Robin Bygrave dbed34cc51 [maven-release-plugin] prepare for next development iteration 2016-05-02 16:35:23 +12:00
Robin Bygrave b4d49161af [maven-release-plugin] prepare release avaje-ebeanorm-7.9.1 2016-05-02 16:35:04 +12:00
Robin Bygrave 8a68e72305 No effective change - modify test, add l2 cache await 2016-05-02 16:32:08 +12:00
Robin Bygrave 07fe1cde6b #689 - Refactor DB Migration to support "V" prefix 2016-05-02 16:25:27 +12:00
Robin Bygrave 9da5ce01a7 #686 - Trouble with non-standard java.sql.Date values caching in 7.8.1. 2016-04-29 22:22:38 +12:00
Robin Bygrave 5bcfce9cd4 #684 - Refactor - rename @CacheStrategy to @Cache ... require explicit enableQueryCache=true for query cache use 2016-04-29 21:52:50 +12:00
Robin Bygrave a6d276d4d3 #683 - Refactor - rename @CacheTuning to @CacheBeanTuning ... for consistency 2016-04-29 09:48:36 +12:00
Robin Bygrave 5b100e6d37 #682 - Remove deprecated Model.Finder constructors that take Id type ... migrate to ones that don't 2016-04-29 09:28:43 +12:00
Robin Bygrave bf75af85c1 #681 - Remove SqlQuery.cancel() ... migrate to SqlQuery.findEachWhile() and stop while iterating 2016-04-29 09:05:36 +12:00
Robin Bygrave 5cf2d3c39a #680 - Remove deprecated SqlQuery.findFutureList() 2016-04-29 08:49:07 +12:00
Robin Bygrave 840c5f8992 #679 - Remove SqlQuery.setListener() ... migrate to SqlQuery.findEach() or SqlQuery.findEachWhile() 2016-04-29 08:43:30 +12:00
Robin Bygrave f867cd4c01 #678 - Remove SqlQuery.findSet() and SqlQuery.findMap() ... migrate to use SlqQuery.findList() 2016-04-29 08:37:52 +12:00
Robin Bygrave ad17da5b36 No effective change - format 2016-04-28 22:22:04 +12:00
Robin Bygrave 9350155c00 #677 - REFACTOR: Remove unused SqlQuery.setBackgroundFetchAfter() 2016-04-28 22:18:14 +12:00
Robin Bygrave 8a84eaf7a7 #675 - ENH: Add SqlQuery.findEach() and SqlQuery.findEachWhile() methods ... to replace setListener() 2016-04-28 22:15:41 +12:00
Robin Bygrave f0fab77ff7 #670 - Remove @EntityConcurrencyMode ... this is now rather redundant since 4.x changes 2016-04-28 20:26:17 +12:00
Robin Bygrave 41aace9dc4 #669 - Remove @EnumMapping ... migrate to use @DbEnumValue or @EnumValue 2016-04-28 20:22:37 +12:00
Robin Bygrave 7c9d752c3d Merge branch 'master' of github.com:ebean-orm/avaje-ebeanorm 2016-04-28 20:19:22 +12:00
Robin Bygrave 81531b6cda #671 - ENH: Add support for @View and extra-ddl.xml to nicely support entity beans based on views 2016-04-28 20:19:05 +12:00
Rob Bygrave b70f3574d9 Update ISSUE_TEMPLATE.md
Add "some java code" placeholder
2016-04-28 13:22:31 +12:00
Rob Bygrave be214273cc Update README.md 2016-04-28 13:05:17 +12:00
Robin Bygrave 69c2810fbe No effective change - add test for SqlQuery listener 2016-04-28 09:54:17 +12:00
Robin Bygrave 82da81116e Add github issue template 2016-04-28 09:40:05 +12:00
Robin Bygrave 7d5e135f56 [maven-release-plugin] prepare for next development iteration 2016-04-27 08:41:26 +12:00
Robin Bygrave 6b05d2343b [maven-release-plugin] prepare release avaje-ebeanorm-7.8.1 2016-04-27 08:41:06 +12:00
Robin Bygrave fc748ea9c1 #667 - Remove deprecated @SqlSelect ... migrate to use RawSql / RawSqlBuilder 2016-04-27 08:40:00 +12:00
Robin Bygrave 7b8d2a2f9d #664 - Remove reference to @SqlInsert, @SqlUpdate, @SqlDelete from comment 2016-04-27 08:14:49 +12:00
Robin Bygrave f8b5a7f312 #666 - deleteAll(beans) return int , but deleteAll(beanType,ids) return void in EbeanServer 2016-04-27 08:04:43 +12:00
Robin Bygrave ae261d3782 #660 - findPagedList() does not handle raw sql order by 2016-04-26 22:54:34 +12:00
Robin Bygrave d2ae044d1f #665 - Remove deprecated @DocStoreEmbedded ... should migrate to @DocEmbedded 2016-04-26 21:35:57 +12:00
Robin Bygrave 03189ac92a #661 - ENH: Add deletePermanent(beanType, id) and deleteAllPermanent(beanType, ids) ... (basically missing API) 2016-04-26 21:30:52 +12:00
Robin Bygrave 2067568a5e No effective change - migrate test from deprecated method 2016-04-26 21:12:22 +12:00
Robin Bygrave 57417610a6 #663 - Change Postgres default Timestamp type to be "Timestamp with time zone" 2016-04-26 17:06:01 +12:00
Robin Bygrave 4cec878242 #662 - Postgres Timestamp with time zone testing 2016-04-26 16:41:11 +12:00
Robin Bygrave 2e7aec3b3d #662 - Postgres Timestamp with time zone testing - remove extra oracle test code 2016-04-26 10:13:33 +12:00
Robin Bygrave 104dc599e8 #662 - Postgres Timestamp with time zone testing 2016-04-26 10:12:37 +12:00
Robin Bygrave e769abf737 #659 - ENH: Add support for Instant with @WhenCreated @WhenModified 2016-04-22 16:51:30 +12:00
Robin Bygrave b79bb892f7 #636 - ENH: Add DB Migration runner (as alternative to running via FlywayDB etc) 2016-04-22 16:19:09 +12:00
Robin Bygrave 8f93f780fd Bump datasource dependency 2016-04-22 16:18:06 +12:00
Robin Bygrave 158a23a34d No effective change - reformat 2016-04-22 16:05:17 +12:00
Robin Bygrave 523ddbab63 #658 - REFACTOR: Simplify LocalDateTime -> Timestamp conversion, use Timestamp.valueOf() 2016-04-21 20:11:39 +12:00
Robin Bygrave 00d4298065 #656 - Remove remoteInsert(), remoteUpdate() remoteDelete() methods from BeanPersistListener 2016-04-21 12:33:06 +12:00
Robin Bygrave 4eb1aded2d #651 - ENH: Add type support for java.nio.file.Path ... such that it stores the underlying URI as VARCHAR/string 2016-04-21 11:34:33 +12:00
Robin Bygrave 221f5ad879 #651 - ENH: Add type support for java.nio.file.Path ... such that it stores the underlying URI as VARCHAR/string 2016-04-21 11:33:26 +12:00
Robin Bygrave 75e3b9276e #657 - POM - drop dependency on org.springframework.boot and avaje-ebeanorm-cluster 2016-04-21 10:38:26 +12:00
Robin Bygrave 29c51ecb95 #655 - DB Migration should not require running L2 cache (ie. Hazel cast server etc) 2016-04-21 10:33:09 +12:00
Robin Bygrave 8c535ba837 [maven-release-plugin] prepare for next development iteration 2016-04-18 21:01:11 +12:00
Robin Bygrave 11e02710d9 [maven-release-plugin] prepare release avaje-ebeanorm-7.7.1 2016-04-18 21:00:50 +12:00
Robin Bygrave 658ce3c5d3 #653 - Change format of all Timestamp/Date time types to use epoch millis 2016-04-18 12:49:16 +12:00
Robin Bygrave 2de78cd20f #652 - ENH: L2 cache - add @CacheQueryTuning annotation 2016-04-18 09:46:42 +12:00
Robin Bygrave 1b8b05790e #650 - Refactor: Optimise L2 cache entry for serialisation 2016-04-14 11:56:31 +12:00
Robin Bygrave 444b848c22 #648 - Test that does not reproduce this issue 2016-04-13 19:36:26 +12:00
Robin Bygrave 707dda636d #649 - ENH: Add ebean.disableL2Cache=true option ... to globally disable l2 cache 2016-04-13 17:44:37 +12:00
Robin Bygrave e8a979bc9d No effective change - imports 2016-04-13 15:59:39 +12:00
Robin Bygrave 3fb9a7414c #647 - REFACTOR: L2 cache - remove cache warming support (from @CacheStrategy and API) 2016-04-12 23:44:24 +12:00
Robin Bygrave 061652a48e Bump pom to 7.7.1-SNAPSHOT 2016-04-12 23:26:09 +12:00
Robin Bygrave 57b03cf86d #646 - REFACTOR: L2 cache towards remote data grid caches (like Ignite etc) 2016-04-12 23:25:19 +12:00
Robin Bygrave 45dbe3bb9a Merge branch 'master' of github.com:ebean-orm/avaje-ebeanorm 2016-04-12 23:21:32 +12:00
Robin Bygrave 24037eeb73 No effective change - reduce test logging 2016-04-12 23:20:54 +12:00
Robin Bygrave 2c6f637dab #646 - REFACTOR: L2 cache towards remote data grid caches (like Ignite etc) 2016-04-12 23:20:16 +12:00
Robin Bygrave a85f9c4be8 #638 - Ensure natural key cache is updated regardless of bean cache entry aging out 2016-04-11 17:09:06 +12:00
Rob Bygrave 5d9f11a362 Merge pull request #645 from icode/master
review duplicate var
2016-04-08 22:16:43 +12:00
icode 3d484c79a2 review duplicate var 2016-04-08 14:32:13 +08:00
Robin Bygrave 5881047606 [maven-release-plugin] prepare for next development iteration 2016-04-08 15:17:04 +12:00
Robin Bygrave 333eaf08c2 [maven-release-plugin] prepare release avaje-ebeanorm-7.6.1 2016-04-08 15:16:44 +12:00
Robin Bygrave a1ff83e9e4 #643 - NPE on OrmQueryProperties.java:474 2016-04-08 15:15:34 +12:00
Robin Bygrave 640db2267f #642 - ENH: Add support for OneToMany expression isEmpty() / isNotEmpty() ... which is effectively an EXISTS and NOT EXISTS subquery 2016-04-08 13:44:54 +12:00
Robin Bygrave 4059034891 #642 - ENH: Add support for OneToMany expression isEmpty() / isNotEmpty() ... which is effectively an EXISTS and NOT EXISTS subquery 2016-04-08 13:41:43 +12:00
Robin Bygrave c58db0033d No effective change - add more tests for raw use of exists / not exists 2016-04-08 08:28:13 +12:00
Robin Bygrave da90eccc12 #638 - ENH: Add Apache Ignite as L2 cache option 2016-04-08 02:03:02 +12:00
Robin Bygrave 524be4ce55 #641 - ENH: Add EbeanServer.setBeanId(bean, id) ... to make it easy to convert id value to appropriate type and set 2016-04-08 01:15:34 +12:00
Robin Bygrave 649c14644e #640 - ENH: ServerConfig - support get/put arbitrary configuration objects for use by plugins 2016-04-08 00:03:37 +12:00
Robin Bygrave c504256579 No effective change - HashQuery.toString() for l2 query cache log message 2016-04-07 23:59:13 +12:00
Robin Bygrave 97d803e3e0 No effective change - HashQuery.toString() for l2 query cache log message 2016-04-07 21:45:59 +12:00
Robin Bygrave 46bc09a09b No effective change - HashQuery.toString() for l2 query cache log message 2016-04-07 21:45:47 +12:00
Robin Bygrave fe387cf456 #637 - CachedManyIds as serializable (Ignite etc) 2016-04-06 23:43:26 +12:00
Robin Bygrave b4cd66e28c #637 - ServerCacheType 2016-04-06 21:39:39 +12:00
Robin Bygrave 7c11acaf89 #637 - Change SPI for ServerCache, add ServerCacheType to allow different cache construction for query bean and bean cache 2016-04-06 21:38:54 +12:00
Robin Bygrave 7b4d6f2d17 No effective change - code format 2016-04-06 20:37:50 +12:00
Robin Bygrave 8f100f2786 No effective change - code format 2016-04-06 20:36:50 +12:00
Robin Bygrave 6233392548 ENH: Add DB Migration runner (as alternative to running via FlywayDB etc) #636 2016-04-06 15:14:50 +12:00
Robin Bygrave abaa1ff934 #636 - ENH: Add DB Migration runner (as alternative to running via FlywayDB etc) 2016-04-06 14:31:57 +12:00
Robin Bygrave a7b239a1b7 ENH: Add DB Migration runner (as alternative to running via FlywayDB etc) #636 2016-04-06 14:31:20 +12:00
Robin Bygrave e8c0756ee9 Bump pom to 7.6.1-SNAPSHOT 2016-04-01 16:44:36 +13:00
Robin Bygrave e5179432a0 #634 - Refactor internal class path scanning to use avaje-classpath-scanner-api / avaje-classpath-scanner 2016-04-01 16:43:59 +13:00
Robin Bygrave d25123eb23 #633 - Remove deprecated SpiEbeanPlugin (people should have migrated to com.avaje.ebean.plugin.Plugin) 2016-04-01 15:07:49 +13:00
Robin Bygrave 27602c15b9 #632 - ENH: Alter AutoTune such that it saves back to autotune.xml (rename any existing autotune file) 2016-04-01 14:56:35 +13:00
Robin Bygrave bdc81bf6f4 [maven-release-plugin] prepare for next development iteration 2016-03-31 16:03:23 +13:00
Robin Bygrave b9237cb8a8 [maven-release-plugin] prepare release avaje-ebeanorm-7.5.1 2016-03-31 16:03:04 +13:00
Robin Bygrave 99e548db03 Modify pom - include avaje-ebeanorm-cluster by default, version range on slf4j 2016-03-31 16:02:12 +13:00
Robin Bygrave 71499d15e1 Bump pom to 7.5.1-SNAPSHOT 2016-03-31 15:47:04 +13:00
Robin Bygrave c9b0fd708a #631 - With find by id query, and id value type conversion (e.g. String to Long) this does not hit L2 cache 2016-03-31 15:18:33 +13:00
Robin Bygrave 8e43ece490 #630 - ENH: Add support for System property "disableTestProperties" ... to enable disabling the load of test-ebean.properties 2016-03-31 14:09:15 +13:00
Robin Bygrave fb2b8b4cf6 #629 - DefaultServerCache using java 1.7 compare method, drop trim logging from DEBUG to TRACE 2016-03-31 14:05:59 +13:00
Robin Bygrave 33f3920a60 #628 Refactor Clustering - tidy 2016-03-30 16:59:02 +13:00
Robin Bygrave 9a912390d4 #628 - Refactor Clustering - extract ClusterBroadcast implementations (TCP and Multicast) 2016-03-30 16:20:24 +13:00
Robin Bygrave 30a5769973 No effective change - remove http elastic test (as that is all in avaje-ebeanorm-elastic) 2016-03-29 17:00:36 +13:00
Robin Bygrave 084c9ad433 [maven-release-plugin] prepare for next development iteration 2016-03-29 16:39:51 +13:00
Robin Bygrave 84fa373728 WIP update for migration runner 2016-02-10 20:51:55 +13:00
Robin Bygrave 12e6c0b139 Merge branch 'dbmig1' into dbmig2 2016-02-10 16:07:04 +13:00
Robin Bygrave 6f702098bc Update DB Migration runner 2016-02-09 12:55:41 +13:00
Robin Bygrave ad3292b92d WIP - DB Migration runner 2016-02-06 00:17:08 +13:00
1316 changed files with 42384 additions and 31187 deletions
+12
View File
@@ -0,0 +1,12 @@
# editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
spaces_around_operators = true
+19
View File
@@ -0,0 +1,19 @@
GITHUB ISSUES ARE STRICTLY CONTROLLED FOR THIS PROJECT.
Refer to http://ebean-orm.github.io/support for the policies controlling the use of github issues.
Please post issues to the Ebean group https://groups.google.com/forum/#!forum/ebean first.
## Expected behavior
## Actual behavior
### Steps to reproduce
```java
// some java code
```
```console
// some logging output
```
+12 -9
View File
@@ -1,14 +1,17 @@
* [![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
# Need help?
Post questions or issues to the Ebean google group - https://groups.google.com/forum/#!forum/ebean
# Documentation
Goto [https://ebean-orm.github.io/](http://ebean-orm.github.io/ "Ebean ORM's Website")
Ebean ORM
==============
[https://ebean-orm.github.io/](http://ebean-orm.github.io/ "Ebean ORM's Website")
## Maven cental links:
[Maven central - ebean](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.avaje.ebean%22%20AND%20a%3A%22ebean%22 "maven central ebean")
[Maven central - all related projects](http://search.maven.org/#search%7Cga%7C1%7Cebean "maven central all related projects")
[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")
[Maven central - all related projects](http://search.maven.org/#search%7Cga%7C1%7Cavaje-ebeanorm "maven central ebeanorm")
## Current versions
* [![Maven Central : ebean](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebean/ebean/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebean/ebean) - ebean
* [![Maven Central : ebean-agent](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebean/ebean-agent/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebean/ebean-agent) - ebean-agent
* [![Maven Central : ebean-maven-plugin](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebean/ebean-maven-plugin/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebean/ebean-maven-plugin) - ebean-maven-plugin
+59 -73
View File
@@ -3,42 +3,25 @@
<parent>
<groupId>org.avaje</groupId>
<artifactId>avaje-javaparent</artifactId>
<version>1.2</version>
<artifactId>java8-parent</artifactId>
<version>1.1</version>
</parent>
<groupId>org.avaje.ebeanorm</groupId>
<artifactId>avaje-ebeanorm</artifactId>
<version>7.4.1</version>
<groupId>org.avaje.ebean</groupId>
<artifactId>ebean</artifactId>
<version>9.1.2</version>
<packaging>jar</packaging>
<name>avaje-ebeanorm</name>
<name>ebean</name>
<url>http://ebean-orm.github.io/</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<id>rbygrave</id>
<name>Rob Bygrave</name>
<email>robin.bygrave@gmail.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/ebean-orm/avaje-ebeanorm.git</connection>
<developerConnection>scm:git:https://github.com/ebean-orm/avaje-ebeanorm.git</developerConnection>
<url>https://github.com/ebean-orm/avaje-ebeanorm.git</url>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-9.1.2</tag>
</scm>
<dependencies>
@@ -64,27 +47,44 @@
<dependency>
<groupId>org.avaje</groupId>
<artifactId>avaje-datasource</artifactId>
<version>1.1.1</version>
<version>1.1.3</version>
</dependency>
<!--<dependency>-->
<!--<groupId>org.avaje</groupId>-->
<!--<artifactId>avaje-datasource-alert</artifactId>-->
<!--<version>1.1.1</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.avaje</groupId>
<artifactId>avaje-classpath-scanner-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.avaje</groupId>
<artifactId>avaje-classpath-scanner</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.avaje</groupId>
<artifactId>avaje-dbmigration</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
<version>[1.7.1,1.7.99)</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>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.5.3</version>
</dependency>
<!-- Jackson core used internally by Ebean -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.5</version>
</dependency>
<!-- provided scope for JsonNode support -->
@@ -95,13 +95,6 @@
<scope>provided</scope>
</dependency>
<!-- Jackson core used internally by Ebean -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.5</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
@@ -139,6 +132,8 @@
<scope>provided</scope>
</dependency>
<!-- Test scope -->
<!--<dependency>-->
<!--<groupId>oracle</groupId>-->
<!--<artifactId>oracle-jdbc</artifactId>-->
@@ -153,13 +148,6 @@
<!--<scope>test</scope>-->
<!--</dependency>-->
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>2.4.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.avaje</groupId>
<artifactId>avaje-agentloader</artifactId>
@@ -168,9 +156,9 @@
</dependency>
<dependency>
<groupId>org.avaje.ebeanorm</groupId>
<artifactId>avaje-ebeanorm-agent</artifactId>
<version>4.9.2</version>
<groupId>org.avaje.ebean</groupId>
<artifactId>ebean-agent</artifactId>
<version>8.1.1</version>
<scope>test</scope>
</dependency>
@@ -179,7 +167,7 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.189</version>
<version>1.4.192</version>
<scope>provided</scope>
</dependency>
@@ -219,33 +207,29 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.avaje.moduuid</groupId>
<artifactId>avaje-moduuid</artifactId>
<version>1.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- Enhance the meta beans -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.avaje.ebeanorm</groupId>
<artifactId>avaje-ebeanorm-mavenenhancer</artifactId>
<version>4.9.2</version>
<groupId>org.avaje.ebean</groupId>
<artifactId>ebean-maven-plugin</artifactId>
<version>8.1.1</version>
<executions>
<!-- Not going to enhance Model bean -->
<execution>
<id>test</id>
<phase>process-test-classes</phase>
<configuration>
<classSource>target/test-classes</classSource>
<packages>com.avaje.tests.**</packages>
<transformArgs>debug=1</transformArgs>
</configuration>
<goals>
@@ -276,7 +260,8 @@
</systemProperties>
</configuration>
</plugin>
<plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
@@ -286,12 +271,13 @@
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<doctitle>Ebean 7</doctitle>
<doctitle>Ebean 9</doctitle>
<overview>src/main/java/com/avaje/ebean/overview.html</overview>
<source>1.8</source>
<doclet>org.avaje.doclet.PygmentsDoclet</doclet>
@@ -311,7 +297,6 @@
<linksource>true</linksource>
<overview>src/main/java/com/avaje/ebean/overview.html</overview>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
@@ -321,6 +306,7 @@
</execution>
</executions>
</plugin>
</plugins>
</build>
@@ -38,6 +38,11 @@ public interface BeanState {
*/
void setDisableLazyLoad(boolean disableLazyLoading);
/**
* Return true if the bean has lazy loading disabled.
*/
boolean isDisableLazyLoad();
/**
* Set the loaded state of the property given it's name.
*
@@ -115,4 +120,9 @@ public interface BeanState {
* for a fully loaded entity bean.
*/
void setLoaded();
/**
* Reset the bean putting it into NEW state such that a save() results in an insert.
*/
void resetForInsert();
}
@@ -30,7 +30,7 @@ final class DRawSqlColumnsParser {
private ColumnMapping parse() {
ArrayList<ColumnMapping.Column> columns = new ArrayList<ColumnMapping.Column>();
ArrayList<ColumnMapping.Column> columns = new ArrayList<>();
while (pos <= end) {
ColumnMapping.Column c = nextColumnInfo();
columns.add(c);
@@ -47,10 +47,10 @@ final class DRawSqlColumnsParser {
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++) {
if (split[i].trim().length() > 0) {
tmp.add(split[i].trim());
ArrayList<String> tmp = new ArrayList<>(split.length);
for (String aSplit : split) {
if (!aSplit.trim().isEmpty()) {
tmp.add(aSplit.trim());
}
}
split = tmp.toArray(new String[tmp.size()]);
@@ -66,8 +66,8 @@ final class DRawSqlColumnsParser {
if (split.length == 2) {
return new ColumnMapping.Column(indexPos++, split[0], split[1]);
}
// Ok, we now expect/require the AS keyword and it should be the
// second to last word in the colInfo content
// Ok, we now expect/require the AS keyword and it should be the
// second to last word in the colInfo content
if (!split[split.length - 2].equalsIgnoreCase("as")) {
throw new PersistenceException("Expecting AS keyword as second to last word when parsing column " + colInfo);
}
@@ -1,6 +1,7 @@
package com.avaje.ebean;
import com.avaje.ebean.RawSql.Sql;
import com.avaje.ebeaninternal.server.querydefn.SimpleTextParser;
/**
* Parses sql-select queries to try and determine the location where WHERE and
@@ -8,13 +9,13 @@ import com.avaje.ebean.RawSql.Sql;
*/
class DRawSqlParser {
public static final String $_AND_HAVING = "${andHaving}";
private static final String $_AND_HAVING = "${andHaving}";
public static final String $_HAVING = "${having}";
private static final String $_HAVING = "${having}";
public static final String $_AND_WHERE = "${andWhere}";
private static final String $_AND_WHERE = "${andWhere}";
public static final String $_WHERE = "${where}";
private static final String $_WHERE = "${where}";
private final SimpleTextParser textParser;
@@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* Document storage operations.
@@ -205,6 +206,39 @@ public interface DocumentStore {
*/
void createIndex(String indexName, String alias);
/**
* Modify the settings on an index.
* <p>
* For example, this can be used be used to set elasticSearch refresh_interval
* on an index before a bulk update.
* </p>
* <pre>{@code
*
* // refresh_interval -1 ... disable refresh while bulk loading
*
* Map<String,Object> settings = new LinkedHashMap<>();
* settings.put("refresh_interval", "-1");
*
* documentStore.indexSettings("product", settings);
*
* }</pre>
*
* <pre>{@code
*
* // refresh_interval 1s ... restore after bulk loading
*
* Map<String,Object> settings = new LinkedHashMap<>();
* settings.put("refresh_interval", "1s");
*
* documentStore.indexSettings("product", settings);
*
* }</pre>
*
* @param indexName the name of the index to update settings on
* @param settings the settings to set on the index
*/
void indexSettings(String indexName, Map<String, Object> settings);
/**
* Copy the index to a new index.
* <p>
+116 -282
View File
@@ -1,24 +1,21 @@
package com.avaje.ebean;
import com.avaje.ebean.cache.ServerCacheManager;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.text.csv.CsvReader;
import com.avaje.ebean.text.json.JsonContext;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.avaje.ebean.annotation.CacheStrategy;
import com.avaje.ebean.cache.ServerCacheManager;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.text.csv.CsvReader;
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
@@ -135,13 +132,13 @@ public final class Ebean {
/**
* Cache for fast concurrent read access.
*/
private final ConcurrentHashMap<String, EbeanServer> concMap = new ConcurrentHashMap<String, EbeanServer>();
private final ConcurrentHashMap<String, EbeanServer> concMap = new ConcurrentHashMap<>();
/**
* Cache for synchronized read, creation and put. Protected by the monitor
* object.
*/
private final HashMap<String, EbeanServer> syncMap = new HashMap<String, EbeanServer>();
private final HashMap<String, EbeanServer> syncMap = new HashMap<>();
private final Object monitor = new Object();
@@ -164,7 +161,7 @@ public final class Ebean {
// look to see if there is a default server defined
String defaultName = PrimaryServer.getDefaultServerName();
logger.debug("defaultName:" + defaultName);
if (defaultName != null && defaultName.trim().length() > 0) {
if (defaultName != null && !defaultName.trim().isEmpty()) {
defaultServer = getWithCreate(defaultName.trim());
}
}
@@ -185,7 +182,7 @@ public final class Ebean {
}
private EbeanServer get(String name) {
if (name == null || name.length() == 0) {
if (name == null || name.isEmpty()) {
return defaultServer;
}
// non-synchronized read
@@ -502,6 +499,13 @@ public final class Ebean {
serverMgr.getDefaultServer().endTransaction();
}
/**
* Mark the current transaction as rollback only.
*/
public static void setRollbackOnly() {
serverMgr.getDefaultServer().currentTransaction().setRollbackOnly();
}
/**
* Return a map of the differences between two objects of the same type.
* <p>
@@ -642,58 +646,6 @@ public final class Ebean {
return serverMgr.getDefaultServer().saveAll(beans);
}
/**
* Delete the associations (from the intersection table) of a ManyToMany given
* the owner bean and the propertyName of the ManyToMany collection.
* <p>
* 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).
*/
public static int deleteManyToManyAssociations(Object ownerBean, String propertyName) {
return serverMgr.getDefaultServer().deleteManyToManyAssociations(ownerBean, propertyName);
}
/**
* Save the associations of a ManyToMany given the owner bean and the
* propertyName of the ManyToMany collection.
* <p>
* Typically the saving of these associations (inserting into the intersection
* table) occurs automatically when persisting a ManyToMany. This provides a
* way to invoke those insertions directly.
* </p>
* <p>
* You can use this when the collection is new and in this case all the
* entries in the collection are treated as additions are result in inserts
* into the intersection table.
* </p>
*/
public static void saveManyToManyAssociations(Object ownerBean, String propertyName) {
serverMgr.getDefaultServer().saveManyToManyAssociations(ownerBean, propertyName);
}
/**
* Save the associated collection or bean given the property name.
* <p>
* This is similar to performing a save cascade on a specific property
* manually/programmatically.
* </p>
* <p>
* Note that you can turn on/off cascading for a transaction via
* {@link Transaction#setPersistCascade(boolean)}
* </p>
*
* @param ownerBean
* the bean instance holding the property we want to save
* @param propertyName
* the property we want to save
*/
public static void saveAssociation(Object ownerBean, String propertyName) {
serverMgr.getDefaultServer().saveAssociation(ownerBean, propertyName);
}
/**
* Delete the bean.
* <p>
@@ -731,11 +683,25 @@ public final class Ebean {
return serverMgr.getDefaultServer().delete(beanType, id);
}
/**
* Delete permanent the bean given its type and id.
*/
public static int deletePermanent(Class<?> beanType, Object id) {
return serverMgr.getDefaultServer().deletePermanent(beanType, id);
}
/**
* Delete several beans given their type and id values.
*/
public static void deleteAll(Class<?> beanType, Collection<?> ids) {
serverMgr.getDefaultServer().deleteAll(beanType, ids);
public static int deleteAll(Class<?> beanType, Collection<?> ids) {
return serverMgr.getDefaultServer().deleteAll(beanType, ids);
}
/**
* Delete permanent several beans given their type and id values.
*/
public static int deleteAllPermanent(Class<?> beanType, Collection<?> ids) {
return serverMgr.getDefaultServer().deleteAllPermanent(beanType, ids);
}
/**
@@ -921,19 +887,6 @@ public final class Ebean {
return serverMgr.getDefaultServer().createSqlQuery(sql);
}
/**
* Create a named sql query.
* <p>
* The query statement will be defined in a deployment orm xml file.
* </p>
*
* @param namedQuery
* the name of the query
*/
public static SqlQuery createNamedSqlQuery(String namedQuery) {
return serverMgr.getDefaultServer().createNamedSqlQuery(namedQuery);
}
/**
* Create a sql update for executing native dml statements.
* <p>
@@ -943,10 +896,6 @@ public final class Ebean {
* <p>
* See {@link SqlUpdate} for example usage.
* </p>
* <p>
* Where possible it would be expected practice to put the statement in a orm
* xml file (named update) and use {@link #createNamedSqlUpdate(String)} .
* </p>
*/
public static SqlUpdate createSqlUpdate(String sql) {
return serverMgr.getDefaultServer().createSqlUpdate(sql);
@@ -961,144 +910,6 @@ public final class Ebean {
return serverMgr.getDefaultServer().createCallableSql(sql);
}
/**
* Create a named sql update.
* <p>
* The statement (an Insert Update or Delete statement) will be defined in a
* deployment orm xml file.
* </p>
*
* <pre>{@code
*
* // Use a namedQuery
* UpdateSql update = Ebean.createNamedSqlUpdate("update.topic.count");
*
* update.setParameter("count", 1);
* update.setParameter("topicId", 50);
*
* int modifiedCount = update.execute();
*
* }</pre>
*/
public static SqlUpdate createNamedSqlUpdate(String namedQuery) {
return serverMgr.getDefaultServer().createNamedSqlUpdate(namedQuery);
}
/**
* Return a named Query that will have defined fetch paths, predicates etc.
* <p>
* The query is created from a statement that will be defined in a deployment
* orm xml file or NamedQuery annotations. The query will typically already
* define fetch paths, predicates, order by clauses etc so often you will just
* need to bind required parameters and then execute the query.
* </p>
*
* <pre>{@code
*
* // example
* Query<Order> query = Ebean.createNamedQuery(Order.class, "new.for.customer");
* query.setParameter("customerId", 23);
* List<Order> newOrders = query.findList();
*
* }</pre>
*
* @param beanType
* the class of entity to be fetched
* @param namedQuery
* the name of the query
*/
public static <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
return serverMgr.getDefaultServer().createNamedQuery(beanType, namedQuery);
}
/**
* Create a query using the query language.
* <p>
* Note that you are allowed to add additional clauses using where() as well
* as use fetch() and setOrderBy() after the query has been created.
* </p>
* <p>
* Note that this method signature used to map to named queries and that has
* moved to {@link #createNamedQuery(Class, String)}.
* </p>
*
* <pre>{@code
*
* String q = "find order fetch details where status = :st";
*
* List<Order> newOrders = Ebean.>findOrder.class, q)
* .setParameter("st", Order.Status.NEW)
* .findList();
*
* }</pre>
*
* @param query
* the object query
*/
public static <T> Query<T> createQuery(Class<T> beanType, String query) {
return serverMgr.getDefaultServer().createQuery(beanType, query);
}
/**
* Create a named orm update. The update statement is specified via the
* NamedUpdate annotation.
* <p>
* The orm update differs from the SqlUpdate in that it uses the bean name and
* bean property names rather than table and column names.
* </p>
* <p>
* Note that named update statements can be specified in raw sql (with column
* and table names) or using bean name and bean property names. This can be
* specified with the isSql flag.
* </p>
* <p>
* Example named updates:
* </p>
*
* <pre>{@code
* package app.data;
*
* import ...
*
* @NamedUpdates(value = {
* @NamedUpdate( name = "setTitle",
* isSql = false,
* notifyCache = false,
* update = "update topic set title = :title, postCount = :postCount where id = :id"),
* @NamedUpdate( name = "setPostCount",
* notifyCache = false,
* update = "update f_topic set post_count = :postCount where id = :id"),
* @NamedUpdate( name = "incrementPostCount",
* notifyCache = false,
* isSql = false,
* update = "update Topic set postCount = postCount + 1 where id = :id") })
* @Entity
* @Table(name = "f_topic")
* public class Topic { ...
*
* }</pre>
*
* <p>
* Example using a named update:
* </p>
*
* <pre>{@code
*
* Update<Topic> update = Ebean.createNamedUpdate(Topic.class, "setPostCount");
* update.setParameter("postCount", 10);
* update.setParameter("id", 3);
*
* int rows = update.execute();
* System.out.println("rows updated: " + rows);
*
* }</pre>
*/
public static <T> Update<T> createNamedUpdate(Class<T> beanType, String namedUpdate) {
return serverMgr.getDefaultServer().createNamedUpdate(beanType, namedUpdate);
}
/**
* Create a orm update where you will supply the insert/update or delete
* statement (rather than using a named one that is already defined using the
@@ -1141,6 +952,21 @@ public final class Ebean {
return serverMgr.getDefaultServer().createCsvReader(beanType);
}
/**
* Create a named query.
* <p>
* For RawSql the named query is expected to be in ebean.xml.
* </p>
*
* @param beanType The type of entity bean
* @param namedQuery The name of the query
* @param <T> The type of entity bean
* @return The query
*/
public static <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
return serverMgr.getDefaultServer().createNamedQuery(beanType, namedQuery);
}
/**
* Create a query for a type of entity bean.
* <p>
@@ -1156,39 +982,7 @@ public final class Ebean {
* {@link Query#findSet()} etc will execute against the same EbeanServer from
* which is was created.
* </p>
*
* <pre>{@code
* // Find order 2 additionally fetching the customer, details and details.product
* // name.
*
* Order order = Ebean.find(Order.class)
* .fetch("customer")
* .fetch("details")
* .fetch("detail.product", "name")
* .setId(2)
* .findUnique();
*
* // Find order 2 additionally fetching the customer, details and details.product
* // name.
* // Note: same query as above but using the query language
* // Note: using a named query would be preferred practice
*
* String oql = "find order fetch customer fetch details fetch details.product (name) where id = :orderId ";
*
* Query<Order> query = Ebean.find(Order.class);
* query.setQuery(oql);
* query.setParameter("orderId", 2);
*
* Order order = query.findUnique();
*
* // Using a named query
* Query<Order> query = Ebean.find(Order.class, "with.details");
* query.setParameter("orderId", 2);
*
* Order order = query.findUnique();
*
* }</pre>
*
*
* @param beanType
* the class of entity to be fetched
* @return A ORM Query object for this beanType
@@ -1198,6 +992,47 @@ public final class Ebean {
return serverMgr.getDefaultServer().createQuery(beanType);
}
/**
* Parse the Ebean query language statement returning the query which can then
* be modified (add expressions, change order by clause, change maxRows, change
* fetch and select paths etc).
*
* <h3>Example</h3>
*
* <pre>{@code
*
*
* // Find order additionally fetching the customer, details and details.product name.
*
* String eql = "fetch customer fetch details fetch details.product (name) where id = :orderId ";
*
* Query<Order> query = Ebean.createQuery(Order.class, eql);
* query.setParameter("orderId", 2);
*
* Order order = query.findUnique();
*
* // This is the same as:
*
* Order order = Ebean.find(Order.class)
* .fetch("customer")
* .fetch("details")
* .fetch("detail.product", "name")
* .setId(2)
* .findUnique();
*
* }</pre>
*
* @param beanType The type of bean to fetch
* @param eql The Ebean query
* @param <T> The type of the entity bean
*
* @return The query with expressions defined as per the parsed query statement
*/
public static <T> Query<T> createQuery(Class<T> beanType, String eql) {
return serverMgr.getDefaultServer().createQuery(beanType, eql);
}
/**
* Create a query for a type of entity bean.
* <p>
@@ -1215,6 +1050,28 @@ public final class Ebean {
return serverMgr.getDefaultServer().find(beanType);
}
/**
* Create an Update query to perform a bulk update.
* <p>
* <pre>{@code
*
* int rows = Ebean.update(Customer.class)
* .set("status", Customer.Status.ACTIVE)
* .set("updtime", new Timestamp(System.currentTimeMillis()))
* .where()
* .gt("id", 1000)
* .update();
*
* }</pre>
*
* @param beanType The type of entity bean to update
* @param <T> The type of entity bean
* @return The update query to use
*/
public static <T> UpdateQuery<T> update(Class<T> beanType) {
return serverMgr.getDefaultServer().update(beanType);
}
/**
* Create a filter for sorting and filtering lists of entities locally without
* going back to the database.
@@ -1484,29 +1341,6 @@ public final class Ebean {
return serverMgr.getDefaultServer().getBackgroundExecutor();
}
/**
* Run the cache warming queries on all bean types that have one defined for
* the default/primary EbeanServer.
* <p>
* A cache warming query can be defined via {@link CacheStrategy}.
* </p>
*/
public static void runCacheWarming() {
serverMgr.getDefaultServer().runCacheWarming();
}
/**
* Run the cache warming query for a specific bean type for the
* default/primary EbeanServer.
* <p>
* A cache warming query can be defined via {@link CacheStrategy}.
* </p>
*/
public static void runCacheWarming(Class<?> beanType) {
serverMgr.getDefaultServer().runCacheWarming(beanType);
}
/**
* Return the JsonContext for reading/writing JSON.
*/
File diff suppressed because it is too large Load Diff
@@ -133,7 +133,7 @@ public class EbeanServerFactory {
/**
* Create the container instance using the configuration.
*/
private static SpiContainer createContainer(ContainerConfig containerConfig) {
protected static SpiContainer createContainer(ContainerConfig containerConfig) {
String implClassName = System.getProperty("ebean.container", DEFAULT_CONTAINER);
+14
View File
@@ -209,6 +209,20 @@ public class Expr {
return Ebean.getExpressionFactory().icontains(propertyName, value);
}
/**
* For collection properties that are empty (have not existing elements).
*/
public static Expression isEmpty(String propertyName) {
return Ebean.getExpressionFactory().isEmpty(propertyName);
}
/**
* For collection properties that are not empty (have existing elements).
*/
public static Expression isNotEmpty(String propertyName) {
return Ebean.getExpressionFactory().isNotEmpty(propertyName);
}
/**
* In - property has a value in the array of values.
*/
@@ -87,6 +87,38 @@ public interface ExpressionFactory {
*/
Expression jsonBetween(String propertyName, String path, Object lowerValue, Object upperValue);
/**
* Array contains all the given values.
* <p>
* Array support is effectively limited to Postgres at this time.
* </p>
*/
Expression arrayContains(String propertyName, Object... values);
/**
* Array does not contain the given values.
* <p>
* Array support is effectively limited to Postgres at this time.
* </p>
*/
Expression arrayNotContains(String propertyName, Object... values);
/**
* Array is empty - for the given array property.
* <p>
* Array support is effectively limited to Postgres at this time.
* </p>
*/
Expression arrayIsEmpty(String propertyName);
/**
* Array is not empty - for the given array property.
* <p>
* Array support is effectively limited to Postgres at this time.
* </p>
*/
Expression arrayIsNotEmpty(String propertyName);
/**
* Equal To - property equal to the given value.
*/
@@ -103,6 +135,11 @@ public interface ExpressionFactory {
*/
Expression ieq(String propertyName, String value);
/**
* Case Insensitive Equal To that allows for named parameter use.
*/
Expression ieqObject(String propertyName, Object value);
/**
* Between - property between the two given values.
*/
@@ -160,6 +197,11 @@ public interface ExpressionFactory {
*/
ExampleExpression exampleLike(Object example, boolean caseInsensitive, LikeType likeType);
/**
* Like with support for named parameters.
*/
Expression like(String propertyName, Object value, boolean caseInsensitive, LikeType likeType);
/**
* Like - property like value where the value contains the SQL wild card
* characters % (percentage) and _ (underscore).
@@ -246,6 +288,16 @@ public interface ExpressionFactory {
*/
Expression notExists(Query<?> subQuery);
/**
* Is empty expression for collection properties.
*/
Expression isEmpty(String propertyName);
/**
* Is not empty expression for collection properties.
*/
Expression isNotEmpty(String propertyName);
/**
* Id Equal to - ID property is equal to the value.
*/
+130 -68
View File
@@ -31,7 +31,7 @@ import java.util.Set;
* more methods than you would initially expect (the ones duplicated from
* Query).
* </p>
*
*
* @see Query#where()
*/
public interface ExpressionList<T> {
@@ -83,14 +83,14 @@ public interface ExpressionList<T> {
/**
* Add an orderBy clause to the query.
*
*
* @see Query#orderBy(String)
*/
Query<T> orderBy(String orderBy);
/**
* Add an orderBy clause to the query.
*
*
* @see Query#orderBy(String)
*/
Query<T> setOrderBy(String orderBy);
@@ -116,12 +116,6 @@ public interface ExpressionList<T> {
*/
Query<T> asDraft();
/**
* Deprecated in favour of setIncludeSoftDeletes().
*/
@Deprecated
Query<T> includeSoftDeletes();
/**
* Execute the query including soft deleted rows.
*/
@@ -135,13 +129,21 @@ public interface ExpressionList<T> {
* optimal depending on the database platform.
* </p>
*
* @return the number of beans/rows that were deleted.
* @return the number of rows that were deleted.
*/
int delete();
/**
* Execute as a update query.
*
* @return the number of rows that were updated.
* @see UpdateQuery
*/
int update();
/**
* Execute the query iterating over the results.
*
*
* @see Query#findIterate()
*/
QueryIterator<T> findIterate();
@@ -163,17 +165,17 @@ public interface ExpressionList<T> {
/**
* Execute the query returning a list.
*
*
* @see Query#findList()
*/
List<T> findList();
/**
* Execute the query returning the list of Id's.
*
*
* @see Query#findIds()
*/
List<Object> findIds();
<A> List<A> findIds();
/**
* Return the count of entities this query should return.
@@ -181,26 +183,53 @@ public interface ExpressionList<T> {
* This is the number of 'top level' or 'root level' entities.
* </p>
*/
int findRowCount();
int findCount();
/**
* Execute the query returning a set.
*
*
* @see Query#findSet()
*/
Set<T> findSet();
/**
* Execute the query returning a map.
*
*
* @see Query#findMap()
*/
Map<?, T> findMap();
<K> Map<K, T> findMap();
/**
* Return a typed map specifying the key property and type.
* Execute the query returning a list of values for a single property.
*
* <h3>Example 1:</h3>
* <pre>{@code
*
* List<String> names =
* Ebean.find(Customer.class)
* .select("name")
* .orderBy().asc("name")
* .findSingleAttributeList();
*
* }</pre>
*
* <h3>Example 2:</h3>
* <pre>{@code
*
* List<String> names =
* Ebean.find(Customer.class)
* .setDistinct(true)
* .select("name")
* .where().eq("status", Customer.Status.NEW)
* .orderBy().asc("name")
* .setMaxRows(100)
* .findSingleAttributeList();
*
* }</pre>
*
* @return the list of values for the selected property
*/
<K> Map<K, T> findMap(String keyProperty, Class<K> keyType);
<A> List<A> findSingleAttributeList();
/**
* Execute the query returning a single bean or null (if no matching
@@ -224,10 +253,10 @@ public interface ExpressionList<T> {
* execution status (isDone etc) and get the value (with or without a
* timeout).
* </p>
*
*
* @return a Future object for the row count query
*/
FutureRowCount<T> findFutureRowCount();
FutureRowCount<T> findFutureCount();
/**
* Execute find Id's query in a background thread.
@@ -236,7 +265,7 @@ public interface ExpressionList<T> {
* execution status (isDone etc) and get the value (with or without a
* timeout).
* </p>
*
*
* @return a Future object for the list of Id's
*/
FutureIds<T> findFutureIds();
@@ -248,32 +277,11 @@ public interface ExpressionList<T> {
* execution status (isDone etc) and get the value (with or without a
* timeout).
* </p>
*
*
* @return a Future object for the list result of the query
*/
FutureList<T> findFutureList();
/**
* 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
* {@link Query#findFutureRowCount()} to determine total row count, total page count etc.
* </p>
* <p>
* Internally this works using {@link Query#setFirstRow(int)} and {@link Query#setMaxRows(int)} on
* the query. This translates into SQL that uses limit offset, rownum or row_number
* function to limit the result set.
* </p>
*
* @param pageIndex
* The zero based index of the page.
* @param pageSize
* The number of beans to return per page.
* @return The PagedList
*/
PagedList<T> findPagedList(int pageIndex, int pageSize);
/**
* Return a PagedList for this query using firstRow and maxRows.
* <p>
@@ -332,7 +340,7 @@ public interface ExpressionList<T> {
/**
* Specify specific properties to fetch on the main/root bean (aka partial
* object).
*
*
* @see Query#select(String)
*/
Query<T> select(String properties);
@@ -357,28 +365,28 @@ public interface ExpressionList<T> {
/**
* Set the first row to fetch.
*
*
* @see Query#setFirstRow(int)
*/
Query<T> setFirstRow(int firstRow);
/**
* Set the maximum number of rows to fetch.
*
*
* @see Query#setMaxRows(int)
*/
Query<T> setMaxRows(int maxRows);
/**
* Set the name of the property which values become the key of a map.
*
*
* @see Query#setMapKey(String)
*/
Query<T> setMapKey(String mapKey);
/**
* Set to true to use the query for executing this query.
*
*
* @see Query#setUseCache(boolean)
*/
Query<T> setUseCache(boolean useCache);
@@ -639,7 +647,7 @@ public interface ExpressionList<T> {
* To get control over the options you can create an ExampleExpression and set
* those options such as case insensitive etc.
* </p>
*
*
* <pre>{@code
*
* // create an example bean and set the properties
@@ -647,26 +655,26 @@ public interface ExpressionList<T> {
* Customer example = new Customer();
* 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("id", 2).findList();
*
*
* }</pre>
*
*
* Similarly you can create an ExampleExpression
*
*
* <pre>{@code
*
* Customer example = new Customer();
* example.setName("Rob%");
* example.setNotes("%something%");
*
*
* // create a ExampleExpression with more control
* ExampleExpression qbe = new ExampleExpression(example, true, LikeType.EQUAL_TO).includeZeros();
*
*
* List<Customer> list = Ebean.find(Customer.class).where().add(qbe).findList();
*
* }</pre>
@@ -754,11 +762,21 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> notIn(String propertyName, Query<?> subQuery);
/**
* Is empty expression for collection properties.
*/
ExpressionList<T> isEmpty(String propertyName);
/**
* Is not empty expression for collection properties.
*/
ExpressionList<T> isNotEmpty(String propertyName);
/**
* Exists expression
*/
ExpressionList<T> exists(Query<?> subQuery);
/**
* Not exists expression
*/
@@ -785,12 +803,41 @@ public interface ExpressionList<T> {
* Expression where all the property names in the map are equal to the
* corresponding value.
* </p>
*
*
* @param propertyMap
* a map keyed by property names.
*/
ExpressionList<T> allEq(Map<String, Object> propertyMap);
/**
* Array property contains entries with the given values.
*/
ExpressionList<T> arrayContains(String propertyName, Object... values);
/**
* Array does not contain the given values.
* <p>
* Array support is effectively limited to Postgres at this time.
* </p>
*/
ExpressionList<T> arrayNotContains(String propertyName, Object... values);
/**
* Array is empty - for the given array property.
* <p>
* Array support is effectively limited to Postgres at this time.
* </p>
*/
ExpressionList<T> arrayIsEmpty(String propertyName);
/**
* Array is not empty - for the given array property.
* <p>
* Array support is effectively limited to Postgres at this time.
* </p>
*/
ExpressionList<T> arrayIsNotEmpty(String propertyName);
/**
* Add raw expression with a single parameter.
* <p>
@@ -906,7 +953,7 @@ public interface ExpressionList<T> {
* This is exactly the same as conjunction();
* </p>
* <p>
* Use endJunction() to end the AND junction.
* Use endAnd() or endJunction() to end the AND junction.
* </p>
* <p>
* Note that a where() clause defaults to an AND junction so
@@ -924,11 +971,11 @@ public interface ExpressionList<T> {
* .and() // nested and
* .startsWith("name", "r")
* .eq("anniversary", onAfter)
* .endJunction() // end AND junction
* .endAnd()
* .and()
* .eq("status", Customer.Status.ACTIVE)
* .gt("id", 0)
* .endJunction() // end AND junction
* .endAnd()
* .orderBy().asc("name")
* .findList();
* }</pre>
@@ -940,7 +987,7 @@ public interface ExpressionList<T> {
* This is exactly the same as disjunction();
*
* <p>
* Use endJunction() to end the OR junction.
* Use endOr() or endJunction() to end the OR junction.
* </p>
*
* <pre>{@code
@@ -954,11 +1001,11 @@ public interface ExpressionList<T> {
* .and()
* .startsWith("name", "r")
* .eq("anniversary", onAfter)
* .endJunction() // end AND junction
* .endAnd()
* .and()
* .eq("status", Customer.Status.ACTIVE)
* .gt("id", 0)
* .endJunction() // end AND junction
* .endAnd()
* .orderBy().asc("name")
* .findList();
*
@@ -969,7 +1016,7 @@ public interface ExpressionList<T> {
/**
* Return a list of expressions that will be wrapped by NOT.
* <p>
* Use endJunction() to end expressions being added to the
* Use endNot() or endJunction() to end expressions being added to the
* NOT expression list.
* </p>
*
@@ -979,7 +1026,7 @@ public interface ExpressionList<T> {
* .not()
* .gt("id", 1)
* .eq("anniversary", onAfter)
* .endJunction() // end the not expressions
* .endNot()
*
* }</pre>
*
@@ -993,7 +1040,7 @@ public interface ExpressionList<T> {
* .not()
* .gt("id", 1)
* .eq("anniversary", onAfter)
* .endJunction() // end the not expressions
* .endNot()
* .orderBy()
* .asc("name")
* .findList();
@@ -1066,4 +1113,19 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> endJunction();
/**
* End a AND junction - synonym for endJunction().
*/
ExpressionList<T> endAnd();
/**
* End a AND junction - synonym for endJunction().
*/
ExpressionList<T> endOr();
/**
* End a NOT junction - synonym for endJunction().
*/
ExpressionList<T> endNot();
}
@@ -29,8 +29,7 @@ import java.io.Serializable;
* // Find Orders join details using a single SQL query
* }</pre>
* <p>
* Example: Using a "query join" instead of a "fetch join" we instead use 2 SQL
* queries
* Example: Using a "query join" instead of a "fetch join" we instead use 2 SQL queries
* </p>
*
* <pre>{@code
@@ -117,7 +116,7 @@ import java.io.Serializable;
* <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.contacts","contactName, phone, email")
* .fetch("customer.shippingAddress")
* .where().eq("status",Order.Status.NEW)
* .findList();
@@ -125,12 +124,7 @@ import java.io.Serializable;
* // query 1) find order where status = Order.Status.NEW
* //
* // .. if lazy loading of customers is invoked
* // .. use a batch size of 5 to load the customers
*
* find customer (name)
* fetch customer.contacts (contactName, phone, email)
* fetch customer.shippingAddress (*)
* where id in (?,?,?,?,?)
* // .. use a batch size of 5 to load the customers
*
* }</pre>
*
@@ -9,8 +9,6 @@ import java.util.concurrent.Future;
* It extends the java.util.concurrent.Future with the ability to get the Id's
* while the query is still executing in the background.
* </p>
*
* @author rbygrave
*/
public interface FutureIds<T> extends Future<List<Object>> {
@@ -19,16 +17,4 @@ public interface FutureIds<T> extends Future<List<Object>> {
*/
Query<T> getQuery();
/**
* Return the list of Id's which could be partially populated.
* <p>
* That is the query getting the id's could still be running and adding id's
* to this list.
* </p>
* <p>
* To get the list of Id's ensuring the query has finished use the
* {@link Future#get()} method instead of this one.
* </p>
*/
List<Object> getPartialIds();
}
@@ -9,6 +9,7 @@ import java.util.concurrent.Future;
* It extends the java.util.concurrent.Future.
* </p>
*
* @param <T> the BeanType
* @author rbygrave
*/
public interface FutureRowCount<T> extends Future<Integer> {
+26 -11
View File
@@ -59,11 +59,11 @@ package com.avaje.ebean;
* .and()
* .startsWith("name", "r")
* .eq("anniversary", onAfter)
* .endJunction()
* .endAnd()
* .and()
* .eq("status", Customer.Status.ACTIVE)
* .gt("id", 0)
* .endJunction()
* .endAnd()
* .order().asc("name");
*
* q.findList();
@@ -84,39 +84,46 @@ public interface Junction<T> extends Expression, ExpressionList<T> {
/**
* AND group.
*/
AND(" and ", ""),
AND(" and ", "", false),
/**
* OR group.
*/
OR(" or ", ""),
OR(" or ", "", false),
/**
* NOT group.
*/
NOT(" and ", "not "),
NOT(" and ", "not ", false),
/**
* FILTER group (for internal use only).
*/
FILTER("filter", "", true),
/**
* Text search AND group.
*/
MUST("must", ""),
MUST("must", "", true),
/**
* Text search NOT group.
*/
MUST_NOT("must_not", ""),
MUST_NOT("must_not", "", true),
/**
* Text search OR group.
*/
SHOULD("should", "");
SHOULD("should", "", true);
String prefix;
String literal;
private String prefix;
private String literal;
private boolean text;
Type(String literal, String prefix) {
Type(String literal, String prefix, boolean text) {
this.literal = literal;
this.prefix = prefix;
this.text = text;
}
/**
@@ -132,6 +139,14 @@ public interface Junction<T> extends Expression, ExpressionList<T> {
public String prefix() {
return prefix;
}
/**
* Return true if this is a text type.
*/
public boolean isText() {
return text;
}
}
}
+25 -60
View File
@@ -362,29 +362,6 @@ public abstract class Model {
super(serverName, type);
}
/**
* Please migrate to use {@link Find} or constructor <code>Finder(Class)</code> that
* does not have the idType parameter.
* <p/>
* Create with the type of the ID property and entity bean and specific server name.
*
* @deprecated
*/
public Finder(Class<I> idType, Class<T> type) {
super(null, type);
}
/**
* Please migrate to use the constructor <code>Finder(String, Class)</code> that
* does not have the idType parameter.
* <p/>
* Create with the type of the ID property and entity bean and specific server name.
*
* @deprecated
*/
public Finder(String serverName, Class<I> idType, Class<T> type) {
super(serverName, type);
}
}
/**
@@ -518,7 +495,7 @@ public abstract class Model {
/**
* Return typically a different EbeanServer to the default.
* <p>
* This is equivilent to {@link Ebean#getServer(String)}
* This is equivalent to {@link Ebean#getServer(String)}
*
* @param server
* The name of the EbeanServer. If this is null then the default EbeanServer is
@@ -535,7 +512,7 @@ public abstract class Model {
* Create and return a new Finder for a different server.
*/
public Finder<I, T> on(String server) {
return new Finder<I, T>(server, type);
return new Finder<>(server, type);
}
/**
@@ -621,7 +598,7 @@ public abstract class Model {
* <p>
* Equivalent to {@link Query#findIds()}
*/
public List<Object> findIds() {
public <A> List<A> findIds() {
return query().findIds();
}
@@ -683,46 +660,43 @@ public abstract class Model {
* <p>
* Equivalent to {@link Query#findMap()}
*/
public Map<?, T> findMap() {
public <K> Map<K, T> findMap() {
return query().findMap();
}
/**
* Executes the query and returns the results as a map of the objects specifying the map key
* property.
* <p>
* Equivalent to {@link Query#findMap(String, Class)}
*/
public <K> Map<K, T> findMap(String keyProperty, Class<K> keyType) {
return query().findMap(keyProperty, keyType);
}
/**
* Return a PagedList of all entities of the given type (use where() to specify predicates as
* needed).
* <p>
* Equivalent to {@link Query#findPagedList(int, int)}
*/
public PagedList<T> findPagedList(int pageIndex, int pageSize) {
return query().findPagedList(pageIndex, pageSize);
}
/**
* Executes a find row count query in a background thread.
* <p>
* Equivalent to {@link Query#findFutureRowCount()}
* Equivalent to {@link Query#findFutureCount()}
*/
public FutureRowCount<T> findFutureCount() {
return query().findFutureCount();
}
/**
* Deprecated in favor of findFutureCount().
* <p>
* Equivalent to {@link Query#findFutureCount()}
*/
public FutureRowCount<T> findFutureRowCount() {
return query().findFutureRowCount();
return query().findFutureCount();
}
/**
* Returns the total number of entities for this type. *
* <p>
* Equivalent to {@link Query#findRowCount()}
* Equivalent to {@link Query#findCount()}
*/
public int findCount() {
return query().findCount();
}
/**
* Deprecated in favor of findCount().
* @deprecated
*/
public int findRowCount() {
return query().findRowCount();
return query().findCount();
}
/**
@@ -866,15 +840,6 @@ public abstract class Model {
return query().setId(id);
}
/**
* Create and return a new query using the OQL.
* <p>
* Equivalent to {@link EbeanServer#createQuery(Class, String)}
*/
public Query<T> setQuery(String oql) {
return db().createQuery(type, oql);
}
/**
* Create and return a new query based on the <code>RawSql</code>.
* <p>
+73 -36
View File
@@ -28,9 +28,9 @@ public final class OrderBy<T> implements Serializable {
* Create an empty OrderBy with no associated query.
*/
public OrderBy() {
this.list = new ArrayList<Property>(3);
this.list = new ArrayList<>(3);
}
private OrderBy(List<Property> list) {
this.list = 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>(3);
this.list = new ArrayList<>(3);
parse(orderByClause);
}
@@ -60,8 +60,8 @@ public final class OrderBy<T> implements Serializable {
* Reverse the ascending/descending order on all the properties.
*/
public void reverse() {
for (int i = 0; i < list.size(); i++) {
list.get(i).reverse();
for (Property aList : list) {
aList.reverse();
}
}
@@ -88,8 +88,8 @@ public final class OrderBy<T> implements Serializable {
*/
public boolean containsProperty(String propertyName) {
for (int i = 0; i < list.size(); i++) {
if (propertyName.equals(list.get(i).getProperty())) {
for (Property aList : list) {
if (propertyName.equals(aList.getProperty())) {
return true;
}
}
@@ -100,13 +100,13 @@ public final class OrderBy<T> implements Serializable {
* Return a copy of this OrderBy with the path trimmed.
*/
public OrderBy<T> copyWithTrim(String path) {
List<Property> newList = new ArrayList<Property>(list.size());
for (int i = 0; i < list.size(); i++) {
newList.add(list.get(i).copyWithTrim(path));
List<Property> newList = new ArrayList<>(list.size());
for (Property aList : list) {
newList.add(aList.copyWithTrim(path));
}
return new OrderBy<T>(newList);
return new OrderBy<>(newList);
}
/**
* Return the properties for this OrderBy.
*/
@@ -141,13 +141,20 @@ public final class OrderBy<T> implements Serializable {
*/
public OrderBy<T> copy() {
OrderBy<T> copy = new OrderBy<T>();
for (int i = 0; i < list.size(); i++) {
copy.add(list.get(i).copy());
OrderBy<T> copy = new OrderBy<>();
for (Property aList : list) {
copy.add(aList.copy());
}
return copy;
}
/**
* Add to the order by by parsing a raw expression.
*/
public void add(String rawExpression) {
parse(rawExpression);
}
/**
* Add a property to the order by.
*/
@@ -185,7 +192,7 @@ public final class OrderBy<T> implements Serializable {
if (!(obj instanceof OrderBy<?>)) {
return false;
}
OrderBy<?> e = (OrderBy<?>) obj;
return e.list.equals(list);
}
@@ -206,8 +213,9 @@ public final class OrderBy<T> implements Serializable {
* order by clause and replace.
* </p>
*/
public void clear() {
public OrderBy<T> clear() {
list.clear();
return this;
}
/**
@@ -221,24 +229,39 @@ public final class OrderBy<T> implements Serializable {
private boolean ascending;
private String nulls;
private String highLow;
public Property(String property, boolean ascending) {
this.property = property;
this.ascending = ascending;
}
public Property(String property, boolean ascending, String nulls, String highLow) {
this.property = property;
this.ascending = ascending;
this.nulls = nulls;
this.highLow = highLow;
}
/**
* Return a copy of this Property with the path trimmed.
*/
public Property copyWithTrim(String path) {
return new Property(property.substring(path.length() + 1), ascending);
return new Property(property.substring(path.length() + 1), ascending, nulls, highLow);
}
@Override
public int hashCode() {
int hc = property.hashCode();
hc = hc * 31 + (ascending ? 0 : 1);
hc = hc * 31 + (nulls == null ? 0 : nulls.hashCode());
hc = hc * 31 + (highLow == null ? 0 : highLow.hashCode());
return hc;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
@@ -246,10 +269,11 @@ public final class OrderBy<T> implements Serializable {
if (!(obj instanceof Property)) {
return false;
}
Property e = (Property) obj;
return e.ascending == ascending
&& e.property.equals(property);
if (ascending != e.ascending) return false;
if (!property.equals(e.property)) return false;
if (nulls != null ? !nulls.equals(e.nulls) : e.nulls != null) return false;
return highLow != null ? highLow.equals(e.highLow) : e.highLow == null;
}
public String toString() {
@@ -257,10 +281,20 @@ public final class OrderBy<T> implements Serializable {
}
public String toStringFormat() {
if (ascending) {
return property;
if (nulls == null) {
if (ascending) {
return property;
} else {
return property + " desc";
}
} else {
return property + " desc";
StringBuilder sb = new StringBuilder();
sb.append(property);
if (!ascending) {
sb.append(" ").append("desc");
}
sb.append(" ").append(nulls).append(" ").append(highLow);
return sb.toString();
}
}
@@ -282,7 +316,7 @@ public final class OrderBy<T> implements Serializable {
* Return a copy of this property.
*/
public Property copy() {
return new Property(property, ascending);
return new Property(property, ascending, nulls, highLow);
}
/**
@@ -322,9 +356,8 @@ public final class OrderBy<T> implements Serializable {
}
String[] chunks = orderByClause.split(",");
for (int i = 0; i < chunks.length; i++) {
String[] pairs = chunks[i].split(" ");
for (String chunk : chunks) {
String[] pairs = chunk.split(" ");
Property p = parseProperty(pairs);
if (p != null) {
list.add(p);
@@ -337,10 +370,10 @@ public final class OrderBy<T> implements Serializable {
return null;
}
ArrayList<String> wordList = new ArrayList<String>(pairs.length);
for (int i = 0; i < pairs.length; i++) {
if (!isEmptyString(pairs[i])) {
wordList.add(pairs[i]);
ArrayList<String> wordList = new ArrayList<>(pairs.length);
for (String pair : pairs) {
if (!isEmptyString(pair)) {
wordList.add(pair);
}
}
if (wordList.isEmpty()) {
@@ -353,8 +386,12 @@ public final class OrderBy<T> implements Serializable {
boolean asc = isAscending(wordList.get(1));
return new Property(wordList.get(0), asc);
}
String m = "Expecting a max of 2 words in [" + Arrays.toString(pairs)
+ "] but got " + wordList.size();
if (wordList.size() == 4) {
// nulls high or nulls low as 3rd and 4th
boolean asc = isAscending(wordList.get(1));
return new Property(wordList.get(0), asc, wordList.get(2), wordList.get(3));
}
String m = "Expecting a 1, 2 or 4 words in [" + Arrays.toString(pairs) + "] but got " + wordList;
throw new RuntimeException(m);
}
@@ -371,6 +408,6 @@ public final class OrderBy<T> implements Serializable {
}
private boolean isEmptyString(String s) {
return s == null || s.length() == 0;
return s == null || s.isEmpty();
}
}
+13 -38
View File
@@ -8,7 +8,7 @@ import java.util.concurrent.Future;
* <p>
* The benefit of using PagedList over just using the normal Query with
* {@link Query#setFirstRow(int)} and {@link Query#setMaxRows(int)} is that it additionally wraps
* functionality that can call {@link Query#findFutureRowCount()} to determine total row count,
* functionality that can call {@link Query#findFutureCount()} to determine total row count,
* total page count etc.
* </p>
* <p>
@@ -44,30 +44,6 @@ import java.util.concurrent.Future;
*
* }</pre>
*
* <h4>Example: typical use including total row count</h4>
* <pre>{@code
*
* // We want to find the first 100 new orders
* // ... 0 means first page
* // ... page size is 100
*
* PagedList<Order> pagedList
* = ebeanServer.find(Order.class)
* .where().eq("status", Order.Status.NEW)
* .order().asc("id")
* .findPagedList(0, 100);
*
* // 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: No total row count required</h4>
* <pre>{@code
@@ -84,7 +60,7 @@ import java.util.concurrent.Future;
* @param <T>
* the entity bean type
*
* @see Query#findPagedList(int, int)
* @see Query#findPagedList()
*/
public interface PagedList<T> {
@@ -110,7 +86,7 @@ public interface PagedList<T> {
* wrapped in the unchecked PersistenceException (which might be preferrable).
* </p>
*/
void loadRowCount();
void loadCount();
/**
* Return the Future row count. You might get this if you wish to cancel the total row count query
@@ -138,7 +114,7 @@ public interface PagedList<T> {
*
* }</pre>
*/
Future<Integer> getFutureRowCount();
Future<Integer> getFutureCount();
/**
* Return the list of entities for this page.
@@ -170,7 +146,7 @@ public interface PagedList<T> {
*
* }</pre>
*/
int getTotalRowCount();
int getTotalCount();
/**
* Return the total number of pages based on the page size and total row count.
@@ -181,20 +157,19 @@ public interface PagedList<T> {
*/
int getTotalPageCount();
/**
* 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 the index position of this page (Zero based).
* <p>
* This is a calculated value based on firstRow/maxRows.
* </p>
*/
int getPageIndex();
/**
* Return true if there is a next page.
* <p>
@@ -7,6 +7,8 @@ import javax.persistence.PersistenceException;
*/
public class PersistenceIOException extends PersistenceException {
private static final long serialVersionUID = -7630050437148176148L;
public PersistenceIOException(String msg, Exception cause) {
super(msg, cause);
}
@@ -78,6 +78,6 @@ class PrimaryServer {
* Return true if the string is null or empty.
*/
private static boolean isEmpty(String value) {
return value == null || value.trim().length() == 0;
return value == null || value.trim().isEmpty();
}
}
File diff suppressed because it is too large Load Diff
@@ -10,28 +10,35 @@ import java.util.Iterator;
* findList(), findSet() etc where all the beans are held in the List or Set
* etc).
* </p>
* <p>
* Note that findIterate (and findEach and findEachWhile) uses a "per graph"
* persistence context scope and adjusts jdbc fetch buffer size for large
* queries. As such it is better to use findList for small queries.
* </p>
* <p>
* Remember that with {@link QueryIterator} you must call {@link QueryIterator#close()}
* when you have finished iterating the results (typically in a finally block).
* </p>
*
* <pre>{@code
*
* <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;)
* Query<Customer> query = server.find(Customer.class)
* .where().gt("id", 0)
* .orderBy("id")
* .setMaxRows(2);
*
* QueryIterator&lt;Customer&gt; it = query.findIterate();
* try {
* while (it.hasNext()) {
* Customer customer = it.next();
* // do something with customer...
* }
* } finally {
* // close the associated resources
* it.close();
* }
* </pre>
*
* @author rbygrave
*
* QueryIterator<Customer> it = query.findIterate();
* try {
* while (it.hasNext()) {
* Customer customer = it.next();
* // do something with customer ...
* }
* } finally {
* // close the underlying resources
* it.close();
* }
*
* }</pre>
*
* @param <T>
* the type of entity bean in the iteration
+41 -42
View File
@@ -53,37 +53,37 @@ import com.avaje.ebean.util.CamelCaseHelper;
* </p>
*
* <h3>Example OrderAggregate</h3>
*
*
* <pre>{@code
* ...
* // @Sql indicates to that this bean
* // is based on RawSql rather than a table
*
*
* @Entity
* @Sql
* public class OrderAggregate {
*
*
* @OneToOne
* Order order;
*
*
* Double totalAmount;
*
*
* Double totalItems;
*
*
* // getters and setters
* ...
*
* }</pre>
*
* <h3>Example 1:</h3>
*
*
* <pre>{@code
*
* String sql = " select order_id, o.status, c.id, c.name, sum(d.order_qty*d.unit_price) as totalAmount"
* + " from o_order o"
* + " join o_customer c on c.id = o.kcustomer_id "
* + " join o_order_detail d on d.order_id = o.id " + " group by order_id, o.status ";
*
*
* RawSql rawSql = RawSqlBuilder.parse(sql)
* // map the sql result columns to bean properties
* .columnMapping("order_id", "order.id")
@@ -93,35 +93,35 @@ import com.avaje.ebean.util.CamelCaseHelper;
* // we don't need to map this one due to the sql column alias
* // .columnMapping("sum(d.order_qty*d.unit_price)", "totalAmount")
* .create();
*
*
* List<OrderAggregate> list = Ebean.find(OrderAggregate.class)
* .setRawSql(rawSql)
* .where().gt("order.id", 0)
* .having().gt("totalAmount", 20)
* .findList();
*
*
*
* }</pre>
*
*
* <h3>Example 2:</h3>
*
*
* <p>
* The following example uses a FetchConfig().query() so that after the initial
* RawSql query is executed Ebean executes a secondary query to fetch the
* associated order status, orderDate along with the customer name.
* </p>
*
*
* <pre>{@code
*
* String sql = " select order_id, 'ignoreMe', sum(d.order_qty*d.unit_price) as totalAmount "
* + " from o_order_detail d"
* + " group by order_id ";
*
*
* RawSql rawSql = RawSqlBuilder.parse(sql)
* .columnMapping("order_id", "order.id")
* .columnMappingIgnore("'ignoreMe'")
* .create();
*
*
* List<OrderAggregate> orders = Ebean.find(OrderAggregate.class)
* .setRawSql(rawSql)
* .fetch("order", "status,orderDate", new FetchConfig().query())
@@ -131,7 +131,7 @@ import com.avaje.ebean.util.CamelCaseHelper;
* .order().desc("totalAmount")
* .setMaxRows(10)
* .findList();
*
*
* }</pre>
*
*
@@ -167,14 +167,14 @@ import com.avaje.ebean.util.CamelCaseHelper;
* <p>
* Note that lazy loading also works with object graphs built with RawSql.
* </p>
*
*
*/
public final class RawSql implements Serializable {
private static final long serialVersionUID = 1L;
private final ResultSet resultSet;
private final Sql sql;
private final ColumnMapping columnMapping;
@@ -192,7 +192,7 @@ public final class RawSql implements Serializable {
this.sql = null;
this.columnMapping = new ColumnMapping(propertyNames);
}
protected RawSql(ResultSet resultSet, Sql sql, ColumnMapping columnMapping) {
this.resultSet = resultSet;
this.sql = sql;
@@ -214,7 +214,7 @@ public final class RawSql implements Serializable {
String unParsedSql = (sql == null) ? "" : sql.unparsedSql;
return new Key(parsed, unParsedSql, columnMapping);
}
/**
* Return the resultSet if this is a ResultSet based RawSql.
*/
@@ -386,7 +386,7 @@ public final class RawSql implements Serializable {
private final LinkedHashMap<String, Column> dbColumnMap;
private final Map<String, String> propertyMap;
private final Map<String, Column> propertyColumnMap;
private final boolean parsed;
@@ -401,10 +401,9 @@ public final class RawSql implements Serializable {
this.parsed = true;
this.propertyMap = null;
this.propertyColumnMap = null;
this.dbColumnMap = new LinkedHashMap<String, Column>();
for (int i = 0; i < columns.size(); i++) {
Column c = columns.get(i);
dbColumnMap.put(c.getDbColumn(), c);
this.dbColumnMap = new LinkedHashMap<>();
for (Column c : columns) {
dbColumnMap.put(c.getDbColumnKey(), c);
}
}
@@ -416,9 +415,9 @@ public final class RawSql implements Serializable {
this.parsed = false;
this.propertyMap = null;
this.propertyColumnMap = null;
this.dbColumnMap = new LinkedHashMap<String, Column>();
this.dbColumnMap = new LinkedHashMap<>();
}
/**
* Construct for ResultSet use.
*/
@@ -426,7 +425,7 @@ public final class RawSql implements Serializable {
this.immutable = false;
this.parsed = false;
this.propertyMap = null;
this.dbColumnMap = new LinkedHashMap<String, Column>();
this.dbColumnMap = new LinkedHashMap<>();
int pos = 0;
for (String prop : propertyNames) {
@@ -443,8 +442,8 @@ public final class RawSql implements Serializable {
this.parsed = parsed;
this.dbColumnMap = dbColumnMap;
HashMap<String, Column> pcMap = new HashMap<String, Column>();
HashMap<String, String> pMap = new HashMap<String, String>();
HashMap<String, Column> pcMap = new HashMap<>();
HashMap<String, String> pMap = new HashMap<>();
for (Column c : dbColumnMap.values()) {
pMap.put(c.getPropertyName(), c.getDbColumn());
@@ -476,7 +475,7 @@ public final class RawSql implements Serializable {
/**
* Creates an immutable copy of this ColumnMapping.
*
*
* @throws IllegalStateException
* when a propertyName has not been defined for a column.
*/
@@ -500,8 +499,7 @@ public final class RawSql implements Serializable {
} else {
Column column = dbColumnMap.get(dbColumn);
if (column == null) {
String msg = "DB Column [" + dbColumn + "] not found in mapping. Expecting one of ["
+ dbColumnMap.keySet() + "]";
String msg = "DB Column [" + dbColumn + "] not found in mapping. Expecting one of [" + dbColumnMap.keySet() + "]";
throw new IllegalArgumentException(msg);
}
column.setPropertyName(propertyName);
@@ -607,9 +605,9 @@ public final class RawSql implements Serializable {
}
}
private static String derivePropertyName(String dbAlias, String dbColumn) {
protected static String derivePropertyName(String dbAlias, String dbColumn) {
if (dbAlias != null) {
return dbAlias;
return CamelCaseHelper.toCamelFromUnderscore(dbAlias);
}
int dotPos = dbColumn.indexOf('.');
if (dotPos > -1) {
@@ -657,6 +655,14 @@ public final class RawSql implements Serializable {
return indexPos;
}
/**
* Return the DB column alias if specified otherwise DB column.
* This is used as the key for mapping a column to a logical property.
*/
public String getDbColumnKey() {
return (dbAlias != null) ? dbAlias : dbColumn;
}
/**
* Return the DB column name including table alias (if it has one).
*/
@@ -664,13 +670,6 @@ public final class RawSql implements Serializable {
return dbColumn;
}
/**
* Return the DB column alias (if it has one).
*/
public String getDbAlias() {
return dbAlias;
}
/**
* Return the bean property this column is mapped to.
*/
@@ -1,167 +0,0 @@
package com.avaje.ebean;
class SimpleTextParser {
private final String oql;
private final char[] chars;
private final int eof;
private int pos;
private String word;
private String lowerWord;
SimpleTextParser(String oql) {
this.oql = oql;
this.chars = oql.toCharArray();
this.eof = oql.length();
}
public int getPos() {
return pos;
}
public String getWord() {
return word;
}
public String peekNextWord() {
int origPos = pos;
String nw = nextWordInternal();
pos = origPos;
return nw;
}
/**
* Match the current and the next word.
*/
public boolean isMatch(String lowerMatch, String nextWordMatch) {
if (isMatch(lowerMatch)) {
String nw = peekNextWord();
if (nw != null) {
nw = nw.toLowerCase();
return nw.equals(nextWordMatch);
}
}
return false;
}
public boolean isFinished() {
return word == null;
}
public int findWordLower(String lowerMatch, int afterPos) {
this.pos = afterPos;
return findWordLower(lowerMatch);
}
public int findWordLower(String lowerMatch) {
do {
if (nextWord() == null) {
return -1;
}
if (lowerMatch.equals(lowerWord)) {
return pos - lowerWord.length();
}
} while (true);
}
/**
* Match the current word.
*/
public boolean isMatch(String lowerMatch) {
return lowerMatch.equals(lowerWord);
}
public String nextWord() {
word = nextWordInternal();
if (word != null) {
lowerWord = word.toLowerCase();
}
return word;
}
private String nextWordInternal() {
trimLeadingWhitespace();
if (pos >= eof) {
return null;
}
int start = pos;
if (chars[pos] == '(') {
moveToClose();
} else {
moveToEndOfWord();
}
return oql.substring(start, pos);
}
private void moveToClose() {
pos++;
int openParenthesisCount = 0;
for (; pos < eof; pos++) {
char c = chars[pos];
if (c == '(') {
// count nested parenthesis
openParenthesisCount++;
} else if (c == ')') {
if (openParenthesisCount > 0) {
// still in nested parenthesis
--openParenthesisCount;
} else {
// we have found the end
pos++;
return;
}
}
}
}
private void moveToEndOfWord() {
char c = chars[pos];
boolean isOperator = isOperator(c);
for (; pos < eof; pos++) {
c = chars[pos];
if (isWordTerminator(c, isOperator)) {
return;
}
}
}
private boolean isWordTerminator(char c, boolean isOperator) {
if (Character.isWhitespace(c)) {
return true;
}
if (isOperator(c)) {
return !isOperator;
}
return c == '(' || isOperator;
}
private boolean isOperator(char c) {
switch (c) {
case '<':
return true;
case '>':
return true;
case '=':
return true;
case '!':
return true;
default:
return false;
}
}
private void trimLeadingWhitespace() {
for (; pos < eof; pos++) {
char c = chars[pos];
if (!Character.isWhitespace(c)) {
break;
}
}
}
}
@@ -1,47 +0,0 @@
package com.avaje.ebean;
import java.util.List;
import java.util.concurrent.Future;
/**
* The SqlFutureList represents the result of a background SQL query execution.
*
* <p>
* It extends the java.util.concurrent.Future.
* </p>
*
* <pre class="code">
* // create a query
* String sql = ... ;
* SqlQuery sqlQuery = Ebean.createSqlQuery(sql);
*
* // execute the query in a background thread
* SqlFutureList sqlFuture = sqlQuery.findFutureList();
*
* // do something else ... we will sleep
* Thread.sleep(3000);
* System.out.println("end of sleep");
*
* if (!futureList.isDone()){
* // we can cancel the query execution
* futureList.cancel(true);
* }
*
* System.out.println("and... done:"+futureList.isDone());
*
* if (!futureList.isCancelled()){
* // wait for the query to finish and return the list
* List&lt;SqlRow&gt; list = futureList.get();
* System.out.println("list:"+list);
* }
*
* </pre>
*
* @author rob
*
*/
public interface SqlFutureList extends Future<List<SqlRow>> {
SqlQuery getQuery();
}
+25 -60
View File
@@ -2,8 +2,6 @@ package com.avaje.ebean;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Query object for performing native SQL queries that return SqlRow's.
@@ -21,45 +19,48 @@ import java.util.Set;
* conversion support added.
* </p>
*
* <pre class="code">
* // its typically a good idea to use a named query
* // and put the sql in the orm.xml instead of in your code
* <pre>{@code
*
* // its typically a good idea to use a named query
* // and put the sql in the orm.xml instead of in your code
*
* String sql = &quot;select id, name from customer where name like :name and status_code = :status&quot;;
* String sql = "select id, name from customer where name like :name and status_code = :status";
*
* SqlQuery sqlQuery = Ebean.createSqlQuery(sql);
* sqlQuery.setParameter(&quot;name&quot;, &quot;Acme%&quot;);
* sqlQuery.setParameter(&quot;status&quot;, &quot;ACTIVE&quot;);
* SqlQuery sqlQuery = Ebean.createSqlQuery(sql);
* sqlQuery.setParameter("name", "Acme%");
* sqlQuery.setParameter("status", "ACTIVE");
*
* // execute the query returning a List of MapBean objects
* List&lt;SqlRow&gt; list = sqlQuery.findList();
* </pre>
* // execute the query returning a List of MapBean objects
* List<SqlRow> list = sqlQuery.findList();
*
* }</pre>
*
*/
public interface SqlQuery extends Serializable {
/**
* Cancel the query if support by the underlying database and driver.
* <p>
* This must be called from a different thread to the one executing the query.
* </p>
*/
void cancel();
/**
* Execute the query returning a list.
*/
List<SqlRow> findList();
/**
* Execute the query returning a set.
* Execute the SqlQuery iterating a row at a time.
* <p>
* This streaming type query is useful for large query execution as only 1 row needs to be held in memory.
* </p>
*/
Set<SqlRow> findSet();
void findEach(QueryEachConsumer<SqlRow> consumer);
/**
* Execute the query returning a map.
* Execute the SqlQuery iterating a row at a time with the ability to stop consuming part way through.
* <p>
* Returning false after processing a row stops the iteration through the query results.
* </p>
* <p>
* This streaming type query is useful for large query execution as only 1 row needs to be held in memory.
* </p>
*/
Map<?, SqlRow> findMap();
void findEachWhile(QueryEachWhileConsumer<SqlRow> consumer);
/**
* Execute the query returning a single row or null.
@@ -70,19 +71,6 @@ public interface SqlQuery extends Serializable {
*/
SqlRow findUnique();
/**
* Execute find list SQL query in a background thread.
* <p>
* This returns a Future object which can be used to cancel, check the
* execution status (isDone etc) and get the value (with or without a
* timeout).
* </p>
*
* @return a Future object for the list result of the query
* @deprecated
*/
SqlFutureList findFutureList();
/**
* The same as bind for named parameters.
*/
@@ -93,19 +81,6 @@ public interface SqlQuery extends Serializable {
*/
SqlQuery setParameter(int position, Object value);
/**
* Set a listener to process the query on a row by row basis.
* <p>
* It this case the rows are not loaded into the persistence context and
* instead can be processed by the query listener.
* </p>
* <p>
* Use this when you want to process a large query and do not want to hold the
* entire query result in memory.
* </p>
*/
SqlQuery setListener(SqlQueryListener queryListener);
/**
* Set the index of the first row of the results to return.
*/
@@ -116,16 +91,6 @@ public interface SqlQuery extends Serializable {
*/
SqlQuery setMaxRows(int maxRows);
/**
* Set the index after which fetching continues in a background thread.
*/
SqlQuery setBackgroundFetchAfter(int backgroundFetchAfter);
/**
* Set the column to use to determine the keys for a Map.
*/
SqlQuery setMapKey(String mapKey);
/**
* Set a timeout on this query.
* <p>
@@ -1,33 +0,0 @@
package com.avaje.ebean;
/**
* Provides a mechanism for processing a SqlQuery one SqlRow at a time.
* <p>
* This is useful when the query will return a large number of results and you
* want to process the beans one at a time rather than have all of the beans in
* memory at once.
* </p>
*
* <pre class="code">
* SqlQueryListener listener = ...;
*
* SqlQuery query = Ebean.createSqlQuery(&quot;my.large.query&quot;);
*
* // set the listener that will process each row one at a time
* query.setListener(listener);
*
* // execute the query. Note that the returned
* // list will be empty ... so don't bother assigning it...
* query.findList();
* </pre>
*/
public interface SqlQueryListener {
/**
* Process the bean that has just been read.
* <p>
* Note this bean will not be added to the List Set or Map.
* </p>
*/
void process(SqlRow bean);
}
+3 -4
View File
@@ -26,7 +26,7 @@ package com.avaje.ebean;
*
* int modifiedCount = Ebean.execute(update);
*
* String msg = &quot;There where &quot; + modifiedCount + &quot;rows updated&quot;
* String msg = &quot;There were &quot; + modifiedCount + &quot; rows updated&quot;
* </pre>
*
* @see Update
@@ -117,8 +117,7 @@ public interface SqlUpdate {
SqlUpdate setParameter(int position, Object value);
/**
* Set a null parameter via its index position. Exactly the same as
* {@link #setNull(int, int)}.
* Set a null parameter via its index position.
*/
SqlUpdate setNull(int position, int jdbcType);
@@ -143,4 +142,4 @@ public interface SqlUpdate {
*/
SqlUpdate setNullParameter(String name, int jdbcType);
}
}
+120 -6
View File
@@ -3,6 +3,7 @@ package com.avaje.ebean;
import com.avaje.ebean.annotation.DocStoreMode;
import com.avaje.ebean.config.DocStoreConfig;
import com.avaje.ebean.config.PersistBatch;
import com.avaje.ebean.config.ServerConfig;
import javax.persistence.PersistenceException;
import javax.persistence.RollbackException;
@@ -53,13 +54,52 @@ public interface Transaction extends Closeable {
*/
void setReadOnly(boolean readOnly);
/**
* Commits the transaction at this point with the expectation that another
* commit (or rollback or end) will occur later to complete the transaction.
* <p>
* This is similar to commit() but leaves the transaction "Active".
* </p>
* <h3>Functions/h3>
* <ul>
* <li>Flush the JDBC batch buffer</li>
* <li>Call commit on the underlying JDBC connection</li>
* <li>Trigger any registered TransactionCallbacks</li>
* <li>Perform post-commit processing updating L2 cache, ElasticSearch etc</li>
* </ul>
*/
void commitAndContinue() throws RollbackException;
/**
* Commit the transaction.
* <p>
* This performs commit and completes the transaction closing underlying resources and
* marking the transaction as "In active".
* </p>
* <h3>Functions/h3>
* <ul>
* <li>Flush the JDBC batch buffer</li>
* <li>Call commit on the underlying JDBC connection</li>
* <li>Trigger any registered TransactionCallbacks</li>
* <li>Perform post-commit processing updating L2 cache, ElasticSearch etc</li>
* <li>Close any underlying resources, closing the underlying JDBC connection</li>
* <li>Mark the transaction as "Inactive"</li>
* </ul>
*/
void commit() throws RollbackException;
/**
* Rollback the transaction.
* <p>
* This performs rollback, closes underlying resources and marks the transaction as "In active".
* </p>
* <h3>Functions/h3>
* <ul>
* <li>Call rollback on the underlying JDBC connection</li>
* <li>Trigger any registered TransactionCallbacks</li>
* <li>Close any underlying resources, closing the underlying JDBC connection</li>
* <li>Mark the transaction as "Inactive"</li>
* </ul>
*/
void rollback() throws PersistenceException;
@@ -73,6 +113,16 @@ public interface Transaction extends Closeable {
*/
void rollback(Throwable e) throws PersistenceException;
/**
* Mark the transaction for rollback only.
*/
void setRollbackOnly();
/**
* Return true if the transaction is marked as rollback only.
*/
boolean isRollbackOnly();
/**
* If the transaction is active then perform rollback. Otherwise do nothing.
*/
@@ -125,13 +175,78 @@ public interface Transaction extends Closeable {
* 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.
* 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);
/**
* Set if the L2 cache should be skipped for "find by id" and "find by natural key" queries.
* <p>
* By default {@link ServerConfig#isSkipCacheAfterWrite()} is true and that means that for
* "find by id" and "find by natural key" queries which normally hit L2 bean cache automatically
* - will not do so after a persist/write on the transaction.
* </p>
* <p>
* This method provides explicit control over whether "find by id" and "find by natural key"
* will skip the L2 bean cache or not (regardless of whether the transaction is considered "read only").
* </p>
* <p>
* Refer to {@link ServerConfig#setSkipCacheAfterWrite(boolean)} for configuring the default behavior
* for using the L2 bean cache in transactions spanning multiple query/persist requests.
* </p>
*
* <pre>{@code
*
* // assume Customer has L2 bean caching enabled ...
*
* Transaction transaction = Ebean.beginTransaction();
* try {
*
* // this uses L2 bean cache as the transaction
* // ... is considered "query only" at this point
* Customer.find.byId(42);
*
* // transaction no longer "query only" once
* // ... a bean has been saved etc
* Ebean.save(someBean);
*
* // will NOT use L2 bean cache as the transaction
* // ... is no longer considered "query only"
* Customer.find.byId(55);
*
*
*
* // explicit control - please use L2 bean cache
*
* transaction.setSkipCache(false);
* Customer.find.byId(77); // hit the l2 bean cache
*
*
* // explicit control - please don't use L2 bean cache
*
* transaction.setSkipCache(true);
* Customer.find.byId(99); // skips l2 bean cache
*
*
* } finally {
* transaction.end();
* }
*
* }</pre>
*
* @see ServerConfig#isSkipCacheAfterWrite()
*/
void setSkipCache(boolean skipCache);
/**
* Return true if the L2 cache should be skipped. More accurately if true then find by id
* and find by natural key queries should NOT automatically use the L2 bean cache.
*/
boolean isSkipCache();
/**
* Turn on or off statement batching. Statement batching can be transparent
* for drivers and databases that support getGeneratedKeys. Otherwise you may
@@ -351,9 +466,8 @@ public interface Transaction extends Closeable {
/**
* Add an arbitrary user object to the transaction. The objects added have no
* impact on any internals of ebena and are solely meant as a convenient
* method push user information to e.g. the
* {@link com.avaje.ebean.event.TransactionEventListener}.
* impact on any internals of ebean and are solely meant as a convenient
* method push user information (although somewhat replaced by TransactionCallback).
*/
void putUserObject(String name, Object value);
+64 -30
View File
@@ -16,7 +16,7 @@ import java.util.ArrayList;
* This object is used internally with the enhancement of a method with
* Transactional annotation.
* </p>
*
*
* @see TxCallable
* @see TxRunnable
* @see Ebean#execute(TxScope, TxCallable)
@@ -36,33 +36,14 @@ public final class TxScope {
int batchSize;
boolean skipGeneratedKeys;
boolean readOnly;
ArrayList<Class<? extends Throwable>> rollbackFor;
ArrayList<Class<? extends Throwable>> noRollbackFor;
/**
* Return true if PersistBatch has been set.
*/
public boolean isBatchSet() {
return batch != null && batch != PersistBatch.INHERIT;
}
/**
* Return true if batch on cascade has been set.
*/
public boolean isBatchOnCascadeSet() {
return batchOnCascade != null && batchOnCascade != PersistBatch.INHERIT;
}
/**
* Return true if batch size has been set.
*/
public boolean isBatchSizeSet() {
return batchSize > 0;
}
/**
* Helper method to create a TxScope with REQUIRES.
*/
@@ -128,6 +109,44 @@ public final class TxScope {
+ "] rollbackFor[" + rollbackFor + "] noRollbackFor[" + noRollbackFor + "]";
}
/**
* Return true if PersistBatch has been set.
*/
public boolean isBatchSet() {
return batch != null && batch != PersistBatch.INHERIT;
}
/**
* Return true if batch on cascade has been set.
*/
public boolean isBatchOnCascadeSet() {
return batchOnCascade != null && batchOnCascade != PersistBatch.INHERIT;
}
/**
* Return true if batch size has been set.
*/
public boolean isBatchSizeSet() {
return batchSize > 0;
}
/**
* Check for batchSize being set without batch mode and use this to imply PersistBatch.ALL.
*/
public void checkBatchMode() {
if (batchSize > 0 && notSet(batch) && notSet(batchOnCascade)) {
// Use setting the batchSize as implying PersistBatch.ALL for @Transactional
batch = PersistBatch.ALL;
}
}
/**
* Return true if the mode is considered not set.
*/
private boolean notSet(PersistBatch batchMode) {
return batchMode == null || batchMode == PersistBatch.INHERIT;
}
/**
* Return the transaction type.
*/
@@ -188,6 +207,21 @@ public final class TxScope {
return this;
}
/**
* Set if the transaction should skip reading generated keys for inserts.
*/
public TxScope setSkipGeneratedKeys() {
this.skipGeneratedKeys = true;
return this;
}
/**
* Return true if getGeneratedKeys should be skipped for this transaction.
*/
public boolean isSkipGeneratedKeys() {
return skipGeneratedKeys;
}
/**
* Return if the transaction should be treated as read only.
*/
@@ -248,7 +282,7 @@ public final class TxScope {
*/
public TxScope setRollbackFor(Class<? extends Throwable> rollbackThrowable) {
if (rollbackFor == null) {
rollbackFor = new ArrayList<Class<? extends Throwable>>(2);
rollbackFor = new ArrayList<>(2);
}
rollbackFor.add(rollbackThrowable);
return this;
@@ -260,10 +294,10 @@ public final class TxScope {
@SuppressWarnings("unchecked")
public TxScope setRollbackFor(Class<?>[] rollbackThrowables) {
if (rollbackFor == null) {
rollbackFor = new ArrayList<Class<? extends Throwable>>(rollbackThrowables.length);
rollbackFor = new ArrayList<>(rollbackThrowables.length);
}
for (int i = 0; i < rollbackThrowables.length; i++) {
rollbackFor.add((Class<? extends Throwable>) rollbackThrowables[i]);
for (Class<?> rollbackThrowable : rollbackThrowables) {
rollbackFor.add((Class<? extends Throwable>) rollbackThrowable);
}
return this;
}
@@ -282,7 +316,7 @@ public final class TxScope {
*/
public TxScope setNoRollbackFor(Class<? extends Throwable> noRollback) {
if (noRollbackFor == null) {
noRollbackFor = new ArrayList<Class<? extends Throwable>>(2);
noRollbackFor = new ArrayList<>(2);
}
this.noRollbackFor.add(noRollback);
return this;
@@ -294,10 +328,10 @@ public final class TxScope {
@SuppressWarnings("unchecked")
public TxScope setNoRollbackFor(Class<?>[] noRollbacks) {
if (noRollbackFor == null) {
noRollbackFor = new ArrayList<Class<? extends Throwable>>(noRollbacks.length);
noRollbackFor = new ArrayList<>(noRollbacks.length);
}
for (int i = 0; i < noRollbacks.length; i++) {
noRollbackFor.add((Class<? extends Throwable>) noRollbacks[i]);
for (Class<?> noRollback : noRollbacks) {
noRollbackFor.add((Class<? extends Throwable>) noRollback);
}
return this;
}
@@ -0,0 +1,160 @@
package com.avaje.ebean;
/**
* An update query typically intended to perform a bulk update of many rows that match the query.
* <p>
* Also note that you can also just use a raw SQL update via {@link SqlUpdate} which is pretty light and simple.
* This UpdateQuery is more for the cases where we want to build the where expression of the update using the
* {@link ExpressionList} "Criteria API" that is used with a normal ORM query.
* </p>
*
* <h4>Example: Simple update</h4>
*
* <pre>{@code
*
* int rows = ebeanServer
* .update(Customer.class)
* .set("status", Customer.Status.ACTIVE)
* .set("updtime", new Timestamp(System.currentTimeMillis()))
* .where()
* .gt("id", 1000)
* .update();
*
* }</pre>
* <pre>{@code sql
*
* update o_customer set status=?, updtime=? where id > ?
*
* }</pre>
*
* <p>
* Note that if the where() clause contains a join then the SQL update changes to use a
* <code> WHERE ID IN () </code> form.
* </p>
*
* <h4>Example: Update with a JOIN</h4>
* <p>
* In this example the expression <code>.eq("billingAddress.country", nz)</code> requires a join
* to the address table.
* </p>
*
* <pre>{@code
*
* int rows = ebeanServer
* .update(Customer.class)
* .set("status", Customer.Status.ACTIVE)
* .set("updtime", new Timestamp(System.currentTimeMillis()))
* .where()
* .eq("status", Customer.Status.NEW)
* .eq("billingAddress.country", nz)
* .gt("id", 1000)
* .update();
* }</pre>
*
* <pre>{@code sql
*
* update o_customer set status=?, updtime=?
* where id in (
* select t0.id c0
* from o_customer t0
* left join o_address t1 on t1.id = t0.billing_address_id
* where t0.status = ?
* and t1.country_code = ?
* and t0.id > ? )
*
* }</pre>
*
* @param <T> The type of entity bean being updated
*
* @see SqlUpdate
*/
public interface UpdateQuery<T> {
/**
* Set the value of a property.
*
*
* <pre>{@code
*
* int rows = ebeanServer
* .update(Customer.class)
* .set("status", Customer.Status.ACTIVE)
* .set("updtime", new Timestamp(System.currentTimeMillis()))
* .where()
* .gt("id", 1000)
* .update();
*
* }</pre>
*
* @param property The bean property to be set
* @param value The value to set the property to
*/
UpdateQuery<T> set(String property, Object value);
/**
* Set the property to be null.
*
* <pre>{@code
*
* int rows = ebeanServer
* .update(Customer.class)
* .setNull("notes")
* .where()
* .gt("id", 1000)
* .update();
*
* }</pre>
*
* @param property The property to be set to null.
*/
UpdateQuery<T> setNull(String property);
/**
*
* Set using a property expression that does not need any bind values.
* <p>
* The property expression typically contains database functions.
* </p>
*
* <pre>{@code
*
* int rows = ebeanServer
* .update(Customer.class)
* .setRaw("status = coalesce(status, 'A')")
* .where()
* .gt("id", 1000)
* .update();
*
* }</pre>
*
* @param propertyExpression A property expression
*/
UpdateQuery<T> setRaw(String propertyExpression);
/**
* Set using a property expression that can contain <code>?</code> bind value placeholders.
* <p>
* For each <code>?</code> in the property expression there should be a matching bind value supplied.
* </p>
* <pre>{@code
*
* int rows = ebeanServer
* .update(Customer.class)
* .setRaw("status = coalesce(status, ?)", Customer.Status.ACTIVE)
* .where()
* .gt("id", 1000)
* .update();
*
* }</pre>
*
* @param propertyExpression A raw property expression
* @param values The values to bind with the property expression
*/
UpdateQuery<T> setRaw(String propertyExpression, Object... values);
/**
* Return the query expression list to add predicates to.
*/
ExpressionList<T> where();
}
@@ -0,0 +1,50 @@
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 property to be an aggregation formula.
* <p>
* The aggregation formula should be a sum, count, avg, min or max.
* By default aggregation properties are treated as transient and not
* included in a query. To populate the aggregation property it must be
* explicitly included in the select().
* </p>
*
* <h3>Example:</h3>
* <pre>{@code
*
* @Aggregation("count(details)")
* Long totalCount;
*
* @Aggregation("sum(details.quantity*details.unitPrice)")
* Long totalAmount;
*
* }</pre>
*
* <h3>Example query</h3>
* <pre>{@code
*
* List<TEventOne> list = Ebean.find(TEventOne.class)
* .select("name, totalCount, totalUnits, totalAmount")
* .where()
* .startsWith("logs.description", "a")
* .having()
* .ge("count", 1)
* .orderBy().asc("name")
* .findList();
*
* }</pre>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Aggregation {
/**
* Aggregation formula using sum, count, avg, min, max.
*/
String value();
}
@@ -0,0 +1,61 @@
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 default cache use specific entity type.
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Cache {
/**
* Set this to true to enable the use of query cache.
* <p>
* By default query caching is disabled as the query cache invalidates
* frequently and so it is typically used for specific bean types and cases.
* </p>
*/
boolean enableQueryCache() default false;
/**
* Set this to false to disable the use of bean cache.
* <p>
* By default bean caching is expected so this defaults to true. We might
* set this to false on a bean type that we want to use query caching but no
* bean caching (and this is expected to be a rare case).
* </p>
* <p>
* When bean caching is enabled by default "find by id" and "find by unique natural key"
* queries will try to use the bean cache. We use {@link com.avaje.ebean.Query#setUseCache(boolean)}
* with <code>false</code> for the case when we do NOT want to use the bean cache.
* </p>
*/
boolean enableBeanCache() default true;
/**
* Specify the property that is a natural unique identifier for the bean.
* <p>
* When a findUnique() query is used with this property as the sole expression
* then there will be a lookup into the L2 natural key cache.
* </p>
*/
String naturalKey() default "";
/**
* When set to true the beans returned from a query will default to be
* readOnly.
* <p>
* If the bean is readOnly and has no relationships then it may be sharable.
* </p>
* <p>
* If you try to modify a readOnly bean it will throw an
* IllegalStateException.
* </p>
*/
boolean readOnly() default false;
}
@@ -0,0 +1,56 @@
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;
/**
* Cache tuning hints for the L2 bean cache of a specific entity type.
* <p>
* Note that this is not useful when distributed L2 bean caches are used like
* ElasticSearch, Hazelcast, Ignite etc.
* </p>
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheBeanTuning {
/**
* The maximum size for the cache.
* <p>
* This defaults to 0 which means unlimited.
* </p>
*/
int maxSize() default 0;
/**
* The maximum time (in seconds) that a cache entry is allowed to stay in the
* cache when it has not been accessed.
* <p>
* This defaults to 0 which means unlimited.
* </p>
*/
int maxIdleSecs() default 0;
/**
* The maximum time (in seconds) a cache entry is allowed to stay in the
* cache.
* <p>
* This is not generally required as the cache entries are automatically
* evicted when related data changes are committed.
* </p>
* <p>
* This defaults to 0 which means unlimited.
* </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;
}
@@ -6,14 +6,14 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specify cache tuning for a specific entity type.
* Specify cache tuning for query caching on a specific entity type.
* <p>
* If this is not specified then the system default settings are used.
* </p>
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheTuning {
public @interface CacheQueryTuning {
/**
* The maximum size for the cache.
@@ -1,58 +0,0 @@
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;
import com.avaje.ebean.Query;
/**
* Specify the default cache use specific entity type.
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheStrategy {
/**
* When set to true the bean cache will be used unless explicitly stated not
* to in a query via {@link Query#setUseCache(boolean)}.
*/
boolean useBeanCache() default true;
/**
* A single property that is a natural unique identifier for the bean.
* <p>
* When a findUnique query is used with this property as the sole expression
* then there will be a lookup into the L2 natural key cache.
* </p>
*/
String naturalKey() default "";
/**
* When set to true the beans returned from a query will default to be
* readOnly.
* <p>
* If the bean is readOnly and has no relationships then it may be sharable.
* </p>
* <p>
* If you try to modify a readOnly bean it will throw an
* IllegalStateException.
* </p>
*/
boolean readOnly() default false;
/**
* Specify a query that can be used to warm the cache.
* <p>
* All the beans fetched by this query will be loaded into the bean cache and
* the query itself will be loaded into the query cache.
* </p>
* <p>
* The warming query will typically be executed at startup time after a short
* delay (defaults to a 30 seconds delay).
* </p>
*/
String warmingQuery() default "";
}
@@ -0,0 +1,40 @@
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 collection property that will be stored into a DB ARRAY type.
* <p>
* If the target database does not support ARRAY type (so not Postgres)
* then the collection will be stored in JSON format into a VARCHAR column.
* </p>
*
* <h3>Example:</h3>
* <pre>{@code
*
* // Store as ARRAY of UUID on Postgres
* @DbArray
* List<UUID> uids = new ArrayList<>();
*
* // Store as ARRAY on Postgres
* @DbArray
* List<String> phoneNumbers = new ArrayList<>();
*
* // Store as ARRAY of INTEGER on Postgres
* @DbArray
* List<Long> someLongs = new ArrayList<>();
*
* }</pre>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface DbArray {
/**
* For VARCHAR storage specify the column length (defaults to 1000).
*/
int length() default 0;
}
@@ -23,4 +23,8 @@ import java.lang.annotation.Target;
@Target(ElementType.FIELD)
public @interface DbHstore {
/**
* For VARCHAR storage specify the column length (defaults to 1000).
*/
int length() default 0;
}
@@ -36,4 +36,8 @@ import java.lang.annotation.Target;
@Target(ElementType.FIELD)
public @interface DbJsonB {
/**
* For VARCHAR storage specify the column length.
*/
int length() default 0;
}
@@ -1,21 +0,0 @@
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;
/**
* Deprecated in favor of @DocEmbedded (i.e. renamed to @DocEmbedded)
*/
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Deprecated
public @interface DocStoreEmbedded {
/**
* The properties on the embedded bean to include in the index.
*/
String doc() default "";
}
@@ -1,19 +0,0 @@
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 explicit ConcurrencyMode for entity bean.
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface EntityConcurrencyMode {
/**
* The ConcurrencyMode value.
*/
ConcurrencyMode value();
}
@@ -1,90 +0,0 @@
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 mapping the values of an Enum to and from Database values.
* <p>
* Also refer to the {@link EnumValue} approach which probably the preferred now
* (preferred over using this EnumMapping annotation).
* </p>
* <p>
* Both of the approaches defined in the JPA have significant problems!!!
* </p>
* <p>
* Using the ordinal value is VERY RISKY because that depends on the compile
* order of the enum values. Aka if you change the order of the enum values you
* have changed their ordinal values and now your DB values are WRONG - a HUGE
* disaster!!!.
* </p>
* <p>
* Using the String values of enums is fairly restrictive because in a Database
* these values are usually truncated into short codes (e.g. "A" short for
* "ACTIVE") so space used in the database is minimised. Making your enum names
* match the database values would give them very short less meaningful names -
* not a great solution.
* </p>
* <p>
* You can use this annotation to control the mapping of your enums to database
* values.
* </p>
* <p>
* The design of this using nameValuePairs is not optimal for safety or
* refactoring so if you have a better solution I'm all ears. The other
* solutions would probably involve modifying each enumeration with a method
* which may be ok.
* </p>
* <p>
* An example mapping the UserState enum.
* </p>
*
* <pre class="code">
* ...
* &#064;EnumMapping(nameValuePairs=&quot;NEW=N, ACTIVE=A, INACTIVE=I&quot;)
* public enum UserState {
* NEW,
* ACTIVE,
* INACTIVE;
* }
* </pre>
*
* @see EnumValue
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface EnumMapping {
/**
* A comma delimited list of name=value pairs.
* <p>
* e.g. "ACTIVE=A, INACTIVE=I, NEW=N".
* </p>
* <p>
* Where ACTIVE, INACTIVE and NEW are the enumeration values and "A", "I" and
* "N" are the database values.
* </p>
* <p>
* This is not really an optimal approach so if you have a better one I'm all
* ears - thanks.
* </p>
*/
String nameValuePairs();
/**
* Defaults to mapping values to database VARCHAR type. If this is set to true
* then the values will be converted to INTEGER and mapped to the database
* integer type.
* <p>
* e.g. "ACTIVE=1, INACTIVE=0, NEW=2".
* </p>
*/
boolean integerType() default false;
/**
* The length of DB column if mapping to string values.
*/
int length() default 0;
}
@@ -82,7 +82,7 @@ public @interface Formula {
* as count, sum etc.
* </p>
* <p>
* The join string should start with either "left outer join" or "join".
* The join string should start with either "left join" or "join".
* </p>
*
* <p>
@@ -1,17 +1,19 @@
package com.avaje.ebean.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* An annotation for declaring an index on a single column.
* An annotation for declaring an index.
*
* @author rvbiljouw
*/
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Indices.class)
public @interface Index {
/**
@@ -27,6 +29,9 @@ public @interface Index {
/**
* When placed on the class (rather than field) you can specify the columns
* to include in the index in order.
*
* Wnen placed on a field, and columnNames are specified, the field-column has to be included.
* You can use "${fa}" for alias
*/
String[] columnNames() default {};
@@ -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;
/**
* An annotation for declaring multiple indices at class or field level.
*
* @author Roland Praml, FOCONIS AG
*/
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Indices {
/**
* Array with {@link Index} definitions.
*/
Index[] value() default {};
}
@@ -1,37 +0,0 @@
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;
/**
* An Update statement for a particular entity bean type.
* <p>
* The update can either be a sql insert,update or delete statement with tables
* and columns etc or the equivalent statement but with table names and columns
* expressed as bean types and bean properties.
* </p>
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface NamedUpdate {
/**
* The name of the update.
*/
String name();
/**
* The insert, update or delete statement.
*/
String update();
/**
* Set this to false if you do not want the cache to be notified. If true the
* cache will invalidate appropriate objects from the cache (after a
* successful transaction commit).
*/
boolean notifyCache() default true;
}
@@ -1,20 +0,0 @@
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;
/**
* Holds an array of named Update statements for a particular entity bean type.
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface NamedUpdates {
/**
* An array of named updates.
*/
NamedUpdate[] value();
}
@@ -6,19 +6,13 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Specify explicit sql for multiple select statements. Need to use this if you
* have more than one SqlSelect for a given bean.
* Mark and entity bean that is used solely via RawSql.
* <p>
* FUTURE: Support explicit sql for SqlInsert, SqlUpdate and SqlDelete.
* This means the entity bean has no base table specified (via @Table).
* </p>
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Sql {
/**
* The sql select statements.
*/
SqlSelect[] select() default { @SqlSelect };
}
@@ -1,298 +0,0 @@
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;
import com.avaje.ebean.Query;
/**
* Specify an explicit sql select statement to use for querying an entity bean.
* <p>
* The reason for using explicit sql is that you want better control over the
* exact sql or sql that Ebean does not generate for you (such as group by,
* union, intersection, window functions, recursive queries).
* </p>
* <p>
* An example of two sql select queries deployed on the ReportTopic entity bean.
* The first one has no name specified so it becomes the default query. The
* second query extends the first adding a where clause with a named parameter.
* </p>
*
* <pre class="code">
* ...
* &#064;Entity
* &#064;Sql(select = {
* &#064;SqlSelect(query =
* &quot;select t.id, t.title, count(p.id) as score &quot;+
* &quot;from f_topic t &quot;+
* &quot;join f_topic_post p on p.topic_id = t.id &quot;+
* &quot;group by t.id, t.title&quot;),
* &#064;SqlSelect(
* name = &quot;with.title&quot;,
* extend = &quot;default&quot;,
* debug = true,
* where = &quot;title like :likeTitle&quot;)
* })
* public class ReportTopic
* &#064;Id Integer id;
* String title;
* Double score;
* ...
* </pre>
*
* <p>
* An example using the first "default" query.
* </p>
*
* <pre class="code">
*
* List&lt;ReportTopic&gt; list =
* Ebean.find(ReportTopic.class)
* .having().gt(&quot;score&quot;, 0)
* .findList();
*
* </pre>
*
* <p>
* The resulting sql, note the having clause has been added.
* </p>
*
* <pre class="code">
* select t.id, t.title, count(p.id) as score
* from f_topic t join f_topic_post p on p.topic_id = t.id
* group by t.id, t.title
* having count(p.id) &gt; ?
* </pre>
*
* <p>
* An example using the second query. Note the named parameter "likeTitle" must
* be set.
* </p>
*
* <pre class="code">
* List&lt;ReportTopic&gt; list =
* Ebean.find(ReportTopic.class, &quot;with.title&quot;)
* .set(&quot;likeTitle&quot;, &quot;a%&quot;)
* .findList();
* </pre>
*
* <p>
* Ebean tries to parse the sql in the query to determine 4 things
* <li>Location for inserting WHERE expressions (if required)</li>
* <li>Location for inserting HAVING expressions (if required)</li>
* <li>Mapping of columns to bean properties</li>
* <li>The order by clause</li>
* </p>
* <p>
* If Ebean is unable to parse out this information (perhaps because the sql
* contains multiple select from keywords etc) then you need to manually specify
* it.
* </p>
* <p>
* Insert ${where} or ${andWhere} into the location where Ebean can insert any
* expressions added to the where clause. Use ${andWhere} if the sql already has
* the WHERE keyword and Ebean will instead start with a AND keyword.
* </p>
* <p>
* Insert ${having} or ${andHaving} into the location where Ebean can insert any
* expressions added to the having clause. Use ${andHaving} if the sql already
* has a HAVING keyword and Ebean will instead start with a AND keyword.
* </p>
* <p>
* Use the columnMapping property if Ebean is unable to determine the columns
* and map them to bean properties.
* </p>
* <p>
* Example with ${andWhere} & ${having}.
* </p>
*
* <pre class="code">
* &#064;SqlSelect(
* name = &quot;explicit.where&quot;,
* query =
* &quot;select t.id, t.title, count(p.id) as score &quot;+
* &quot;from f_topic t, f_topic_post p &quot;+
* &quot;where p.topic_id = t.id ${andWhere} &quot;+
* &quot;group by t.id, t.title ${having}&quot;),
* </pre>
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Deprecated
public @interface SqlSelect {
/**
* The name of the query. If left blank this is assumed to be the default
* query for this bean type.
* <p>
* This will default to "default" and in that case becomes the default query
* used for the bean.
* </p>
*/
String name() default "default";
/**
* The tableAlias used when adding where expressions to the query.
*/
String tableAlias() default "";
/**
* The sql select statement.
* <p>
* If this query <em>extends</em> another then this string is appended to the
* parent query string. Often when using <em>extend</em> you will leave the
* query part blank and just specify a where and/or having clauses.
* </p>
* <p>
* This sql <em>CAN NOT</em> contain named parameters. You have to put these
* in the separate where and/or having sections.
* </p>
* <p>
* Ebean automatically tries to determine the location in the sql string for
* putting in additional where or having clauses. If Ebean is unable to
* successfully determine this then you have to explicitly specify these
* locations by including
* <em>${where} or ${andWhere} and ${having} or ${andHaving}</em> in the sql.
* </p>
* <p>
* <b>${where}</b> location of where clause (and will add WHERE ... ) <br/>
* Use this when there is no where clause in the sql. If expressions are added
* to the where clause Ebean will put them in at this location starting with
* the WHERE keyword.
* <p>
* <p>
* <b>${andWhere}</b> <br/>
* Use this instead of ${where} if there IS an existing where clause in the
* sql. Ebean will add the expressions starting with the AND keyword.
* <p>
* <b>${having}</b> location of having clause (and will add HAVING... ) <br/>
* </p>
* <p>
* <b>${andHaving}</b> <br/>
* Use this instead of ${having} when there IS an existing HAVING clause.
* Ebean will add the expressions starting with the AND keyword.
* </p>
* <p>
* You can include one of ${where} OR ${andWhere} but not both.
* </p>
* <p>
* You can include one of ${having} OR ${andHaving} but not both.
* </p>
*/
String query() default "";
/**
* Specify the name of a sql-select query that this one 'extends'.
* <p>
* When a query is extended the sql query contents are appended together. The
* where and having clauses are NOT appended but overridden.
* </p>
*/
String extend() default "";
/**
* Specify a where clause typically containing named parameters.
* <p>
* If a where clause is specified with named parameters then they will need to
* be set on the query via {@link Query#setParameter(String, Object)}.
* </p>
* <p>
* In the example below the query specifies a where clause that includes a
* named parameter "likeTitle".
* </p>
*
* <pre class="code">
* ...
* &#064;Entity
* &#064;Sql(select = {
* ...
* &#064;SqlSelect(
* name = &quot;with.title&quot;,
* extend = &quot;default&quot;,
* debug = true,
* where = &quot;title like :likeTitle&quot;)
* })
* public class ReportTopic
* ...
* </pre>
*
* <p>
* Example use of the above named query.
* </p>
*
* <pre class="code">
*
* Query&lt;ReportTopic&gt; query0 = Ebean.createQuery(ReportTopic.class, &quot;with.title&quot;);
*
* query0.set(&quot;likeTitle&quot;, &quot;Bana%&quot;);
*
* List&lt;ReportTopic&gt; list0 = query0.findList();
* </pre>
*
*/
String where() default "";
/**
* Specify a having clause typically containing named parameters.
* <p>
* If a having clause is specified with named parameters then they will need
* to be set on the query via {@link Query#setParameter(String, Object)}.
* </p>
*/
String having() default "";
/**
* (Optional) Explicitly specify column to property mapping.
* <p>
* This is required when Ebean is unable to parse the sql. This could occur if
* the sql contains multiple select keywords etc.
* </p>
* <p>
* Specify the columns and property names they map to in the format.
* </p>
*
* <pre class="code">
* column1 propertyName1, column2 propertyName2, ...
* </pre>
*
* <p>
* Optionally put a AS keyword between the column and property.
* </p>
*
* <pre class="code">
* // the AS keyword is optional
* column1 AS propertyName1, column2 propertyName2, ...
* </pre>
*
* <p>
* <b>column</b> should contain the table alias if there is one
* </p>
* <p>
* <b>propertyName</b> should match the property name.
* </p>
*
* <p>
* Example mapping 5 columns to properties.
* </p>
*
* <pre class="code">
* columnMapping=&quot;t.id, t.bug_body description, t.bug_title as title, count(p.id) as scoreValue&quot;,
* </pre>
*
* <p>
* Without this set Ebean will parse the sql looking for the select clause and
* try to map the columns to property names. It is expected that Ebean will
* not be able to successfully parse some sql and for those cases you should
* specify the column to property mapping explicitly.
* </p>
*
*/
String columnMapping() default "";
/**
* Set this to true to have debug output when Ebean parses the sql-select.
*/
boolean debug() default false;
}
@@ -90,6 +90,16 @@ public @interface Transactional {
*/
int batchSize() default 0;
/**
* Set to false when we want to skip getting generatedKeys.
* <p>
* This is typically used in the case of large batch inserts where we get a
* performance benefit from not calling getGeneratedKeys (as we are going to
* insert a lot of rows and have no need for the Id values after the insert).
* </p>
*/
boolean getGeneratedKeys() default true;
/**
* The transaction isolation level this transaction should have.
* <p>
@@ -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;
/**
* Annotate an entity bean with @View to indicates the bean is based on a view.
* <p>
* As such typically the view is defined in <code>extra-ddl.xml</code> using
* <code>create or replace view ...</code>.
* </p>
* <p>
* When using extra-ddl.xml Ebean will run the resulting DDL script after the
* <code>create-all</code> DDL (which is typically used during development) and for
* DB Migration will copy the scripts as <code>repeatable migration scripts</code> that
* will be run by FlywayDb (or Ebean's own migration runner) when their MD5 hash changes.
* </p>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface View {
/**
* The name of the view this entity bean is based on.
*/
String name();
/**
* Tables this view is dependent on.
* <p>
* This is used with l2 caching to invalidate the query cache. Changes to these
* tables invalidate the query cache for the entity based on this view.
* </p>
*/
String[] dependentTables() default {};
}
@@ -31,6 +31,11 @@ public interface BeanCollection<E> extends Serializable {
ALL
}
/**
* Set the disableLazyLoad state.
*/
void setDisableLazyLoad(boolean disableLazyLoad);
/**
* Load bean from another collection.
*/
@@ -54,10 +59,12 @@ public interface BeanCollection<E> extends Serializable {
void reset(EntityBean ownerBean, String propertyName);
/**
* Return true if the collection is empty and untouched. Used to detect if a
* collection was 'cleared' deliberately or just un-initialised.
* Return true if the collection is uninitialised or is empty without any held modifications.
* <p>
* Returning true means can safely skip cascade save for this bean collection.
* </p>
*/
boolean isEmptyAndUntouched();
boolean isSkipSave();
/**
* Return the bean that owns this collection.
@@ -92,11 +99,6 @@ public interface BeanCollection<E> extends Serializable {
*/
void setFilterMany(ExpressionList<?> filterMany);
/**
* Set a listener to be notified when the BeanCollection is first touched.
*/
void setBeanCollectionTouched(BeanCollectionTouched notify);
/**
* Return true if the collection has been registered with the batch loading context.
*/
@@ -1,20 +0,0 @@
package com.avaje.ebean.bean;
/**
* Used to specify a listener to be notified when a BeanCollection is first
* used.
* <p>
* To use this you can set a BeanCollectionTouched onto a BeanCollection before
* it has been used. When the BeanCollection is first used by the client code
* then the BeanCollectionTouched is notified. It can only be notified once.
* </p>
*
* @author rbygrave
*/
public interface BeanCollectionTouched {
/**
* Notify the listener that the bean collection has been used.
*/
void notifyTouched(BeanCollection<?> c);
}
@@ -34,12 +34,12 @@ public final class CallStack implements Serializable {
public int hashCode() {
int hc = 0;
for (int i = 0; i < callStack.length; i++) {
hc = 31 * hc + callStack[i].hashCode();
for (StackTraceElement aCallStack : callStack) {
hc = 31 * hc + aCallStack.hashCode();
}
return hc;
}
public boolean equals(Object obj) {
if (obj == this) {
return true;
@@ -88,8 +88,8 @@ public final class CallStack implements Serializable {
*/
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);
for (StackTraceElement aCallStack : callStack) {
sb.append(aCallStack.toString()).append(newLine);
}
return sb.toString();
}
@@ -30,7 +30,7 @@ public final class EntityBeanIntercept implements Serializable {
private static final int STATE_NEW = 0;
private static final int STATE_REFERENCE = 1;
private static final int STATE_LOADED = 2;
private transient NodeUsageCollector nodeUsageCollector;
private transient PropertyChangeSupport pcs;
@@ -39,6 +39,8 @@ public final class EntityBeanIntercept implements Serializable {
private transient BeanLoader beanLoader;
private transient PreGetterCallback preGetterCallback;
private String ebeanServerName;
/**
@@ -53,11 +55,11 @@ public final class EntityBeanIntercept implements Serializable {
* One of NEW, REF, UPD.
*/
private int state;
private boolean readOnly;
private boolean dirty;
/**
* Flag set to disable lazy loading - typically for SQL "report" type entity beans.
*/
@@ -72,14 +74,14 @@ public final class EntityBeanIntercept implements Serializable {
* Used when a bean is partially filled.
*/
private final boolean[] loadedProps;
private boolean fullyLoadedBean;
/**
* Set of changed properties.
*/
private boolean[] changedProps;
/**
* Flags indicating if a property is a dirty embedded bean. Used to distingush
* between an embedded bean being completely overwritten and one of its
@@ -178,7 +180,7 @@ public final class EntityBeanIntercept implements Serializable {
public Object getEmbeddedOwner() {
return embeddedOwner;
}
/**
* Return the property index (for the parent) of this embedded bean.
*/
@@ -186,6 +188,21 @@ public final class EntityBeanIntercept implements Serializable {
return embeddedOwnerIndex;
}
/**
* Clear the getter callback.
*/
public void clearGetterCallback() {
this.preGetterCallback = null;
}
/**
* Register the callback to be triggered when getter is called.
* This is used primarily to automatically flush the JDBC batch.
*/
public void registerGetterCallback(PreGetterCallback getterCallback) {
this.preGetterCallback = getterCallback;
}
/**
* Set the embedded beans owning bean.
*/
@@ -223,8 +240,8 @@ public final class EntityBeanIntercept implements Serializable {
* 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]) {
for (boolean loadedProp : loadedProps) {
if (!loadedProp) {
return true;
}
}
@@ -246,7 +263,7 @@ public final class EntityBeanIntercept implements Serializable {
this.dirty = true;
setEmbeddedPropertyDirty(embeddedProperty);
}
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
@@ -273,12 +290,12 @@ public final class EntityBeanIntercept implements Serializable {
if (i == idIndex) {
if (!loadedProps[i]) return false;
} else if (loadedProps[i]) {
return false;
return false;
}
}
return true;
}
/**
* Return true if the entity is a reference.
*/
@@ -295,7 +312,7 @@ public final class EntityBeanIntercept implements Serializable {
// For cases where properties are set on constructor
// set every non Id property to unloaded (for lazy loading)
for (int i=0; i< loadedProps.length; i++) {
if (i != idPos) {
if (i != idPos) {
loadedProps[i] = false;
}
}
@@ -325,6 +342,13 @@ public final class EntityBeanIntercept implements Serializable {
return state == STATE_LOADED;
}
/**
* Set the bean into NEW state.
*/
public void setNew() {
this.state = STATE_NEW;
}
/**
* Set the loaded state to true.
* <p>
@@ -424,7 +448,7 @@ public final class EntityBeanIntercept implements Serializable {
}
return origValues[propertyIndex];
}
/**
* Finds the index position of a given property. Returns -1 if the property
* can not be found.
@@ -438,7 +462,7 @@ public final class EntityBeanIntercept implements Serializable {
}
return -1;
}
/**
* Return the property name for the given property.
*/
@@ -448,7 +472,7 @@ public final class EntityBeanIntercept implements Serializable {
}
return owner._ebean_getPropertyName(propertyIndex);
}
/**
* Return the number of properties.s
*/
@@ -474,7 +498,7 @@ public final class EntityBeanIntercept implements Serializable {
public void setPropertyUnloaded(int propertyIndex) {
loadedProps[propertyIndex] = false;
}
/**
* Set the property to be loaded.
*/
@@ -501,7 +525,7 @@ public final class EntityBeanIntercept implements Serializable {
* embedded properties is dirty.
*/
public boolean isDirtyProperty(int propertyIndex) {
return (changedProps != null && changedProps[propertyIndex]
return (changedProps != null && changedProps[propertyIndex]
|| embeddedDirty != null && embeddedDirty[propertyIndex]);
}
@@ -512,7 +536,7 @@ public final class EntityBeanIntercept implements Serializable {
setChangedProperty(propertyIndex);
setDirty(true);
}
public void setChangedProperty(int propertyIndex) {
if (changedProps == null) {
changedProps = new boolean[owner._ebean_getPropertyNames().length];
@@ -529,7 +553,7 @@ public final class EntityBeanIntercept implements Serializable {
}
embeddedDirty[propertyIndex] = true;
}
private void setOriginalValue(int propertyIndex, Object value) {
if (origValues == null) {
origValues = new Object[owner._ebean_getPropertyNames().length];
@@ -543,19 +567,19 @@ public final class EntityBeanIntercept implements Serializable {
* For forced update on a 'New' bean set all the loaded properties to changed.
*/
public void setNewBeanForUpdate() {
if (changedProps == null) {
changedProps = new boolean[owner._ebean_getPropertyNames().length];
}
for (int i=0; i< loadedProps.length; i++) {
if (loadedProps[i]) {
changedProps[i] = true;
changedProps[i] = true;
}
}
setDirty(true);
}
/**
* Return the set of property names for a partially loaded bean.
*/
@@ -563,7 +587,7 @@ public final class EntityBeanIntercept implements Serializable {
if (fullyLoadedBean) {
return null;
}
Set<String> props = new LinkedHashSet<String>();
Set<String> props = new LinkedHashSet<>();
for (int i=0; i<loadedProps.length; i++) {
if (loadedProps[i]) {
props.add(getProperty(i));
@@ -593,11 +617,11 @@ public final class EntityBeanIntercept implements Serializable {
* Return the set of dirty properties.
*/
public Set<String> getDirtyPropertyNames() {
Set<String> props = new LinkedHashSet<String>();
Set<String> props = new LinkedHashSet<>();
addDirtyPropertyNames(props, null);
return props;
}
/**
* Recursively add dirty properties.
*/
@@ -642,11 +666,11 @@ public final class EntityBeanIntercept implements Serializable {
* Return a map of dirty properties with their new and old values.
*/
public Map<String,ValuePair> getDirtyValues() {
Map<String,ValuePair> dirtyValues = new LinkedHashMap<String, ValuePair>();
Map<String,ValuePair> dirtyValues = new LinkedHashMap<>();
addDirtyPropertyValues(dirtyValues, null);
return dirtyValues;
}
/**
* Recursively add dirty properties.
*/
@@ -660,7 +684,7 @@ public final class EntityBeanIntercept implements Serializable {
Object oldVal = getOrigValue(i);
dirtyValues.put(propName, new ValuePair(newVal, oldVal));
} else if (embeddedDirty != null && embeddedDirty[i]) {
// an embedded property has been changed - recurse
EntityBean embeddedBean = (EntityBean)owner._ebean_getField(i);
@@ -668,14 +692,14 @@ public final class EntityBeanIntercept implements Serializable {
}
}
}
/**
* Return a dirty property hash taking into account embedded beans.
*/
public int getDirtyPropertyHash() {
return addDirtyPropertyHash(37);
}
/**
* Add and return a dirty property hash recursing into embedded beans.
*/
@@ -725,7 +749,7 @@ public final class EntityBeanIntercept implements Serializable {
public int getLazyLoadPropertyIndex() {
return lazyLoadProperty;
}
/**
* Return the property that triggered the lazy load.
*/
@@ -825,26 +849,38 @@ public final class EntityBeanIntercept implements Serializable {
}
return obj1.equals(obj2);
}
/**
* Called when a BeanCollection is initialised automatically.
*/
public void initialisedMany(int propertyIndex) {
loadedProps[propertyIndex] = true;
}
private final void preGetterCallback() {
if (preGetterCallback != null) {
preGetterCallback.preGetterTrigger();
}
}
/**
* Called prior to Id property getter.
*/
public void preGetId() {
preGetterCallback();
}
/**
* Method that is called prior to a getter method on the actual entity.
*/
public void preGetter(int propertyIndex) {
preGetterCallback();
if (state == STATE_NEW || disableLazyLoad) {
return;
}
if (!isLoadedProperty(propertyIndex)) {
loadBean(propertyIndex);
}
if (nodeUsageCollector != null) {
nodeUsageCollector.addUsed(getProperty(propertyIndex));
}
@@ -884,7 +920,7 @@ public final class EntityBeanIntercept implements Serializable {
if (readOnly) {
throw new IllegalStateException("This bean is readOnly");
}
setLoadedProperty(propertyIndex);
// Bean itself not considered dirty when many changed
@@ -894,7 +930,7 @@ public final class EntityBeanIntercept implements Serializable {
return null;
}
}
private void setChangedPropertyValue(int propertyIndex, boolean setDirtyState, Object origValue) {
if (readOnly) {
@@ -905,7 +941,7 @@ public final class EntityBeanIntercept implements Serializable {
if (setDirtyState) {
setOriginalValue(propertyIndex, origValue);
if (!dirty) {
dirty = true;
dirty = true;
if (embeddedOwner != null) {
// Cascade dirty state from Embedded bean to parent bean
embeddedOwner._ebean_getIntercept().setEmbeddedDirty(embeddedOwnerIndex);
@@ -916,7 +952,7 @@ public final class EntityBeanIntercept implements Serializable {
}
}
}
/**
* Check to see if the values are not equal. If they are not equal then create
* the old values for use with ConcurrencyMode.ALL.
@@ -926,15 +962,15 @@ public final class EntityBeanIntercept implements Serializable {
if (state == STATE_NEW) {
setLoadedProperty(propertyIndex);
} else if (!areEqual(oldValue, newValue)) {
setChangedPropertyValue(propertyIndex, intercept, oldValue);
setChangedPropertyValue(propertyIndex, intercept, oldValue);
} else {
return null;
}
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
}
/**
* Check for primitive boolean.
*/
@@ -971,13 +1007,13 @@ public final class EntityBeanIntercept implements Serializable {
public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, long oldValue, long newValue) {
if (state == STATE_NEW) {
setLoadedProperty(propertyIndex);
setLoadedProperty(propertyIndex);
} else if (oldValue != newValue) {
setChangedPropertyValue(propertyIndex, intercept, oldValue);
} else {
return null;
}
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
}
@@ -989,7 +1025,7 @@ public final class EntityBeanIntercept implements Serializable {
if (state == STATE_NEW) {
setLoadedProperty(propertyIndex);
} else if (oldValue != newValue) {
setChangedPropertyValue(propertyIndex, intercept, oldValue);
setChangedPropertyValue(propertyIndex, intercept, oldValue);
} else {
return null;
}
@@ -29,7 +29,7 @@ public final class NodeUsageCollector {
/**
* The properties used at this profile point.
*/
private final Set<String> used = new LinkedHashSet<String>();
private final Set<String> used = new LinkedHashSet<>();
/**
* set to true if the bean is modified (setter called)
@@ -0,0 +1,13 @@
package com.avaje.ebean.bean;
/**
* A callback that can be registered to fire on getter method calls.
* It's primary purpose is to automatically flush JDBC batch buffer.
*/
public interface PreGetterCallback {
/**
* Trigger the callback.
*/
void preGetterTrigger();
}
-23
View File
@@ -1,7 +1,5 @@
package com.avaje.ebean.cache;
import com.avaje.ebean.EbeanServer;
/**
* Represents part of the "L2" server side cache.
* <p>
@@ -17,27 +15,6 @@ import com.avaje.ebean.EbeanServer;
*/
public interface ServerCache {
/**
* Just after a cache is created this init method is called. This is so that a
* cache implementation can make use of the BackgroundExecutor service to
* trim/cleanup itself or use the EbeanServer to populate itself.
* <p>
* This method is called after the cache is constructed but before the cache
* is made available for use.
* </p>
*/
void init(EbeanServer ebeanServer);
/**
* Return the configuration options for this cache.
*/
ServerCacheOptions getOptions();
/**
* Update the configuration options for this cache.
*/
void setOptions(ServerCacheOptions options);
/**
* Return the value given the key.
*/
+1 -14
View File
@@ -1,26 +1,13 @@
package com.avaje.ebean.cache;
import com.avaje.ebean.EbeanServer;
/**
* Defines method for constructing caches for beans and queries.
*/
public interface ServerCacheFactory {
/**
* Just after the ServerCacheFactory is constructed this method is called
* passing the EbeanServer.
* <p>
* This is so that a cache implementation can utilise the EbeanServer to
* populate itself or use the BackgroundExecutor service to schedule periodic
* cache trimming/cleanup.
* </p>
*/
void init(EbeanServer ebeanServer);
/**
* Create the cache for the given type with options.
*/
ServerCache createCache(String cacheKey, ServerCacheOptions cacheOptions);
ServerCache createCache(ServerCacheType type, String cacheKey, ServerCacheOptions cacheOptions);
}
+7 -10
View File
@@ -1,24 +1,18 @@
package com.avaje.ebean.cache;
import com.avaje.ebean.EbeanServer;
/**
* The cache service for server side caching of beans and query results.
*/
public interface ServerCacheManager {
/**
* This method is called just after the construction of the
* ServerCacheManager.
* Return true if the L2 caching is local.
* <p>
* The EbeanServer is provided so that cache implementations can make use of
* EbeanServer and BackgroundExecutor for automatically populating and
* background trimming of the cache.
* Local L2 caching means that the cache updates should occur in foreground
* rather than background processing.
* </p>
*/
void init(EbeanServer server);
void setCaching(Class<?> beanType, boolean useCache);
boolean isLocalL2Caching();
/**
* Return true if there is an active bean cache for this type of bean.
@@ -35,6 +29,9 @@ public interface ServerCacheManager {
*/
ServerCache getBeanCache(Class<?> beanType);
/**
* Return the cache for associated many properties of a bean type.
*/
ServerCache getCollectionIdsCache(Class<?> beanType, String propertyName);
/**
+13 -12
View File
@@ -1,6 +1,7 @@
package com.avaje.ebean.cache;
import com.avaje.ebean.annotation.CacheTuning;
import com.avaje.ebean.annotation.CacheQueryTuning;
import com.avaje.ebean.annotation.CacheBeanTuning;
/**
* Options for controlling a cache.
@@ -22,23 +23,23 @@ public class ServerCacheOptions {
/**
* Create from the cacheTuning deployment annotation.
*/
public ServerCacheOptions(CacheTuning cacheTuning) {
public ServerCacheOptions(CacheBeanTuning tuning) {
this.maxSize = tuning.maxSize();
this.maxIdleSecs = tuning.maxIdleSecs();
this.maxSecsToLive = tuning.maxSecsToLive();
this.trimFrequency = tuning.trimFrequency();
}
/**
* Create from the cacheTuning deployment annotation.
*/
public ServerCacheOptions(CacheQueryTuning cacheTuning) {
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 defaults) {
this.maxSize = defaults.getMaxSize();
this.maxIdleSecs = defaults.getMaxIdleSecs();
this.maxSecsToLive = defaults.getMaxIdleSecs();
this.trimFrequency = defaults.getTrimFrequency();
}
/**
* Apply any settings from the default settings that have not already been
* specifically set.
@@ -0,0 +1,15 @@
package com.avaje.ebean.cache;
import com.avaje.ebean.BackgroundExecutor;
import com.avaje.ebean.config.ServerConfig;
/**
* The plugin interface that creates a ServerCacheFactory.
*/
public interface ServerCachePlugin {
/**
* Create the ServerCacheFactory given the server config and background executor service.
*/
ServerCacheFactory create(ServerConfig config, BackgroundExecutor executor);
}
@@ -0,0 +1,27 @@
package com.avaje.ebean.cache;
/**
* The type of L2 caches.
*/
public enum ServerCacheType {
/**
* Bean cache.
*/
BEAN,
/**
* Natural key cache.
*/
NATURAL_KEY,
/**
* Collection Ids for Many properties.
*/
COLLECTION_IDS,
/**
* Query cache.
*/
QUERY
}
@@ -1,16 +1,14 @@
package com.avaje.ebean.common;
import java.util.Set;
import javax.persistence.PersistenceException;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.ExpressionList;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollectionLoader;
import com.avaje.ebean.bean.BeanCollectionTouched;
import com.avaje.ebean.bean.EntityBean;
import javax.persistence.PersistenceException;
import java.util.Set;
/**
* Base class for List Set and Map implementations of BeanCollection.
*
@@ -22,6 +20,8 @@ public abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
protected boolean readOnly;
protected boolean disableLazyLoad;
/**
* The EbeanServer this is associated with. (used for lazy fetch).
*/
@@ -36,8 +36,6 @@ public abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
protected String ebeanServerName;
protected transient BeanCollectionTouched beanCollectionTouched;
/**
* The owning bean (used for lazy fetch).
*/
@@ -55,12 +53,6 @@ public abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
protected boolean modifyRemoveListening;
protected boolean modifyListening;
/**
* Flag used to tell if empty collections have been cleared etc or just
* uninitialised.
*/
protected boolean touched;
/**
* Constructor not non-lazy loading collection.
*/
@@ -94,6 +86,11 @@ public abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
this.filterMany = filterMany;
}
@Override
public void setDisableLazyLoad(boolean disableLazyLoad) {
this.disableLazyLoad = disableLazyLoad;
}
protected void lazyLoadCollection(boolean onlyIds) {
if (loader == null) {
loader = (BeanCollectionLoader) Ebean.getServer(ebeanServerName);
@@ -109,25 +106,6 @@ public abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
checkEmptyLazyLoad();
}
/**
* Set touched. If setFlag is false then typically an isEmpty() call and still
* considering that to be untouched.
*/
protected void touched(boolean setFlag) {
if (setFlag) {
touched = true;
}
if (beanCollectionTouched != null) {
// only call this once
beanCollectionTouched.notifyTouched(this);
beanCollectionTouched = null;
}
}
public void setBeanCollectionTouched(BeanCollectionTouched notify) {
this.beanCollectionTouched = notify;
}
public boolean isRegisteredWithLoadContext() {
return registeredWithLoadContext;
}
@@ -181,7 +159,7 @@ public abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
protected ModifyHolder<E> getModifyHolder() {
if (modifyHolder == null) {
modifyHolder = new ModifyHolder<E>();
modifyHolder = new ModifyHolder<>();
}
return modifyHolder;
}
@@ -219,4 +197,11 @@ public abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
return modifyHolder.getModifyRemovals();
}
}
/**
* Return true if there are underlying additions or removals.
*/
public boolean holdsModifications() {
return modifyHolder != null && modifyHolder.hasModifications();
}
}
@@ -37,7 +37,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
* Uses an ArrayList as the underlying List implementation.
*/
public BeanList() {
this(new ArrayList<E>());
this(new ArrayList<>());
}
/**
@@ -52,12 +52,11 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
this.ownerBean = ownerBean;
this.propertyName = propertyName;
this.list = null;
this.touched = false;
}
@Override
public boolean isEmptyAndUntouched() {
return !touched && (list == null || list.isEmpty());
public boolean isSkipSave() {
return list == null || (list.isEmpty() && !holdsModifications());
}
@SuppressWarnings("unchecked")
@@ -69,7 +68,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
@SuppressWarnings("unchecked")
public void loadFrom(BeanCollection<?> other) {
if (list == null) {
list = new ArrayList<E>();
list = new ArrayList<>();
}
list.addAll((Collection<? extends E>) other.getActualDetails());
}
@@ -77,7 +76,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
@SuppressWarnings("unchecked")
public void internalAdd(Object bean) {
if (list == null) {
list = new ArrayList<E>();
list = new ArrayList<>();
}
if (bean != null) {
list.add((E) bean);
@@ -93,7 +92,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
public boolean checkEmptyLazyLoad() {
if (list == null) {
list = new ArrayList<E>();
list = new ArrayList<>();
return true;
} else {
return false;
@@ -103,30 +102,24 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
private void initClear() {
synchronized (this) {
if (list == null) {
if (modifyListening) {
if (!disableLazyLoad && modifyListening) {
lazyLoadCollection(true);
} else {
list = new ArrayList<E>();
list = new ArrayList<>();
}
}
touched(true);
}
}
private void initAsUntouched() {
init(false);
}
private void init() {
init(true);
}
private void init(boolean setTouched) {
synchronized (this) {
if (list == null) {
lazyLoadCollection(false);
if (disableLazyLoad) {
list = new ArrayList<>();
} else {
lazyLoadCollection(false);
}
}
touched(setTouched);
}
}
@@ -268,8 +261,8 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
// and fetch just the Id's
initClear();
if (modifyRemoveListening) {
for (int i = 0; i < list.size(); i++) {
getModifyHolder().modifyRemoval(list.get(i));
for (E aList : list) {
getModifyHolder().modifyRemoval(aList);
}
}
list.clear();
@@ -296,18 +289,18 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
}
public boolean isEmpty() {
initAsUntouched();
init();
return list.isEmpty();
}
public Iterator<E> iterator() {
init();
if (isReadOnly()) {
return new ReadOnlyListIterator<E>(list.listIterator());
return new ReadOnlyListIterator<>(list.listIterator());
}
if (modifyListening) {
Iterator<E> it = list.iterator();
return new ModifyIterator<E>(this, it);
return new ModifyIterator<>(this, it);
}
return list.iterator();
}
@@ -320,11 +313,11 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
public ListIterator<E> listIterator() {
init();
if (isReadOnly()) {
return new ReadOnlyListIterator<E>(list.listIterator());
return new ReadOnlyListIterator<>(list.listIterator());
}
if (modifyListening) {
ListIterator<E> it = list.listIterator();
return new ModifyListIterator<E>(this, it);
return new ModifyListIterator<>(this, it);
}
return list.listIterator();
}
@@ -332,11 +325,11 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
public ListIterator<E> listIterator(int index) {
init();
if (isReadOnly()) {
return new ReadOnlyListIterator<E>(list.listIterator(index));
return new ReadOnlyListIterator<>(list.listIterator(index));
}
if (modifyListening) {
ListIterator<E> it = list.listIterator(index);
return new ModifyListIterator<E>(this, it);
return new ModifyListIterator<>(this, it);
}
return list.listIterator(index);
}
@@ -432,7 +425,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
return Collections.unmodifiableList(list.subList(fromIndex, toIndex));
}
if (modifyListening) {
return new ModifyList<E>(this, list.subList(fromIndex, toIndex));
return new ModifyList<>(this, list.subList(fromIndex, toIndex));
}
return list.subList(fromIndex, toIndex);
}
@@ -33,7 +33,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
* Create using a underlying LinkedHashMap.
*/
public BeanMap() {
this(new LinkedHashMap<K, E>());
this(new LinkedHashMap<>());
}
public BeanMap(BeanCollectionLoader ebeanServer, EntityBean ownerBean, String propertyName) {
@@ -45,11 +45,10 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
this.ownerBean = ownerBean;
this.propertyName = propertyName;
this.map = null;
this.touched = false;
}
public boolean isEmptyAndUntouched() {
return !touched && (map == null || map.isEmpty());
public boolean isSkipSave() {
return map == null || (map.isEmpty() && !holdsModifications());
}
@Override
@@ -62,14 +61,14 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
public void internalPutNull() {
if (map == null) {
map = new LinkedHashMap<K, E>();
map = new LinkedHashMap<>();
}
}
@SuppressWarnings("unchecked")
public void internalPut(Object key, Object bean) {
if (map == null) {
map = new LinkedHashMap<K, E>();
map = new LinkedHashMap<>();
}
if (key != null) {
map.put((K) key, (E) bean);
@@ -109,7 +108,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
public boolean checkEmptyLazyLoad() {
if (map == null) {
map = new LinkedHashMap<K, E>();
map = new LinkedHashMap<>();
return true;
} else {
return false;
@@ -122,27 +121,17 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
if (modifyListening) {
lazyLoadCollection(true);
} else {
map = new LinkedHashMap<K, E>();
map = new LinkedHashMap<>();
}
}
touched(true);
}
}
private void initAsUntouched() {
init(false);
}
private void init() {
init(true);
}
private void init(boolean setTouched) {
synchronized (this) {
if (map == null) {
lazyLoadCollection(false);
}
touched(setTouched);
}
}
@@ -249,7 +238,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
}
public boolean isEmpty() {
initAsUntouched();
init();
return map.isEmpty();
}
@@ -276,7 +265,6 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
return map.put(key, value);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void putAll(Map<? extends K, ? extends E> puts) {
checkReadOnly();
init();
@@ -325,7 +313,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
}
if (modifyListening) {
Collection<E> c = map.values();
return new ModifyCollection<E>(this, c);
return new ModifyCollection<>(this, c);
}
return map.values();
}
@@ -34,7 +34,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
* Create using an underlying LinkedHashSet.
*/
public BeanSet() {
this(new LinkedHashSet<E>());
this(new LinkedHashSet<>());
}
public BeanSet(BeanCollectionLoader loader, EntityBean ownerBean, String propertyName) {
@@ -46,11 +46,10 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
this.ownerBean = ownerBean;
this.propertyName = propertyName;
this.set = null;
this.touched = false;
}
public boolean isEmptyAndUntouched() {
return !touched && (set == null || set.isEmpty());
public boolean isSkipSave() {
return set == null || (set.isEmpty() && !holdsModifications());
}
@SuppressWarnings("unchecked")
@@ -62,7 +61,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
@SuppressWarnings("unchecked")
public void loadFrom(BeanCollection<?> other) {
if (set == null) {
set = new LinkedHashSet<E>();
set = new LinkedHashSet<>();
}
set.addAll((Collection<? extends E>) other.getActualDetails());
}
@@ -77,7 +76,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
@SuppressWarnings("unchecked")
public void internalAdd(Object bean) {
if (set == null) {
set = new LinkedHashSet<E>();
set = new LinkedHashSet<>();
}
if (bean != null) {
set.add((E) bean);
@@ -101,7 +100,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
public boolean checkEmptyLazyLoad() {
if (set == null) {
set = new LinkedHashSet<E>();
set = new LinkedHashSet<>();
return true;
} else {
return false;
@@ -114,27 +113,17 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
if (modifyListening) {
lazyLoadCollection(true);
} else {
set = new LinkedHashSet<E>();
set = new LinkedHashSet<>();
}
}
touched(true);
}
}
private void initAsUntouched() {
init(false);
}
private void init() {
init(true);
}
private void init(boolean setTouched) {
synchronized (this) {
if (set == null) {
lazyLoadCollection(true);
}
touched(setTouched);
}
}
@@ -260,17 +249,17 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
}
public boolean isEmpty() {
initAsUntouched();
init();
return set.isEmpty();
}
public Iterator<E> iterator() {
init();
if (isReadOnly()) {
return new ReadOnlyIterator<E>(set.iterator());
return new ReadOnlyIterator<>(set.iterator());
}
if (modifyListening) {
return new ModifyIterator<E>(this, set.iterator());
return new ModifyIterator<>(this, set.iterator());
}
return set.iterator();
}
@@ -72,7 +72,7 @@ class ModifyCollection<E> implements Collection<E> {
@Override
public Iterator<E> iterator() {
Iterator<E> it = c.iterator();
return new ModifyIterator<E>(owner, it);
return new ModifyIterator<>(owner, it);
}
@Override
@@ -21,16 +21,16 @@ class ModifyHolder<E> implements Serializable {
/**
* Deletions list for manyToMany persistence.
*/
private Set<E> modifyDeletions = new LinkedHashSet<E>();
private Set<E> modifyDeletions = new LinkedHashSet<>();
/**
* Additions list for manyToMany persistence.
*/
private Set<E> modifyAdditions = new LinkedHashSet<E>();
private Set<E> modifyAdditions = new LinkedHashSet<>();
void reset() {
modifyDeletions = new LinkedHashSet<E>();
modifyAdditions = new LinkedHashSet<E>();
modifyDeletions = new LinkedHashSet<>();
modifyAdditions = new LinkedHashSet<>();
}
/**
@@ -71,4 +71,11 @@ class ModifyHolder<E> implements Serializable {
Set<E> getModifyRemovals() {
return modifyDeletions;
}
/**
* Return true if there additions or removals.
*/
boolean hasModifications() {
return !modifyDeletions.isEmpty() || !modifyAdditions.isEmpty();
}
}
@@ -61,11 +61,11 @@ class ModifyList<E> extends ModifyCollection<E> implements List<E> {
}
public ListIterator<E> listIterator() {
return new ModifyListIterator<E>(owner, list.listIterator());
return new ModifyListIterator<>(owner, list.listIterator());
}
public ListIterator<E> listIterator(int index) {
return new ModifyListIterator<E>(owner, list.listIterator(index));
return new ModifyListIterator<>(owner, list.listIterator(index));
}
public E remove(int index) {
@@ -82,7 +82,7 @@ class ModifyList<E> extends ModifyCollection<E> implements List<E> {
}
public List<E> subList(int fromIndex, int toIndex) {
return new ModifyList<E>(owner, list.subList(fromIndex, toIndex));
return new ModifyList<>(owner, list.subList(fromIndex, toIndex));
}
}
@@ -274,7 +274,7 @@ public abstract class AbstractNamingConvention implements NamingConvention {
* Checks string is null or empty .
*/
protected boolean isEmpty(String s) {
return s == null || s.trim().length() == 0;
return s == null || s.trim().isEmpty();
}
/**
@@ -1,6 +1,10 @@
package com.avaje.ebean.config;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
/**
* Helper to find classes taking into account the context class loader.
*/
@@ -29,6 +33,13 @@ public class ClassLoadConfig {
return isPresent("java.time.LocalDate");
}
/**
* Return true if Java7 is present.
*/
public boolean isJava7Present() {
return isPresent("java.nio.file.Path");
}
/**
* Return true if the Joda types are available and should be supported.
*/
@@ -70,10 +81,17 @@ public class ClassLoadConfig {
}
}
/**
* Return the resources for the given name.
*/
public Enumeration<URL> getResources(String name) throws IOException {
return context.getResources(name);
}
/**
* Return true if the given class is present.
*/
protected boolean isPresent(String className) {
public boolean isPresent(String className) {
try {
forName(className);
return true;
@@ -122,6 +140,13 @@ public class ClassLoadConfig {
return (loader != null) ? loader: callerLoader;
}
Enumeration<URL> getResources(String name) throws IOException {
if (preferredLoader != null) {
return preferredLoader.getResources(name);
}
return contextLoader().getResources(name);
}
Class<?> forName(String name) throws ClassNotFoundException {
if (preferredLoader != null) {
@@ -1,7 +1,5 @@
package com.avaje.ebean.config;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
/**
@@ -12,453 +10,51 @@ import java.util.Properties;
*/
public class ContainerConfig {
protected boolean clusterActive;
protected Properties properties;
/**
* Communication mode used for clustering.
* Return true if clustering is active.
*/
public enum ClusterMode {
/**
* No clustering.
*/
NONE,
/**
* Use Multicast networking for cluster wide communication.
*/
MULTICAST,
/**
* Use TCP Sockets for cluster wide communication.
*/
SOCKET
public boolean isClusterActive() {
return clusterActive;
}
/**
* The cluster mode to use.
* Set to true for clustering to be active.
*/
ClusterMode mode = ClusterMode.NONE;
/**
* Configuration if using TCP sockets for clustering communication.
*/
SocketConfig socketConfig = new SocketConfig();
/**
* Configuration if using Multicast for clustering communication.
*/
MulticastConfig multicastConfig = new MulticastConfig();
// -------------------------------------------------------------------------------------------
// MulticastConfig
/**
* The configuration for clustering using Multicast networking.
*/
public static class MulticastConfig {
int managerSleepMillis = 80;
int lastSendTimeFreqSecs = 300;//5mins
int lastStatusTimeFreqSecs = 600;//10mins
int maxResendOutgoingAttempts = 200;
int maxResendIncomingRequests = 50;
int listenPort;
String listenAddress;
int sendPort;
String sendAddress;
// Note 1500 is Ethernet MTU and this must be less than UDP max packet size of 65507
int maxSendPacketSize = 1500;
// Whether to send packets even when there are no other members online
boolean sendWithNoMembers = true;
// When multiple instances are on same box you need to broadcast back locally
boolean disableLoopback;
int listenTimeToLive = -1;
int listenTimeout = 1000;
int listenBufferSize = 65500;
// For multihomed environment the address the listener should bind to
String listenBindAddress;
/**
* Return the manager sleep millis.
*/
public int getManagerSleepMillis() {
return managerSleepMillis;
}
/**
* Set the manager sleep millis.
*/
public void setManagerSleepMillis(int managerSleepMillis) {
this.managerSleepMillis = managerSleepMillis;
}
/**
* Return the last send time frequency.
*/
public int getLastSendTimeFreqSecs() {
return lastSendTimeFreqSecs;
}
/**
* Set the last send time frequency.
*/
public void setLastSendTimeFreqSecs(int lastSendTimeFreqSecs) {
this.lastSendTimeFreqSecs = lastSendTimeFreqSecs;
}
/**
* Return the last status time frequency.
*/
public int getLastStatusTimeFreqSecs() {
return lastStatusTimeFreqSecs;
}
/**
* Set the last status time frequency.
*/
public void setLastStatusTimeFreqSecs(int lastStatusTimeFreqSecs) {
this.lastStatusTimeFreqSecs = lastStatusTimeFreqSecs;
}
/**
* Return the maximum number of times we will try to re-send a given packet before giving up sending
*/
public int getMaxResendOutgoingAttempts() {
return maxResendOutgoingAttempts;
}
/**
* Set the maximum retry attempts for outgoing messages.
*/
public void setMaxResendOutgoingAttempts(int maxResendOutgoingAttempts) {
this.maxResendOutgoingAttempts = maxResendOutgoingAttempts;
}
/**
* Return the maximum number of times we will ask for a packet to be resent to us before giving up asking.
*/
public int getMaxResendIncomingRequests() {
return maxResendIncomingRequests;
}
/**
* Set the maximum retry attempts for incoming messages.
*/
public void setMaxResendIncomingRequests(int maxResendIncomingRequests) {
this.maxResendIncomingRequests = maxResendIncomingRequests;
}
/**
* Return the listen port.
*/
public int getListenPort() {
return listenPort;
}
/**
* Set the listen port.
*/
public void setListenPort(int port) {
this.listenPort = port;
}
/**
* Return the listen address.
*/
public String getListenAddress() {
return listenAddress;
}
/**
* Set the listen address.
*/
public void setListenAddress(String listenAddress) {
this.listenAddress = listenAddress;
}
/**
* Return the send port.
*/
public int getSendPort() {
return sendPort;
}
/**
* Set the send port.
*/
public void setSendPort(int sendPort) {
this.sendPort = sendPort;
}
/**
* Return the send address.
*/
public String getSendAddress() {
return sendAddress;
}
/**
* Set the send address.
*/
public void setSendAddress(String sendAddress) {
this.sendAddress = sendAddress;
}
/**
* Return the maximum send packet size.
*/
public int getMaxSendPacketSize() {
return maxSendPacketSize;
}
/**
* Set the maximum send packet size. Note 1500 is Ethernet MTU and this must be less than UDP max packet size of 65507.
*/
public void setMaxSendPacketSize(int maxSendPacketSize) {
this.maxSendPacketSize = maxSendPacketSize;
}
/**
* Return true if send messages when no other members in the cluster are up.
*/
public boolean isSendWithNoMembers() {
return sendWithNoMembers;
}
/**
* Set true if send messages when no other members in the cluster are up.
*/
public void setSendWithNoMembers(boolean sendWithNoMembers) {
this.sendWithNoMembers = sendWithNoMembers;
}
/**
* Return true if loopback is disabled. When multiple instances are on same box you need to broadcast back locally.
*/
public boolean isDisableLoopback() {
return disableLoopback;
}
/**
* Set if loopback is disabled. When multiple instances are on same box you need to broadcast back locally.
*/
public void setDisableLoopback(boolean disableLoopback) {
this.disableLoopback = disableLoopback;
}
/**
* Return the listen time to live.
*/
public int getListenTimeToLive() {
return listenTimeToLive;
}
/**
* Set the listen time to live.
*/
public void setListenTimeToLive(int listenTimeToLive) {
this.listenTimeToLive = listenTimeToLive;
}
/**
* Return the listen timeout.
*/
public int getListenTimeout() {
return listenTimeout;
}
/**
* set the listen timeout.
*/
public void setListenTimeout(int listenTimeout) {
this.listenTimeout = listenTimeout;
}
/**
* Return the listen buffer size.
*/
public int getListenBufferSize() {
return listenBufferSize;
}
/**
* Set the listen buffer size.
*/
public void setListenBufferSize(int listenBufferSize) {
this.listenBufferSize = listenBufferSize;
}
/**
* Return the listener bind address (optional). For multihomed environment the address the listener should bind to.
*/
public String getListenBindAddress() {
return listenBindAddress;
}
/**
* Set the listener bind address (optional). For multihomed environment the address the listener should bind to.
*/
public void setListenBindAddress(String listenBindAddress) {
this.listenBindAddress = listenBindAddress;
}
public void setClusterActive(boolean clusterActive) {
this.clusterActive = clusterActive;
}
// -------------------------------------------------------------------------------------------
// SocketConfig
/**
* Configuration for clustering using TCP sockets.
* <p>
* This is good for when there are relatively small number of cluster members.
* Return the deployment properties.
*/
public static class SocketConfig {
/**
* This local server in host:port format.
*/
String localHostPort;
/**
* All the cluster members in host:port format.
*/
List<String> members = new ArrayList<String>();
/**
* core threads for the associated thread pool.
*/
int coreThreads = 2;
/**
* Max threads for the associated thread pool.
*/
int maxThreads = 16;
String threadPoolName = "EbeanCluster";
/**
* Return the host and port for this server instance.
*/
public String getLocalHostPort() {
return localHostPort;
}
/**
* Set the host and port for this server instance.
*/
public void setLocalHostPort(String localHostPort) {
this.localHostPort = localHostPort;
}
/**
* Return all the host and port for all the members of the cluster.
*/
public List<String> getMembers() {
return members;
}
/**
* Set all the host and port for all the members of the cluster.
*/
public void setMembers(List<String> members) {
this.members = members;
}
/**
* Return the number of core threads to use.
*/
public int getCoreThreads() {
return coreThreads;
}
/**
* Set the number of core threads to use.
*/
public void setCoreThreads(int coreThreads) {
this.coreThreads = coreThreads;
}
/**
* Return the number of max threads to use.
*/
public int getMaxThreads() {
return maxThreads;
}
/**
* Set the number of max threads to use.
*/
public void setMaxThreads(int maxThreads) {
this.maxThreads = maxThreads;
}
/**
* Return the thread pool name.
*/
public String getThreadPoolName() {
return threadPoolName;
}
/**
* Set the thread pool name.
*/
public void setThreadPoolName(String threadPoolName) {
this.threadPoolName = threadPoolName;
}
public Properties getProperties() {
return properties;
}
// -------------------------------------------------------------------------------------------
// Members
/**
* Set the deployment properties.
*/
public void setProperties(Properties properties) {
this.properties = properties;
}
/**
* Load the settings from properties.
*/
public void loadFromProperties(Properties properties) {
//TODO
this.properties = properties;
this.clusterActive = getProperty(properties, "ebean.cluster.active", clusterActive);
}
/**
* Return the cluster mode.
* Return the boolean property setting.
*/
public ClusterMode getMode() {
return mode;
protected boolean getProperty(Properties properties, String key, boolean defaultValue) {
return "true".equalsIgnoreCase(properties.getProperty(key, Boolean.toString(defaultValue)));
}
/**
* Set the cluster mode.
*/
public void setMode(ClusterMode mode) {
this.mode = mode;
}
/**
* Return the socket communication configuration.
*/
public SocketConfig getSocketConfig() {
return socketConfig;
}
/**
* Set the socket communication configuration.
*/
public void setSocketConfig(SocketConfig socketConfig) {
this.socketConfig = socketConfig;
}
/**
* Return the multicast communication configuration.
*/
public MulticastConfig getMulticastConfig() {
return multicastConfig;
}
/**
* Set the multicast communication configuration.
*/
public void setMulticastConfig(MulticastConfig multicastConfig) {
this.multicastConfig = multicastConfig;
}
}
@@ -0,0 +1,54 @@
package com.avaje.ebean.config;
import com.avaje.ebean.config.dbplatform.DbType;
/**
* Custom mappings for DB types that override the default.
*
* @see ServerConfig#addCustomMapping(DbType, String)
*/
public class CustomDbTypeMapping {
protected final DbType type;
protected final String columnDefinition;
protected final Platform platform;
/**
* Create a mapping.
*/
public CustomDbTypeMapping(DbType type, String columnDefinition, Platform platform) {
this.type = type;
this.columnDefinition = columnDefinition;
this.platform = platform;
}
/**
* Create a mapping that should apply to all the database platforms.
*/
public CustomDbTypeMapping(DbType type, String columnDefinition) {
this(type, columnDefinition, null);
}
/**
* Return the DB type the mapping applies to.
*/
public DbType getType() {
return type;
}
/**
* Return the DB column definition to use.
*/
public String getColumnDefinition() {
return columnDefinition;
}
/**
* Return the platform this mapping should apply to. Null means it applied to all platforms.
*/
public Platform getPlatform() {
return platform;
}
}
@@ -78,8 +78,8 @@ public class DbConstraintNormalise {
public boolean notQuoted(String tableName) {
// remove quoted identifier characters
for (int i = 0; i < quotedIdentifiers.length; i++) {
if (tableName.contains(quotedIdentifiers[i])) {
for (String quotedIdentifier : quotedIdentifiers) {
if (tableName.contains(quotedIdentifier)) {
return false;
}
}
@@ -95,8 +95,8 @@ public class DbConstraintNormalise {
return "";
}
// remove quoted identifier characters
for (int i = 0; i < quotedIdentifiers.length; i++) {
tableName = tableName.replace(quotedIdentifiers[i], "");
for (String quotedIdentifier : quotedIdentifiers) {
tableName = tableName.replace(quotedIdentifier, "");
}
return tableName;
}
@@ -1,11 +1,14 @@
package com.avaje.ebean.config;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.config.dbplatform.DbPlatformName;
import com.avaje.ebean.dbmigration.DbMigration;
import org.avaje.dbmigration.MigrationConfig;
import org.avaje.dbmigration.MigrationRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
/**
* Configuration for the DB migration processing.
*/
@@ -16,7 +19,7 @@ public class DbMigrationConfig {
/**
* The database platform to generate migration DDL for.
*/
protected DbPlatformName platform;
protected Platform platform;
/**
* Set to true if the DB migration should be generated on server start.
@@ -58,6 +61,11 @@ public class DbMigrationConfig {
protected String applySuffix = ".sql";
/**
* Set this to "V" to be compatible with FlywayDB.
*/
protected String applyPrefix = "";
protected String modelSuffix = ".model.xml";
protected boolean includeGeneratedFileComment;
@@ -67,20 +75,50 @@ public class DbMigrationConfig {
*/
protected String generatePendingDrop;
/**
* For running migration the DB table that holds migration execution status.
*/
protected String metaTable = "db_migration";
/**
* Flag set to true means to run any outstanding migrations on startup.
*/
protected boolean runMigration;
/**
* Comma and equals delimited key/value placeholders to replace in DDL scripts.
*/
protected String runPlaceholders;
/**
* Map of key/value placeholders to replace in DDL scripts.
*/
protected Map<String,String> runPlaceholderMap;
/**
* DB user used to run the DB migration.
*/
protected String dbUsername;
/**
* DB password used to run the DB migration.
*/
protected String dbPassword;
/**
* Return the DB platform to generate migration DDL for.
*
* We typically need to explicitly specify this as migration can often be generated
* when running against H2.
*/
public DbPlatformName getPlatform() {
public Platform getPlatform() {
return platform;
}
/**
* Set the DB platform to generate migration DDL for.
*/
public void setPlatform(DbPlatformName platform) {
public void setPlatform(Platform platform) {
this.platform = platform;
}
@@ -145,6 +183,20 @@ public class DbMigrationConfig {
this.applySuffix = applySuffix;
}
/**
* Return the apply prefix.
*/
public String getApplyPrefix() {
return applyPrefix;
}
/**
* Set the apply prefix. This might be set to "V" for use with FlywayDB.
*/
public void setApplyPrefix(String applyPrefix) {
this.applyPrefix = applyPrefix;
}
/**
* Return true if the generated file comment should be included.
*/
@@ -192,34 +244,144 @@ public class DbMigrationConfig {
}
/**
* Set the model, rollback and drop paths to be empty such that all the migration files are generated
* into a single directory.
* Return the table name that holds the migration run details
* (used by DB Migration runner only).
*/
public void singleDirectory() {
this.modelPath = "";
public String getMetaTable() {
return metaTable;
}
/**
* Set the table name that holds the migration run details
* (used by DB Migration runner only).
*/
public void setMetaTable(String metaTable) {
this.metaTable = metaTable;
}
/**
* Return a comma and equals delimited placeholders that are substituted in SQL scripts when running migration
* (used by DB Migration runner only).
*/
public String getRunPlaceholders() {
// environment properties take precedence
String placeholders = readEnvironment("ddl.migration.placeholders");
if (placeholders != null) {
return placeholders;
}
return runPlaceholders;
}
/**
* Set a comma and equals delimited placeholders that are substituted in SQL scripts when running migration
* (used by DB Migration runner only).
*/
public void setRunPlaceholders(String runPlaceholders) {
this.runPlaceholders = runPlaceholders;
}
/**
* Return a map of placeholder values that are substituted in SQL scripts when running migration
* (used by DB Migration runner only).
*/
public Map<String, String> getRunPlaceholderMap() {
return runPlaceholderMap;
}
/**
* Set a map of placeholder values that are substituted when running migration
* (used by DB Migration runner only).
*/
public void setRunPlaceholderMap(Map<String, String> runPlaceholderMap) {
this.runPlaceholderMap = runPlaceholderMap;
}
/**
* Return true if the DB migration should be run on startup.
*/
public boolean isRunMigration() {
// environment properties take precedence
String run = readEnvironment("ddl.migration.run");
if (run != null) {
return "true".equalsIgnoreCase(run.trim());
}
return runMigration;
}
/**
* Set to true to run the DB migration on startup.
*/
public void setRunMigration(boolean runMigration) {
this.runMigration = runMigration;
}
/**
* Return the DB username to use for running DB migrations.
*/
public String getDbUsername() {
// environment properties take precedence
String user = readEnvironment("ddl.migration.user");
if (user != null) {
return user;
}
return dbUsername;
}
/**
* Set the DB username to use for running DB migrations.
*/
public void setDbUsername(String dbUsername) {
this.dbUsername = dbUsername;
}
/**
* Return the DB password to use for running DB migrations.
*/
public String getDbPassword() {
String user = readEnvironment("ddl.migration.password");
if (user != null) {
return user;
}
return dbPassword;
}
/**
* Set the DB password to use for running DB migrations.
*/
public void setDbPassword(String dbPassword) {
this.dbPassword = dbPassword;
}
/**
* Load the settings from the PropertiesWrapper.
*/
public void loadSettings(PropertiesWrapper properties) {
public void loadSettings(PropertiesWrapper properties, String serverName) {
migrationPath = properties.get("migration.migrationPath", migrationPath);
if (properties.getBoolean("migration.singleDirectory", false)) {
singleDirectory();
} else {
modelPath = properties.get("migration.modelPath", modelPath);
}
modelPath = properties.get("migration.modelPath", modelPath);
applyPrefix = properties.get("migration.applyPrefix", applyPrefix);
applySuffix = properties.get("migration.applySuffix", applySuffix);
modelSuffix = properties.get("migration.modelSuffix", modelSuffix);
includeGeneratedFileComment = properties.getBoolean("migration.includeGeneratedFileComment", includeGeneratedFileComment);
generatePendingDrop = properties.get("migration.generatePendingDrop", generatePendingDrop);
platform = properties.getEnum(DbPlatformName.class, "migration.platform", platform);
platform = properties.getEnum(Platform.class, "migration.platform", platform);
generate = properties.getBoolean("migration.generate", generate);
version = properties.get("migration.version", version);
name = properties.get("migration.name", name);
runMigration = properties.getBoolean("migration.run", runMigration);
metaTable = properties.get("migration.metaTable", metaTable);
runPlaceholders = properties.get("migration.placeholders", runPlaceholders);
String adminUser = properties.get("datasource."+serverName+".username", dbUsername);
adminUser = properties.get("datasource."+serverName+".adminusername", adminUser);
dbUsername = properties.get("migration.dbusername", adminUser);
String adminPwd = properties.get("datasource."+serverName+".password", dbPassword);
adminPwd = properties.get("datasource."+serverName+".adminpassword", adminPwd);
dbPassword = properties.get("migration.dbpassword", adminPwd);
}
/**
@@ -321,4 +483,20 @@ public class DbMigrationConfig {
return val == null || val.trim().isEmpty();
}
/**
* Create the MigrationRunner to run migrations if necessary.
*/
public MigrationRunner createRunner(ClassLoader classLoader) {
MigrationConfig runnerConfig = new MigrationConfig();
runnerConfig.setMetaTable(metaTable);
runnerConfig.setApplySuffix(applySuffix);
runnerConfig.setMigrationPath(migrationPath);
runnerConfig.setRunPlaceholderMap(runPlaceholderMap);
runnerConfig.setRunPlaceholders(runPlaceholders);
runnerConfig.setDbUsername(getDbUsername());
runnerConfig.setDbPassword(getDbPassword());
runnerConfig.setClassLoader(classLoader);
return new MigrationRunner(runnerConfig);
}
}
@@ -0,0 +1,123 @@
package com.avaje.ebean.config;
import com.avaje.ebean.config.dbplatform.DbType;
import com.avaje.ebean.config.dbplatform.IdType;
import java.util.ArrayList;
import java.util.List;
/**
* Configuration for DB types such as UUID, Geometry etc.
*/
public class DbTypeConfig {
/**
* The Geometry SRID value (default 4326).
*/
private int geometrySRID = 4326;
/**
* Set for DB's that support both Sequence and Identity (and the default choice is not desired).
*/
private IdType idType;
/**
* Setting to indicate if UUID should be stored as binary(16) or varchar(40) or native DB type (for H2 and Postgres).
*/
private ServerConfig.DbUuid dbUuid = ServerConfig.DbUuid.AUTO_VARCHAR;
/**
* Modify the default mapping of standard types such as default precision for DECIMAL etc.
*/
private List<CustomDbTypeMapping> customDbTypeMappings = new ArrayList<>();
/**
* Return the Geometry SRID.
*/
public int getGeometrySRID() {
return geometrySRID;
}
/**
* Set the Geometry SRID.
*/
public void setGeometrySRID(int geometrySRID) {
this.geometrySRID = geometrySRID;
}
/**
* Return the DB type used to store UUID.
*/
public ServerConfig.DbUuid getDbUuid() {
return dbUuid;
}
/**
* Set the DB type used to store UUID.
*/
public void setDbUuid(ServerConfig.DbUuid dbUuid) {
this.dbUuid = dbUuid;
}
/**
* Return the IdType to use (or null for the default choice).
*/
public IdType getIdType() {
return idType;
}
/**
* Set the IdType to use (when the DB supports both SEQUENCE and IDENTITY and the default is not desired).
*/
public void setIdType(IdType idType) {
this.idType = idType;
}
/**
* Add a custom type mapping.
* <p>
* <pre>{@code
*
* // set the default mapping for BigDecimal.class/decimal
* serverConfig.addCustomMapping(DbType.DECIMAL, "decimal(18,6)");
*
* // set the default mapping for String.class/varchar but only for Postgres
* serverConfig.addCustomMapping(DbType.VARCHAR, "text", Platform.POSTGRES);
*
* }</pre>
*
* @param type The DB type this mapping should apply to
* @param columnDefinition The column definition that should be used
* @param platform Optionally specify the platform this mapping should apply to.
*/
public void addCustomMapping(DbType type, String columnDefinition, Platform platform) {
customDbTypeMappings.add(new CustomDbTypeMapping(type, columnDefinition, platform));
}
/**
* Add a custom type mapping that applies to all platforms.
* <p>
* <pre>{@code
*
* // set the default mapping for BigDecimal/decimal
* serverConfig.addCustomMapping(DbType.DECIMAL, "decimal(18,6)");
*
* // set the default mapping for String/varchar
* serverConfig.addCustomMapping(DbType.VARCHAR, "text");
*
* }</pre>
*
* @param type The DB type this mapping should apply to
* @param columnDefinition The column definition that should be used
*/
public void addCustomMapping(DbType type, String columnDefinition) {
customDbTypeMappings.add(new CustomDbTypeMapping(type, columnDefinition));
}
/**
* Return the list of custom type mappings.
*/
public List<CustomDbTypeMapping> getCustomTypeMappings() {
return customDbTypeMappings;
}
}
@@ -83,7 +83,6 @@ public class DocStoreConfig {
if (systemValue != null) {
return systemValue;
}
return url;
}
@@ -100,6 +99,10 @@ public class DocStoreConfig {
* Return true if Ebean should generate mapping files on server startup.
*/
public boolean isGenerateMapping() {
String systemValue = System.getProperty("ebean.docstore.generateMapping");
if (systemValue != null) {
return Boolean.parseBoolean(systemValue);
}
return generateMapping;
}
@@ -114,6 +117,10 @@ public class DocStoreConfig {
* Return true if the document store should recreate mapped indexes.
*/
public boolean isDropCreate() {
String systemValue = System.getProperty("ebean.docstore.dropCreate");
if (systemValue != null) {
return Boolean.parseBoolean(systemValue);
}
return dropCreate;
}
@@ -129,6 +136,10 @@ public class DocStoreConfig {
* This is only used if dropCreate is false.
*/
public boolean isCreate() {
String systemValue = System.getProperty("ebean.docstore.create");
if (systemValue != null) {
return Boolean.parseBoolean(systemValue);
}
return create;
}
@@ -0,0 +1,22 @@
package com.avaje.ebean.config;
/**
* A customer Id generator that can be registered with Ebean and
* assigned to @Id properties using the name attribute of @GeneratedValue.
*/
public interface IdGenerator {
/**
* Return the next Id value.
*/
Object nextValue();
/**
* Return the name of the IdGenerator.
* <p>
* The name is used to assign the IdGenerator to a property using
* <code>@GeneratedValue(name="myGeneratorName")</code>
* </p>
*/
String getName();
}
@@ -1,9 +1,9 @@
package com.avaje.ebean.config.dbplatform;
package com.avaje.ebean.config;
/**
* Built in supported platforms.
*/
public enum DbPlatformName {
public enum Platform {
/**
* Generic base platform configured via properties or code.
@@ -16,7 +16,7 @@ public final class PropertyMap implements Serializable {
private static final long serialVersionUID = 1L;
private final LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
private final LinkedHashMap<String, String> map = new LinkedHashMap<>();
/**
* Return properties loaded from test-ebean.properties.
@@ -31,6 +31,11 @@ public final class PropertyMap implements Serializable {
return (propertyMap == null) ? new Properties() : propertyMap.asProperties();
}
public static boolean loadTestProperties() {
String disable = System.getProperty("disableTestProperties");
return (disable == null || !disable.equalsIgnoreCase("true"));
}
public String toString() {
return map.toString();
}
@@ -18,6 +18,9 @@ final class PropertyMapLoader {
* Load the <code>test-ebean.properties</code>.
*/
public static PropertyMap loadTestProperties() {
if (!PropertyMap.loadTestProperties()) {
return new PropertyMap();
}
return load(null, "test-ebean.properties");
}
@@ -31,7 +34,7 @@ final class PropertyMapLoader {
if (fileName == null) {
fileName = System.getProperty("ebean.props.file");
if (fileName == null) {
loadTestProperties = true;
loadTestProperties = PropertyMap.loadTestProperties();
fileName = "ebean.properties";
}
}
File diff suppressed because it is too large Load Diff
@@ -146,6 +146,6 @@ public final class TableName {
* @return true, if is valid
*/
public boolean isValid() {
return name != null && name.length() > 0;
return name != null && !name.isEmpty();
}
}
@@ -0,0 +1,24 @@
package com.avaje.ebean.config.dbplatform;
/**
* Adds ANSI based OFFSET FETCH NEXT clauses to a SQL query.
*/
public class BasicSqlAnsiLimiter implements BasicSqlLimiter {
@Override
public String limit(String dbSql, int firstRow, int maxRows) {
StringBuilder sb = new StringBuilder(50 + dbSql.length());
sb.append(dbSql);
if (firstRow > 0) {
sb.append(" ").append("offset");
sb.append(" ").append(firstRow).append(" rows");
}
if (maxRows > 0) {
sb.append(" fetch next ").append(maxRows).append(" rows only");
}
return sb.toString();
}
}
@@ -0,0 +1,36 @@
package com.avaje.ebean.config.dbplatform;
/**
* Adds LIMIT OFFSET clauses to a SQL query.
*/
public class BasicSqlLimitOffset implements BasicSqlLimiter {
/**
* LIMIT keyword.
*/
private static final String LIMIT = "limit";
/**
* OFFSET keyword.
*/
private static final String OFFSET = "offset";
@Override
public String limit(String dbSql, int firstRow, int maxRows) {
StringBuilder sb = new StringBuilder(50 + dbSql.length());
sb.append(dbSql);
if (maxRows > 0) {
sb.append(" ").append(LIMIT);
sb.append(" ").append(maxRows);
}
if (firstRow > 0) {
sb.append(" ").append(OFFSET).append(" ");
sb.append(firstRow);
}
return sb.toString();
}
}
@@ -0,0 +1,12 @@
package com.avaje.ebean.config.dbplatform;
/**
* Simple SQL limiter for use with SqlQuery.
*/
public interface BasicSqlLimiter {
/**
* Add basic offset/limit clause to SqlQuery query.
*/
String limit(String dbSql, int firstRow, int maxRows);
}
@@ -24,9 +24,9 @@ public class DB2Platform extends DatabasePlatform {
this.dbIdentity.setSupportsSequence(true);
booleanDbType = Types.BOOLEAN;
dbTypeMap.put(Types.REAL, new DbType("real"));
dbTypeMap.put(Types.TINYINT, new DbType("smallint"));
dbTypeMap.put(Types.DECIMAL, new DbType("decimal", 15));
dbTypeMap.put(DbType.REAL, new DbPlatformType("real"));
dbTypeMap.put(DbType.TINYINT, new DbPlatformType("smallint"));
dbTypeMap.put(DbType.DECIMAL, new DbPlatformType("decimal", 15));
}
/**
@@ -34,8 +34,8 @@ public class DB2Platform extends DatabasePlatform {
* sequence values.
*/
@Override
public IdGenerator createSequenceIdGenerator(BackgroundExecutor be,
DataSource ds, String seqName, int batchSize) {
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be,
DataSource ds, String seqName, int batchSize) {
return new DB2SequenceIdGenerator(be, ds, seqName, batchSize);
}
@@ -2,6 +2,10 @@ package com.avaje.ebean.config.dbplatform;
import com.avaje.ebean.BackgroundExecutor;
import com.avaje.ebean.Query;
import com.avaje.ebean.config.CustomDbTypeMapping;
import com.avaje.ebean.config.DbTypeConfig;
import com.avaje.ebean.config.PersistBatch;
import com.avaje.ebean.config.Platform;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.dbmigration.ddlgeneration.DdlHandler;
import com.avaje.ebean.dbmigration.ddlgeneration.platform.PlatformDdl;
@@ -9,6 +13,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
/**
@@ -28,12 +36,6 @@ public class DatabasePlatform {
*/
ROLLBACK,
/**
* Just close the transaction. Valid at READ_COMMITTED isolation and preferred on some Databases
* as a performance optimisation.
*/
CLOSE,
/**
* Commit the transaction
*/
@@ -66,10 +68,15 @@ public class DatabasePlatform {
*/
protected SqlLimiter sqlLimiter = new LimitOffsetSqlLimiter();
/**
* Limit/offset support for SqlQuery only.
*/
protected BasicSqlLimiter basicSqlLimiter = new BasicSqlLimitOffset();
/**
* Mapping of JDBC to Database types.
*/
protected DbTypeMap dbTypeMap = new DbTypeMap();
protected DbPlatformTypeMapping dbTypeMap = new DbPlatformTypeMapping();
/**
* Default values for DB columns.
@@ -145,11 +152,9 @@ public class DatabasePlatform {
protected boolean forwardOnlyHintOnFindIterate;
/**
* Flag set for SQL Server due to lack of support of getGeneratedKeys in
* batch mode (meaning for batch inserts you should explicitly turn off
* getGeneratedKeys - joy).
* By default we use JDBC batch when cascading (except for SQL Server).
*/
protected boolean disallowBatchOnCascade;
protected PersistBatch persistBatchOnCascade = PersistBatch.ALL;
protected PlatformDdl platformDdl;
@@ -165,12 +170,53 @@ public class DatabasePlatform {
*/
protected int maxConstraintNameLength = 60;
protected boolean supportsNativeIlike;
/**
* Instantiates a new database platform.
*/
public DatabasePlatform() {
}
/**
* Configure UUID Storage etc based on ServerConfig settings.
*/
public void configure(DbTypeConfig config) {
addGeoTypes(config.getGeometrySRID());
configureIdType(config.getIdType());
dbTypeMap.config(nativeUuidType, config.getDbUuid());
for (CustomDbTypeMapping mapping : config.getCustomTypeMappings()) {
if (platformMatch(mapping.getPlatform())) {
dbTypeMap.put(mapping.getType(), parse(mapping.getColumnDefinition()));
}
}
}
protected void configureIdType(IdType idType) {
if (idType != null) {
this.dbIdentity.setIdType(idType);
}
}
protected void addGeoTypes(int srid) {
// default has no geo type support
}
private DbPlatformType parse(String columnDefinition) {
return DbPlatformType.parse(columnDefinition);
}
private boolean platformMatch(Platform platform) {
return platform == null || platform.name().equalsIgnoreCase(name);
}
/**
* Return true if this matches the given platform.
*/
public boolean isPlatform(Platform platform) {
return platform.name().equalsIgnoreCase(name);
}
/**
* Return the name of the DatabasePlatform.
* <p>
@@ -182,6 +228,13 @@ public class DatabasePlatform {
return name;
}
/**
* Return true if this database platform supports native ILIKE expression.
*/
public boolean isSupportsNativeIlike() {
return supportsNativeIlike;
}
/**
* Return the maximum table name length.
* <p>
@@ -233,7 +286,7 @@ public class DatabasePlatform {
* @param seqName the name of the sequence
* @param batchSize the number of sequences that should be loaded
*/
public IdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int batchSize) {
public PlatformIdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int batchSize) {
return null;
}
@@ -291,7 +344,7 @@ public class DatabasePlatform {
*
* @return the db type map
*/
public DbTypeMap getDbTypeMap() {
public DbPlatformTypeMapping getDbTypeMap() {
return dbTypeMap;
}
@@ -436,6 +489,13 @@ public class DatabasePlatform {
return sqlLimiter;
}
/**
* Return the BasicSqlLimiter for limit/offset of SqlQuery queries.
*/
public BasicSqlLimiter getBasicSqlLimiter() {
return basicSqlLimiter;
}
/**
* Set the DB TRUE literal (from the registered boolean ScalarType)
*/
@@ -462,7 +522,7 @@ public class DatabasePlatform {
*/
public String convertQuotedIdentifiers(String dbName) {
// Ignore null values e.g. schema name or catalog
if (dbName != null && dbName.length() > 0) {
if (dbName != null && !dbName.isEmpty()) {
if (dbName.charAt(0) == BACK_TICK) {
if (dbName.charAt(dbName.length() - 1) == BACK_TICK) {
@@ -512,14 +572,34 @@ public class DatabasePlatform {
}
/**
* Return true if the persistBatchOnCascade setting should be ignored.
* <p>
* This is primarily for SQL Server which does not support getGeneratedKeys with jdbc batch mode
* so can't really be transparently used.
* </p>
* Return the platform default JDBC batch mode for persist cascade.
*/
public boolean isDisallowBatchOnCascade() {
return disallowBatchOnCascade;
public PersistBatch getPersistBatchOnCascade() {
return persistBatchOnCascade;
}
/**
* Return true if the table exists.
*/
public boolean tableExists(Connection connection, String catalog, String schema, String table) throws SQLException {
DatabaseMetaData metaData = connection.getMetaData();
ResultSet tables = metaData.getTables(catalog, schema, table, null);
try {
return tables.next();
} finally {
close(tables);
}
}
/**
* Close the resultSet.
*/
protected void close(ResultSet resultSet) {
try {
resultSet.close();
} catch (SQLException e) {
logger.error("Error closing resultSet", e);
}
}
}
@@ -23,7 +23,7 @@ public class DbDefaultValue {
*/
public static final String NOW = "now";
protected Map<String,String> map = new LinkedHashMap<String,String>();
protected Map<String,String> map = new LinkedHashMap<>();
/**
* Set the DB now function.
@@ -6,11 +6,13 @@ package com.avaje.ebean.config.dbplatform;
public interface DbHistorySupport {
/**
* Return true if the 'As of' predicate is part of the from clause
* (more standard sql2011). So true for Oracle total recall and false
* for Postgres and MySql (where we use views and history tables).
* Return true if the implementation is SQL2011 standards based.
* <p>
* Non standards based means we need to add additional predicates into the
* JOIN ON clause and add an additional predicate for the base table.
* </p>
*/
boolean isBindWithFromClause();
boolean isStandardsBased();
/**
* Return the number of columns bound in a 'As Of' predicate.
@@ -135,9 +135,9 @@ public class DbIdentity {
return supportsSequence ? IdType.SEQUENCE : idType;
case IDENTITY:
return supportsIdentity ? IdType.IDENTITY : idType;
default:
return idType;
}
// use the default
return idType;
}
}
@@ -0,0 +1,158 @@
package com.avaje.ebean.config.dbplatform;
/**
* Represents a DB type with name, length, precision, and scale.
* <p>
* The length is for VARCHAR types and precision/scale for DECIMAL types.
* </p>
*/
public class DbPlatformType implements ExtraDbTypes {
/**
* The data type name (VARCHAR, INTEGER ...)
*/
private final String name;
/**
* The default length or precision.
*/
private final int defaultLength;
/**
* The default scale (decimal).
*/
private final int defaultScale;
/**
* Set to true if the type should never have a length or scale.
*/
private final boolean canHaveLength;
/**
* Parse a type definition into a DbPlatformType.
* <p>
* e.g. "decimal(18,6)"
* e.g. "text"
* </p>
*/
public static DbPlatformType parse(String columnDefinition) {
return DbPlatformTypeParser.parse(columnDefinition);
}
/**
* Construct with no length or scale.
*/
public DbPlatformType(String name) {
this(name, 0, 0);
}
/**
* Construct with a given length.
*/
public DbPlatformType(String name, int defaultLength) {
this(name, defaultLength, 0);
}
/**
* Construct for Decimal with precision and scale.
*/
public DbPlatformType(String name, int defaultPrecision, int defaultScale) {
this.name = name;
this.defaultLength = defaultPrecision;
this.defaultScale = defaultScale;
this.canHaveLength = true;
}
/**
* Use with canHaveLength=false for types that should never have a length.
*
* @param name
* the type name
* @param canHaveLength
* set this to false for type that should never have a length
*/
public DbPlatformType(String name, boolean canHaveLength) {
this.name = name;
this.defaultLength = 0;
this.defaultScale = 0;
this.canHaveLength = canHaveLength;
}
/**
* Return the type name.
*/
public String getName() {
return name;
}
/**
* Return the default length/precision.
*/
public int getDefaultLength() {
return defaultLength;
}
/**
* Return the default scale.
*/
public int getDefaultScale() {
return defaultScale;
}
/**
* Return the type for a specific property that incorporates the name, length,
* precision and scale.
* <p>
* The deployLength and deployScale are for the property we are rendering the
* DB type for.
* </p>
*
* @param deployLength
* the length or precision defined by deployment on a specific
* property.
* @param deployScale
* the scale defined by deployment on a specific property.
*/
public String renderType(int deployLength, int deployScale) {
return renderType(deployLength, deployScale, true);
}
/**
* Render the type defining strict mode.
* <p>
* If strict mode if OFF then this will render with a scale value even if
* that is not strictly supported. The reason for supporting this is to enable
* use to use types like jsonb(200) as a "logical" type that maps to JSONB for
* Postgres and VARCHAR(200) for other databases.
* </p>
*/
public String renderType(int deployLength, int deployScale, boolean strict) {
StringBuilder sb = new StringBuilder();
sb.append(name);
if (canHaveLength || !strict) {
// see if there is a precision/scale to add (or not)
int len = deployLength != 0 ? deployLength : defaultLength;
if (len > 0) {
sb.append("(");
sb.append(len);
int scale = deployScale != 0 ? deployScale : defaultScale;
if (scale > 0) {
sb.append(",");
sb.append(scale);
}
sb.append(")");
}
}
return sb.toString();
}
/**
* Create a copy of the type with a new default length.
*/
public DbPlatformType withLength(int defaultLength) {
return new DbPlatformType(name, defaultLength);
}
}
@@ -0,0 +1,53 @@
package com.avaje.ebean.config.dbplatform;
import java.util.HashMap;
import java.util.Map;
/**
* Helper to reverse lookup a DbType given the name or JDBC int value.
*/
class DbPlatformTypeLookup {
/**
* A map to lookup the type by name.
*/
private Map<String, DbType> nameLookup = new HashMap<>();
/**
* A map to lookup the type by JDBC int value.
*/
private Map<Integer, DbType> idLookup = new HashMap<>();
DbPlatformTypeLookup() {
addAll();
}
/**
* Return the DbType for the given name.
*/
DbType byName(String name) {
return nameLookup.get(name.trim().toUpperCase());
}
/**
* Return the DbType for the given name.
*/
DbType byId(int jdbcId) {
return idLookup.get(jdbcId);
}
private void addAll() {
// Extra mapping for Float and Varchar2
add("FLOAT", DbType.REAL);
add("VARCHAR2", DbType.VARCHAR);
for (DbType type : DbType.values()) {
add(type.name(), type);
}
}
private void add(String name, DbType dbType) {
nameLookup.put(name, dbType);
idLookup.put(dbType.id(), dbType);
}
}
@@ -0,0 +1,194 @@
package com.avaje.ebean.config.dbplatform;
import com.avaje.ebean.config.ServerConfig;
import java.util.HashMap;
import java.util.Map;
/**
* Used to map bean property types to DB specific types for DDL generation.
*/
public class DbPlatformTypeMapping {
private static DbPlatformTypeLookup lookup = new DbPlatformTypeLookup();
private static final DbPlatformType UUID_NATIVE = new DbPlatformType("uuid", false);
private static final DbPlatformType UUID_PLACEHOLDER = new DbPlatformType("uuidPlaceholder");
private static final DbPlatformType JSON_CLOB_PLACEHOLDER = new DbPlatformType("jsonClobPlaceholder");
private static final DbPlatformType JSON_BLOB_PLACEHOLDER = new DbPlatformType("jsonBlobPlaceholder");
private static final DbPlatformType JSON_VARCHAR_PLACEHOLDER = new DbPlatformType("jsonVarcharPlaceholder");
private static final DbPlatformType POINT = new DbPlatformType("point");
private static final DbPlatformType POLYGON = new DbPlatformType("polygon");
private static final DbPlatformType LINESTRING = new DbPlatformType("linestring");
private static final DbPlatformType MULTIPOINT = new DbPlatformType("multipoint");
private static final DbPlatformType MULTILINESTRING = new DbPlatformType("multilinestring");
private static final DbPlatformType MULTIPOLYGON = new DbPlatformType("multipolygon");
private final Map<DbType, DbPlatformType> typeMap = new HashMap<>();
/**
* Return the DbTypeMap with standard (not platform specific) types.
* <p>
* This has some extended JSON types (JSON, JSONB, JSONVarchar, JSONClob, JSONBlob).
* These types get translated to specific database platform types during DDL generation.
*/
public static DbPlatformTypeMapping logicalTypes() {
return new DbPlatformTypeMapping(true);
}
public DbPlatformTypeMapping() {
loadDefaults(false);
}
private DbPlatformTypeMapping(boolean logicalTypes) {
loadDefaults(logicalTypes);
}
/**
* Load the standard types. These can be overridden by DB specific platform.
*/
private void loadDefaults(boolean logicalTypes) {
put(DbType.BOOLEAN);
put(DbType.BIT);
put(DbType.INTEGER);
put(DbType.BIGINT);
put(DbType.DOUBLE);
put(DbType.SMALLINT);
put(DbType.TINYINT);
put(DbType.BLOB);
put(DbType.CLOB);
put(DbType.ARRAY);
put(DbType.DATE);
put(DbType.TIME);
put(DbType.TIMESTAMP);
put(DbType.LONGVARBINARY);
put(DbType.LONGVARCHAR);
// most commonly real maps to db float
put(DbType.REAL, new DbPlatformType("float"));
put(DbType.POINT, POINT);
put(DbType.POLYGON, POLYGON);
put(DbType.LINESTRING, LINESTRING);
put(DbType.MULTIPOINT, MULTIPOINT);
put(DbType.MULTILINESTRING, MULTILINESTRING);
put(DbType.MULTIPOLYGON, MULTIPOLYGON);
if (logicalTypes) {
// keep it logical for 2 layer DDL generation
put(DbType.VARCHAR, new DbPlatformType("varchar"));
put(DbType.DECIMAL, new DbPlatformType("decimal"));
put(DbType.VARBINARY, new DbPlatformType("varbinary"));
put(DbType.BINARY, new DbPlatformType("binary"));
put(DbType.CHAR, new DbPlatformType("char"));
put(DbType.HSTORE, new DbPlatformType("hstore", false));
put(DbType.JSON, new DbPlatformType("json", false));
put(DbType.JSONB, new DbPlatformType("jsonb", false));
put(DbType.JSONCLOB, new DbPlatformType("jsonclob"));
put(DbType.JSONBLOB, new DbPlatformType("jsonblob"));
put(DbType.JSONVARCHAR, new DbPlatformType("jsonvarchar", 1000));
put(DbType.UUID, UUID_NATIVE);
} else {
put(DbType.VARCHAR, new DbPlatformType("varchar", 255));
put(DbType.DECIMAL, new DbPlatformType("decimal", 38));
put(DbType.VARBINARY, new DbPlatformType("varbinary", 255));
put(DbType.BINARY, new DbPlatformType("binary", 255));
put(DbType.CHAR, new DbPlatformType("char", 1));
put(DbType.JSON, JSON_CLOB_PLACEHOLDER); // Postgres maps this to JSON
put(DbType.JSONB, JSON_CLOB_PLACEHOLDER); // Postgres maps this to JSONB
put(DbType.JSONCLOB, JSON_CLOB_PLACEHOLDER);
put(DbType.JSONBLOB, JSON_BLOB_PLACEHOLDER);
put(DbType.JSONVARCHAR, JSON_VARCHAR_PLACEHOLDER);
// use reasonable default of varchar(40) - ideally set via DatabasePlatform.configure(DbTypeConfig)
put(DbType.UUID, get(DbType.VARCHAR).withLength(40));
}
}
/**
* Lookup the platform specific DbType given the standard sql type name.
*/
public DbPlatformType lookup(String name, boolean withScale) {
DbType type = lookup.byName(name);
if (type == null) {
throw new IllegalArgumentException("Unknown type [" + name + "] - not standard sql type");
}
// handle JSON types mapped to clob, blob and varchar
switch (type) {
case JSONBLOB:
return get(DbType.BLOB);
case JSONCLOB:
return get(DbType.CLOB);
case JSONVARCHAR:
return get(DbType.VARCHAR);
case JSON:
return getJsonType(DbType.JSON, withScale);
case JSONB:
return getJsonType(DbType.JSONB, withScale);
default:
return get(type);
}
}
private DbPlatformType getJsonType(DbType type, boolean withScale) {
DbPlatformType dbType = get(type);
if (dbType == JSON_CLOB_PLACEHOLDER) {
// if we have scale that implies this maps to varchar
return withScale ? get(DbType.VARCHAR) : get(DbType.CLOB);
}
if (dbType == JSON_BLOB_PLACEHOLDER) {
return get(DbType.BLOB);
}
if (dbType == JSON_VARCHAR_PLACEHOLDER) {
return get(DbType.VARCHAR);
}
// Postgres has specific type
return get(type);
}
/**
* Override the type for a given JDBC type.
*/
private void put(DbType type) {
typeMap.put(type, type.createPlatformType());
}
/**
* Override the type for a given JDBC type.
*/
public void put(DbType type, DbPlatformType platformType) {
typeMap.put(type, platformType);
}
/**
* Return the type for a given jdbc type.
*/
public DbPlatformType get(int jdbcType) {
return get(lookup.byId(jdbcType));
}
/**
* Return the type for a given jdbc type.
*/
public DbPlatformType get(DbType dbType) {
return typeMap.get(dbType);
}
/**
* Map the UUID appropriately based on native DB support and ServerConfig.DbUuid.
*/
public void config(boolean nativeUuidType, ServerConfig.DbUuid dbUuid) {
if (nativeUuidType && dbUuid.useNativeType()) {
put(DbType.UUID, UUID_NATIVE);
} else if (dbUuid.useBinary()) {
put(DbType.UUID, get(DbType.BINARY).withLength(16));
} else {
put(DbType.UUID, get(DbType.VARCHAR).withLength(40));
}
}
}
@@ -0,0 +1,40 @@
package com.avaje.ebean.config.dbplatform;
/**
* Parse raw column definitions into DbPlatformType like "decimal(18,6)" and "varchar(20) and "json".
*/
class DbPlatformTypeParser {
/**
* Parse the column definition and return the DbPlatformType.
*/
static DbPlatformType parse(String columnDefinition) {
columnDefinition = columnDefinition.trim();
int openPos = columnDefinition.indexOf('(');
if (openPos == -1) {
return new DbPlatformType(columnDefinition, false);
}
int closePos = columnDefinition.indexOf(')', openPos);
if (closePos == -1) {
return new DbPlatformType(columnDefinition, false);
}
try {
int commaPos = columnDefinition.indexOf(',', openPos);
if (commaPos > -1) {
String type = columnDefinition.substring(0, openPos);
int scale = Integer.parseInt(columnDefinition.substring(openPos + 1, commaPos));
int precision = Integer.parseInt(columnDefinition.substring(commaPos + 1, closePos));
return new DbPlatformType(type, scale, precision);
} else {
String type = columnDefinition.substring(0, openPos);
int scale = Integer.parseInt(columnDefinition.substring(openPos + 1, closePos));
return new DbPlatformType(type, scale);
}
} catch (RuntimeException e) {
return new DbPlatformType(columnDefinition, false);
}
}
}
@@ -5,11 +5,8 @@ package com.avaje.ebean.config.dbplatform;
*/
public abstract class DbStandardHistorySupport implements DbHistorySupport {
/**
* Return true as with sql2011 the 'as of timestamp' clause included in from or join clause.
*/
@Override
public boolean isBindWithFromClause() {
public boolean isStandardsBased() {
return true;
}

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