Compare commits

..
Author SHA1 Message Date
rbygrave aa27aedca9 [maven-release-plugin] prepare release ebean-parent-12.11.2 2021-08-31 17:21:52 +12:00
rbygrave 172c1d10a1 Tidy test only - tidy TestDbArray_asSet 2021-08-31 14:28:54 +12:00
rbygrave da6f7d671b #2336 - @DbArray List or Set of UUID or enum returned as String (not converted) when DB does not support ARRAY 2021-08-31 14:26:52 +12:00
rbygrave 6e10d641b2 Merge branch 'master' of github.com:ebean-orm/ebean 2021-08-30 22:43:06 +12:00
rbygrave c5dca69482 Tests only - update tests for sql server 2021-08-30 22:42:12 +12:00
rob 371a50176e Tidy tests only - ClusterTest and TestAggregateFormula 2021-08-30 22:39:11 +12:00
Rob BygraveandGitHub 56fed3ad87 Merge pull request #2331 from FOCONIS/pr/bugfix/npe_mutableNext_call
Fix for NPE in mutableNext in EBI
2021-08-25 10:38:32 +12:00
Rob BygraveandGitHub 9a65731be9 Merge pull request #2330 from FOCONIS/pr/enh/sort_order_in_bean_state
Make getSortOrder accessible in BeanState API
2021-08-25 10:36:29 +12:00
Rob BygraveandGitHub 34b011f683 Merge pull request #2329 from FOCONIS/pr/bugfix/oder_column_cache
@OrderdColum did not work properly with cached beans
2021-08-25 10:29:45 +12:00
Jonas Pöhler 69c721b66e ADD: getSortOrder accessible in BeanState API 2021-08-24 14:48:22 +02:00
Jonas Pöhler f2a578cd76 FIX: OrderdColums did not work properly with cache 2021-08-24 14:28:21 +02:00
rbygrave 1e34d65675 Tests only - update ddl review for Postgres 2021-08-24 15:59:58 +12:00
rbygrave 60db0b0999 #2328 - Postgres JSONB dirty checking - trim json 2021-08-24 15:58:29 +12:00
rbygrave 3bfb6dbc20 #2327 - Follow up and fix test TestQueryFilterMany 2021-08-24 15:04:52 +12:00
rbygrave d4d9bb204d #2327 - findSingleAttribute() on a ToMany path includes the id column
Follow up refactor SqlTreeBuilder
2021-08-24 15:04:23 +12:00
rbygrave bedb841fa9 #2327 - findSingleAttribute() on a ToMany path includes the id column
Follow up test changes
2021-08-24 14:52:54 +12:00
rbygrave c4c4663144 #2327 - findSingleAttribute() on a ToMany path includes the id column 2021-08-24 14:31:30 +12:00
rbygrave b392db866c Update tests for multi-platform testing 2021-08-22 17:48:19 +12:00
rbygrave 3556f9a42b Rename test helper StartPostgres (start docker postgres) 2021-08-22 16:39:44 +12:00
rbygrave 0345ca9f18 Update ddl review only - for #2326 2021-08-22 16:38:50 +12:00
rbygrave eacc4b907d Update ddl review only - for #2326 2021-08-22 15:55:45 +12:00
rbygrave 09cb5da3d3 #2326 - [ddl generator] Primary key constraint not generated for @IdClass 2021-08-22 15:55:08 +12:00
rbygrave b22791c15b Update ddl review for h2 2021-08-22 15:29:27 +12:00
rbygrave df3eda411a #2318 - Refactor internals - trim whitespace in deploy package 2021-08-22 13:59:08 +12:00
Jonas Pöhler 5b10c053de FIX: NPE when accessing mutableNext in EBI 2021-08-20 15:13:42 +02:00
rbygrave bf2d75e55e #2318 - Refactor internals - trim whitespace in deploy package 2021-08-20 17:51:01 +12:00
rbygrave 6f7efe6922 #2318 - Refactor internals - trim whitespace in deploy package 2021-08-20 17:39:11 +12:00
rbygrave 90e321ddbd #2318 - Refactor internals - trim whitespace in deploy package 2021-08-20 16:58:37 +12:00
Rob BygraveandGitHub 9649d71082 Merge pull request #2325 from FOCONIS/pr/bugfix/ordere_list_modify_listen_mode
Modification of a OneToMany-Relation with @OrderColumn was not detected
2021-08-20 15:29:22 +12:00
rbygrave 932337d83d Bump ebean-agent to 12.11.2 relating to fix for #2325 2021-08-20 13:09:59 +12:00
Jonas Pöhler 7e4bde8d34 FIX: Modification of a OneToMany-Relation with @OrderColumn was not detected 2021-08-19 17:11:31 +02:00
rbygrave 01e8b5f471 #2323 - Fallback to database query if redis connection fails 2021-08-18 20:41:09 +12:00
rbygrave 68a6da22be Fix imports on test TestQueryExists 2021-08-18 09:41:36 +12:00
rbygrave 986f3b5bca Merge branch 'master' of github.com:ebean-orm/ebean 2021-08-18 09:32:30 +12:00
rbygrave 4b1bb9d1ee #2324 - Bump ebean-datasource to 7.2 2021-08-18 09:11:24 +12:00
rbygrave ec340c0abe #2320 - Tidy only changes 2021-08-18 09:10:27 +12:00
rbygrave b062ec050c #2320 - Tidy only changes 2021-08-18 09:05:28 +12:00
rbygrave 965f4c6227 #2320 - Tidy only changes 2021-08-18 09:05:18 +12:00
Rob BygraveandGitHub bdc4022211 Merge pull request #2322 from FOCONIS/pr/bugfix/subquery_without_where
Fix for subqueries without where condition
2021-08-18 08:53:34 +12:00
rbygrave 7edfe3607d #2320 - When I use Redis for L2 cache, can I set the TTL of the cache key? 2021-08-18 08:43:06 +12:00
Jonas Pöhler e1731b87ec Merge remote-tracking branch 'ebean/master' into pr/bugfix/subquery_without_where 2021-08-17 16:07:02 +02:00
rbygrave ebadc92f63 #2319 - redis - ReentrantLock to replace synchronized(this) 2021-08-17 22:07:31 +12:00
rbygrave ea56ec7435 #2319 - redis - final classes 2021-08-17 22:06:48 +12:00
rbygrave 3b990fb6e1 #2319 - redis - remove unused PrefixKey 2021-08-17 22:03:33 +12:00
rbygrave 96b4fbea4b #2319 - redis - tidy whitespace 2021-08-17 22:02:57 +12:00
rbygrave 9161e17476 #2318 - Refactor internals - final classes in querybean package 2021-08-17 21:39:57 +12:00
rbygrave 190a2c47e9 #2318 - Refactor internals - final classes in cache package 2021-08-17 21:24:56 +12:00
rbygrave d096706685 #2318 - Refactor internals - final classes in internal api package 2021-08-17 21:03:53 +12:00
rbygrave 7521cb530e #2318 - Refactor internals - final classes in type packages 2021-08-17 20:48:15 +12:00
rbygrave dde9b507ce #2318 - Refactor internals - final classes in type packages 2021-08-17 20:09:27 +12:00
rbygrave 183416a640 #2318 - Delete unused ScalarTypeLongToTimestamp 2021-08-17 20:09:02 +12:00
rbygrave 826e8518ea #2318 - Refactor internals - final classes in type packages 2021-08-17 19:46:08 +12:00
rbygrave 55587b12aa #2318 - Refactor internals - final classes in el packages 2021-08-17 19:15:35 +12:00
rbygrave 285a94e5fe #2318 - Refactor internals - final classes in dto packages 2021-08-17 19:06:54 +12:00
rbygrave 16a05528b7 #2318 - Refactor internals - final classes in deploy packages etc 2021-08-17 19:00:55 +12:00
rbygrave b4f4ef3c1b #2318 - Refactor internals - final classes in server packages 2021-08-17 18:24:28 +12:00
rbygrave cd407ee467 #2318 - Refactor internals - final classes in changelog packages 2021-08-16 23:32:26 +12:00
rbygrave 9ee63144e5 #2318 - Refactor internals - final classes in core packages 2021-08-16 23:32:05 +12:00
rbygrave 0413d89a9e #2318 - Refactor internals - final classes in expression packages 2021-08-16 23:19:02 +12:00
rbygrave f33e54d8ba #2318 - Refactor internals - final classes in id and generated property packages 2021-08-16 22:53:38 +12:00
Rob BygraveandGitHub a2b19d46e1 Merge pull request #2316 from FOCONIS/pr/bugfix/json-null-formatValue
Fix: setting json values to null was throwing a NPE when persisting
2021-08-16 22:31:47 +12:00
rbygrave 4163b4dc25 #2317 - Plus test changes due to tidy whitespace on sql generation 2021-08-16 22:23:58 +12:00
rbygrave 12220d4322 #2317 - Incorrect SQL generated for @IdClass with fetch() on ToMany path 2021-08-16 22:21:49 +12:00
rbygrave 14262d4c25 #2317 - Incorrect SQL generated for @IdClass with fetch() on ToMany path 2021-08-16 22:20:21 +12:00
Jonas Pöhler (JPo) f3ec4a78c9 FIX: setting json values to null was throwing a NPE when persisting 2021-08-16 12:02:47 +02:00
rbygrave f7a0ae8b4a [maven-release-plugin] prepare for next development iteration 2021-08-16 09:23:18 +12:00
rbygrave 3c6d17c9a5 [maven-release-plugin] prepare release ebean-parent-12.11.1 2021-08-16 09:23:11 +12:00
rbygrave 885ba0fdd2 Set autoReleaseAfterClose true 2021-08-16 09:18:31 +12:00
rbygrave f3b0e34b67 #2315 - Refactor internals - make more classes final in transaction packages 2021-08-16 09:16:31 +12:00
rbygrave 4109fab0d8 #2313 - Refactor internals - make more classes final in query packages 2021-08-15 15:22:02 +12:00
rbygrave 0688061f5c Speed up TestUuidGenerator 2021-08-15 15:17:19 +12:00
rbygrave 82c12b1565 #2312 - Refactor internals - make more classes final in persist packages 2021-08-15 14:50:43 +12:00
rbygrave ebc0fabbdb #2311 - Fix BindPadding for empty list 2021-08-15 14:15:03 +12:00
rbygrave 587b2e3075 #2310 Tidy to only cast once 2021-08-15 14:09:44 +12:00
Rob BygraveandGitHub ec82dd3da9 Merge pull request #2310 from FOCONIS/nutation-on-cache
FIX: mutation info is not restored on cache hit
2021-08-15 13:50:19 +12:00
rbygrave 3e190b34f5 Merge branch 'master' of github.com:ebean-orm/ebean 2021-08-15 13:48:43 +12:00
rbygrave e059ad9172 Merge branch 'FOCONIS-mutationdetection-source-special-json-types' 2021-08-15 13:48:27 +12:00
rbygrave 1297324fa9 Fix where using JDK 10 Reader.transferTo() method plus add final to methods and classes 2021-08-15 13:47:46 +12:00
rbygrave e2b7434d98 Merge branch 'mutationdetection-source-special-json-types' of https://github.com/FOCONIS/ebean into FOCONIS-mutationdetection-source-special-json-types 2021-08-15 12:06:12 +12:00
rbygrave ada8df5755 Improve startup logging messages 2021-08-15 12:05:30 +12:00
Roland Praml 843b90cbba FIX: mutation info is not restored on cache hit 2021-08-13 11:52:31 +02:00
Roland Praml 6b263919d5 handle also JsonNode 2021-08-13 11:19:24 +02:00
Roland Praml 965c1e803f FIX: mutationDetection = SOURCE works also for special json types 2021-08-13 10:47:14 +02:00
Rob BygraveandGitHub a13bc481b8 Merge pull request #2306 from FOCONIS/pr/enh/softreference_in_cache
Use SoftReferences in Cache
2021-08-13 09:35:38 +12:00
rbygrave fc7379aabc Tidy internals - server.persist.dml package for whitespace and typos 2021-08-13 09:18:31 +12:00
rbygrave a17683c549 #2307 - Tidy ShutdownManager DatabaseFactory only 2021-08-12 16:32:12 +12:00
rbygrave eeacad0fb9 #2307 - ENH: Add DatabaseFactory.disableShutdownHook() ... [ alias for ShutdownManager.deregisterShutdownHook() ] 2021-08-12 14:36:14 +12:00
rbygrave c51140b59a Add DefaultServer.toString() and tidy DbOffline remove unnecessary log message 2021-08-12 13:01:07 +12:00
Jonas Pöhler f1817a0dbb Merge remote-tracking branch 'ebean/master' into pr/enh/softreference_in_cache 2021-08-11 15:26:42 +02:00
Jonas Pöhler 5b05510bb9 Merge remote-tracking branch 'ebean/master' into pr/enh/softreference_in_cache 2021-08-11 14:08:55 +02:00
rbygrave b676476cd2 Add SpiQuery.Type.defaultSelect() for ATTRIBUTE and sub-query type queries 2021-08-11 20:51:46 +12:00
rbygrave 709f8ed05f Merge branch 'master' of github.com:ebean-orm/ebean 2021-08-11 20:21:26 +12:00
rbygrave 31282416d8 Merge branch 'FOCONIS-subquery-with-fetch-path' 2021-08-11 20:16:33 +12:00
Rob BygraveandGitHub 385c84ae6f Merge pull request #2302 from FOCONIS/feature/switch-db2-driver
Switch DB2 driver to the publicly available JCC driver
2021-08-11 19:43:09 +12:00
Roland Praml 2d24020202 Added / enhanced test case 2021-08-11 09:32:21 +02:00
Roland Praml 1a2aba3f56 Distinguish between exists and in subquery 2021-08-11 08:54:40 +02:00
Thomas Fellner f50f0192d1 Switch DB2 driver to the publicly available JCC driver 2021-08-11 08:47:49 +02:00
Roland Praml 12b8b4b955 Merge remote-tracking branch 'upstream/master' into subquery-with-fetch-path 2021-08-11 07:42:11 +02:00
rbygrave c267366578 Refactor tidy internals - aList -> expr in for loops etc. No functional change. 2021-08-11 15:32:54 +12:00
Rob BygraveandGitHub 18e49cc1ce Merge pull request #2300 from FOCONIS/exists-with-dynamic
Enables select + exists for dynamic formula properties
2021-08-11 14:01:46 +12:00
Rob BygraveandGitHub 1ce4b1a994 Merge pull request #2299 from FOCONIS/push-pops-in-wrong-order
PushJson/PopJson did not work correctly, if null beans were involved
2021-08-11 13:48:00 +12:00
Rob BygraveandGitHub f3c87e488a Merge pull request #2301 from FOCONIS/bugfix/update-ddl-generator-version
Updating ebean-ddl-generator version in ebean-core
2021-08-11 13:46:19 +12:00
Rob BygraveandGitHub f24c698cd5 Merge pull request #2298 from ebean-orm/FOCONIS-md5-for-querybindhash
Foconis md5 for querybindhash
2021-08-11 13:29:44 +12:00
rbygrave 144a3b54bb Refactor rename method queryBindHash() to queryBindKey() 2021-08-11 13:25:04 +12:00
rbygrave ec7c7048db Refactor rename BindHash to BindValuesKey 2021-08-11 13:19:44 +12:00
rbygrave fd2e542c0b Change BindHash from interface to implementation, Delete unused server persist BindValues 2021-08-11 12:43:58 +12:00
rbygrave 11e8e3696f BindParams does not need encryptionKey in equals/hashCode 2021-08-11 12:24:36 +12:00
Thomas Fellner d08f7af1e0 update ebean-ddl-generator version in ebean-core 2021-08-10 18:31:02 +02:00
Roland Praml 60dfaab22c Enables select + exists for dynamic formula properties 2021-08-10 15:29:10 +02:00
Roland Praml 75fa7cb7fd PushJson/PopJson did not work correctly, if null beans were involved 2021-08-10 13:24:13 +02:00
rbygrave e47b1737a8 Add HashCodeBindHashTest 2021-08-10 22:28:31 +12:00
rbygrave e1ad210bb0 Tidy JunctionExpression 2021-08-10 22:18:33 +12:00
rbygrave ac3edbedf4 Remove MdBindHash, tidy DefaultOrmQuery 2021-08-10 22:07:48 +12:00
rbygrave 2dc48cf08d ArrayContainsExpression equals() to use enhanced for loop 2021-08-10 22:00:46 +12:00
rbygrave ede1ad0a4c Fix BindParams equals() and hashCode() 2021-08-10 21:58:41 +12:00
rbygrave 3e8f76cd6d Update HashCodeBindHash to use values for equals() 2021-08-10 21:49:31 +12:00
rbygrave cd6df2be39 Merge branch 'md5-for-querybindhash' of https://github.com/FOCONIS/ebean into FOCONIS-md5-for-querybindhash 2021-08-10 21:18:43 +12:00
Rob BygraveandGitHub 7091e972fc Merge pull request #2297 from FOCONIS/fix-mutable-next-changelog
FIX: Changelog-oldValue did not work for Json mutable properties
2021-08-10 21:10:15 +12:00
Roland Praml c8ae3c5ef6 FIX: Changelog-oldValue did not work for Json mutable properties 2021-08-10 09:30:25 +02:00
Rob BygraveandGitHub 54e8c4df8a Merge pull request #2296 from FOCONIS/fix-test-for-java-8
Fix the test to run with java 8
2021-08-10 17:04:14 +12:00
Roland Praml e18c190905 Fix the test to run with java 8 2021-08-09 09:46:49 +02:00
Roland Praml 181dc73d39 Use MD5 for QueryBindHash 2021-08-09 09:19:53 +02:00
rbygrave 7ed2de9178 Update github issue template 2021-08-09 16:57:43 +12:00
rbygrave 8c101fd0a4 #2268 - Feature request/question: Query execution time for debugging 2021-08-09 16:48:59 +12:00
rbygrave 43213ead05 #2291 - ENH: Explicit option for fast-failing or not fast-failing (skipDataSourceCheck config option) 2021-08-09 15:10:59 +12:00
Rob BygraveandGitHub 0ef5c65c94 Merge pull request #2294 from ebean-orm/feature/metric-hash-2
#2293 - Metric hash back to MD5 of sql + name + loc (minus location file and line source) ~= Revert of #2288
2021-08-09 14:49:17 +12:00
rbygrave c610f95b2d #2293 - Metric hash back to MD5 of sql + name + loc (minus location file and line source) ~= Revert of #2288 2021-08-09 14:05:10 +12:00
rbygrave c4484c758e [maven-release-plugin] prepare for next development iteration 2021-08-06 14:56:15 +12:00
Jonas Pöhler 4cebb367de FIX: subquery could not not have a where clause 2021-07-29 17:09:24 +02:00
Jonas Pöhler 60ef87b269 Merge remote-tracking branch 'ebean/master' into pr/enh/softreference_in_cache 2021-07-16 15:29:33 +02:00
Roland Praml 7e265f7bde FIX: SubQuery with fetch-path does not work correctly 2021-07-13 09:09:30 +02:00
Jonas Pöhler (JPo) bd7499a505 Use SoftReference in Cache, so it can be gc'ed if the jvm runs out of memory
Signed-off-by: Jonas Pöhler (JPo) <jonas.poehler@foconis.de>
2021-03-29 13:23:56 +02:00
816 changed files with 5618 additions and 5084 deletions
-6
View File
@@ -1,9 +1,3 @@
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
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.11.0</version>
<version>12.11.2</version>
</parent>
<name>ebean api</name>
@@ -118,4 +118,9 @@ public interface BeanState {
*/
@Nullable
Map<String, Exception> getLoadErrors();
/**
* Return the sort order value for an order column.
*/
int getSortOrder();
}
@@ -16,18 +16,15 @@ import java.util.concurrent.locks.ReentrantLock;
* <p>
* This uses either DatabaseConfig or properties in the application.properties file to
* configure and create a Database instance.
* </p>
* <p>
* The Database instance can either be registered with the DB singleton or
* not. The DB singleton effectively holds a map of Database by a name.
* If the Database is registered with the DB singleton you can retrieve it
* later via {@link DB#byName(String)}.
* </p>
* <p>
* One Database can be nominated as the 'default/primary' Database. Many
* methods on the DB singleton such as {@link DB#find(Class)} are just a
* convenient way of using the 'default/primary' Database.
* </p>
*/
public class DatabaseFactory {
@@ -48,7 +45,7 @@ public class DatabaseFactory {
public static void initialiseContainer(ContainerConfig containerConfig) {
lock.lock();
try {
getContainer(containerConfig);
container(containerConfig);
} finally {
lock.unlock();
}
@@ -60,7 +57,7 @@ public class DatabaseFactory {
public static Database create(String name) {
lock.lock();
try {
return getContainer(null).createServer(name);
return container(null).createServer(name);
} finally {
lock.unlock();
}
@@ -68,6 +65,16 @@ public class DatabaseFactory {
/**
* Create using the DatabaseConfig object to configure the database.
*
* <pre>{@code
*
* DatabaseConfig config = new DatabaseConfig();
* config.setName("db");
* config.loadProperties();
*
* Database database = DatabaseFactory.create(config);
*
* }</pre>
*/
public static Database create(DatabaseConfig config) {
lock.lock();
@@ -115,7 +122,6 @@ public class DatabaseFactory {
* Shutdown gracefully all Database instances cleaning up any resources as required.
* <p>
* This is typically invoked via JVM shutdown hook and not explicitly called.
* </p>
*/
public static void shutdown() {
lock.lock();
@@ -127,15 +133,15 @@ public class DatabaseFactory {
}
private static Database createInternal(DatabaseConfig config) {
return getContainer(config.getContainerConfig()).createServer(config);
return container(config.getContainerConfig()).createServer(config);
}
/**
* Get the EbeanContainer initialising it if necessary.
* Return the SpiContainer initialising it if necessary.
*
* @param containerConfig the configuration controlling clustering communication
*/
private static SpiContainer getContainer(ContainerConfig containerConfig) {
private static SpiContainer container(ContainerConfig containerConfig) {
// thread safe in that all calling methods hold lock
if (container != null) {
return container;
@@ -45,14 +45,6 @@ public interface ProfileLocation {
*/
String label();
/**
* Return a hash of the location that intentionally excludes the line number.
* <p>
* The hash is expected to be stable regardless of line number in the source file
* so that is identifies the class and method location over a long time.
*/
long hash();
/**
* Return the full location.
*/
@@ -395,6 +395,15 @@ public final class EntityBeanIntercept implements Serializable {
this.owner._ebean_setEmbeddedLoaded();
this.lazyLoadProperty = -1;
this.origValues = null;
// after save, transfer the mutable next values back to mutable info
if (mutableNext != null) {
for (int i = 0; i < mutableNext.length; i++) {
MutableValueNext next = mutableNext[i];
if (next != null) {
mutableInfo(i, next.info());
}
}
}
this.mutableNext = null;
for (int i = 0; i < flags.length; i++) {
flags[i] &= ~(FLAG_CHANGED_PROP | FLAG_ORIG_VALUE_SET);
@@ -1224,8 +1233,7 @@ public final class EntityBeanIntercept implements Serializable {
return null;
}
final MutableValueNext next = mutableNext[propertyIndex];
mutableInfo(propertyIndex, next.info());
return next.content();
return next != null ? next.content() : null;
}
}
@@ -319,6 +319,8 @@ public class DatabaseConfig {
*/
private ExternalTransactionManager externalTransactionManager;
private boolean skipDataSourceCheck;
/**
* The data source (if programmatically provided).
*/
@@ -1651,6 +1653,20 @@ public class DatabaseConfig {
this.autoTuneConfig = autoTuneConfig;
}
/**
* Return true if the startup DataSource check should be skipped.
*/
public boolean skipDataSourceCheck() {
return skipDataSourceCheck;
}
/**
* Set to true to skip the startup DataSource check.
*/
public void setSkipDataSourceCheck(boolean skipDataSourceCheck) {
this.skipDataSourceCheck = skipDataSourceCheck;
}
/**
* Return the DataSource.
*/
@@ -2932,6 +2948,7 @@ public class DatabaseConfig {
jsonDate = p.getEnum(JsonConfig.Date.class, "jsonDate", jsonDate);
jsonMutationDetection = p.getEnum(MutationDetection.class, "jsonMutationDetection", jsonMutationDetection);
skipDataSourceCheck = p.getBoolean("skipDataSourceCheck", skipDataSourceCheck);
runMigration = p.getBoolean("migration.run", runMigration);
ddlGenerate = p.getBoolean("ddl.generate", ddlGenerate);
ddlRun = p.getBoolean("ddl.run", ddlRun);
@@ -14,10 +14,9 @@ import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
/**
* Manages the shutdown of the JVM Runtime.
* Manages the shutdown of Ebean.
* <p>
* Makes sure all the resources are shutdown properly and in order.
* </p>
*/
public final class ShutdownManager {
@@ -44,6 +43,9 @@ public final class ShutdownManager {
private ShutdownManager() {
}
/**
* Registers the container (potentially with cluster management).
*/
public static void registerContainer(SpiContainer ebeanContainer) {
container = ebeanContainer;
}
@@ -94,7 +96,7 @@ public final class ShutdownManager {
/**
* Register the shutdown hook with the Runtime.
*/
protected static void registerShutdownHook() {
private static void registerShutdownHook() {
lock.lock();
try {
String value = System.getProperty("ebean.registerShutdownHook");
@@ -123,13 +125,10 @@ public final class ShutdownManager {
// Already run shutdown...
return;
}
if (logger.isDebugEnabled()) {
logger.debug("Shutting down");
}
stopping = true;
deregisterShutdownHook();
String shutdownRunner = System.getProperty("ebean.shutdown.runnable");
@@ -147,7 +146,6 @@ public final class ShutdownManager {
// shutdown cluster networking if active
container.shutdown();
}
// shutdown any registered servers that have not
// already been shutdown manually
for (Database server : databases) {
@@ -158,7 +156,6 @@ public final class ShutdownManager {
ex.printStackTrace();
}
}
if ("true".equalsIgnoreCase(System.getProperty("ebean.datasource.deregisterAllDrivers", "false"))) {
deregisterAllJdbcDrivers();
}
@@ -168,15 +165,15 @@ public final class ShutdownManager {
}
private static void deregisterAllJdbcDrivers() {
// This manually deregisters all JDBC drivers
// This manually de-registers all JDBC drivers
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
logger.info("Deregistering jdbc driver: " + driver);
logger.info("De-registering jdbc driver: " + driver);
DriverManager.deregisterDriver(driver);
} catch (SQLException e) {
logger.error("Error deregistering driver " + driver, e);
logger.error("Error de-registering driver " + driver, e);
}
}
}
@@ -209,6 +206,9 @@ public final class ShutdownManager {
}
private static class ShutdownHook extends Thread {
private ShutdownHook() {
super("EbeanHook");
}
@Override
public void run() {
ShutdownManager.shutdown();
@@ -45,15 +45,8 @@ public interface MetaQueryMetric extends MetaTimedMetric {
}
/**
* Return the hash of the sql.
* Return the hash of the plan.
*/
long sqlHash();
String hash();
/**
* Migrate to sqlHash().
*/
@Deprecated
default long getSqlHash() {
return sqlHash();
}
}
@@ -30,7 +30,7 @@ public interface MetaQueryPlan {
/**
* Return the hash of the plan.
*/
long sqlHash();
String hash();
/**
* Return a description of the bind values.
@@ -6,14 +6,6 @@ package io.ebean.meta;
*/
public interface MetaTimedMetric extends MetaMetric {
/**
* Return the metric location hash if defined.
* <p>
* This hash excludes line number with the intention of being stable over time
* as code changes move the source line (but the method is the same).
*/
long locationHash();
/**
* Return the metric location if defined.
*/
@@ -6,7 +6,7 @@ package io.ebean.meta;
public class MetricData {
private String name;
private long sqlHash;
private String hash;
private String loc;
private String sql;
@@ -14,7 +14,6 @@ public class MetricData {
private Long mean;
private Long max;
private Long total;
private long locHash;
public MetricData(String name) {
this.name = name;
@@ -31,20 +30,12 @@ public class MetricData {
this.name = name;
}
public long getSqlHash() {
return sqlHash;
public String getHash() {
return hash;
}
public void setSqlHash(long sqlHash) {
this.sqlHash = sqlHash;
}
public void setLocHash(long locHash) {
this.locHash = locHash;
}
public long getLocHash() {
return locHash;
public void setHash(String hash) {
this.hash = hash;
}
public String getLoc() {
@@ -10,7 +10,7 @@ public class QueryPlanInit {
private boolean all;
private Set<Long> hashes = new HashSet<>();
private Set<String> hashes = new HashSet<>();
private long thresholdMicros;
@@ -47,21 +47,21 @@ public class QueryPlanInit {
/**
* Return true if the query plan should be initiated based on it's hash.
*/
public boolean includeHash(long sqlHash) {
return all || hashes.contains(sqlHash);
public boolean includeHash(String hash) {
return all || hashes.contains(hash);
}
/**
* Return the specific hashes that we want to collect query plans on.
*/
public Set<Long> sqlHashes() {
public Set<String> hashes() {
return hashes;
}
/**
* Set the specific hashes that we want to collect query plans on.
*/
public void sqlHashes(Set<Long> hashes) {
public void hashes(Set<String> hashes) {
this.hashes = hashes;
}
}
@@ -12,11 +12,6 @@ public interface TimedMetricStats extends MetaTimedMetric {
*/
void setLocation(String location);
/**
* Additionally set the location hash.
*/
void setLocationHash(long locationHash);
/**
* Override the name based on profile location.
*/
+3 -3
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.11.0</version>
<version>12.11.2</version>
</parent>
<!-- <parent>-->
<!-- <groupId>org.avaje</groupId>-->
@@ -14,7 +14,7 @@
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-parent-12.11.0</tag>
<tag>ebean-parent-12.11.2</tag>
</scm>
<name>ebean autotune</name>
@@ -26,7 +26,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
<scope>provided</scope>
</dependency>
@@ -146,7 +146,8 @@ public class BaseQueryTuner {
case ID_LIST:
case UPDATE:
case DELETE:
case SUBQUERY:
case SQ_EXISTS:
case SQ_IN:
return false;
default:
// not using autoTune when explicitly loading the l2 bean cache
+15 -25
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.11.0</version>
<version>12.11.2</version>
</parent>
<name>ebean bom</name>
@@ -12,16 +12,6 @@
<artifactId>ebean-bom</artifactId>
<packaging>pom</packaging>
<properties>
<ebean-ddl-runner.version>1.0</ebean-ddl-runner.version>
<ebean-migration-auto.version>1.1</ebean-migration-auto.version>
<ebean-migration.version>12.11.0</ebean-migration.version>
<ebean-test-docker.version>4.1</ebean-test-docker.version>
<ebean-datasource.version>7.0</ebean-datasource.version>
<ebean-agent.version>12.11.0</ebean-agent.version>
<ebean-maven-plugin.version>12.11.0</ebean-maven-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
@@ -81,88 +71,88 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-xml</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-autotune</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>kotlin-querybean-generator</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-redis</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.11.0</version>
<version>12.11.2</version>
</parent>
<artifactId>ebean-core-type</artifactId>
@@ -16,7 +16,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
<dependency>
+11 -20
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.11.0</version>
<version>12.11.2</version>
</parent>
<artifactId>ebean-core</artifactId>
@@ -15,27 +15,18 @@
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-parent-12.11.0</tag>
<tag>ebean-parent-12.11.2</tag>
</scm>
<profiles>
<profile>
<!-- Note: to use this profile, you need to download manually the db2jcc4 driver.
After that, install it into your local maven repository:
mvn install:install-file \
-Dfile=db2jcc4.jar \
-DgroupId=com.ibm.jdbc \
-DartifactId=db2jcc4 \
-Dversion=4.23.42 \
-Dpackaging=jar
-->
<id>db2</id>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.ibm.db2/jcc -->
<dependency>
<groupId>com.ibm.jdbc</groupId>
<artifactId>db2jcc4</artifactId>
<version>4.23.42</version>
<groupId>com.ibm.db2</groupId>
<artifactId>jcc</artifactId>
<version>11.5.5.0</version>
<scope>test</scope>
</dependency>
</dependencies>
@@ -72,7 +63,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>12.9.4-RC1</version>
<version>12.11.0</version>
<scope>test</scope>
</dependency>
@@ -87,19 +78,19 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>12.11.0</version>
<version>12.11.2</version>
</dependency>
<dependency>
@@ -302,7 +293,7 @@
<plugin>
<groupId>io.ebean</groupId>
<artifactId>ebean-maven-plugin</artifactId>
<version>12.10.0</version>
<version>${ebean-maven-plugin.version}</version>
<executions>
<execution>
<id>test</id>
@@ -6,7 +6,7 @@ import java.util.List;
/**
* The results of bean cache hit.
*/
public class BeanCacheResult<T> {
public final class BeanCacheResult<T> {
private final List<Entry<T>> list = new ArrayList<>();
@@ -27,7 +27,7 @@ public class BeanCacheResult<T> {
/**
* Bean and cache key pair.
*/
static class Entry<T> {
static final class Entry<T> {
private final T bean;
private final Object key;
@@ -7,7 +7,7 @@ import java.io.IOException;
/**
* Context used to read binary format messages.
*/
public class BinaryReadContext {
public final class BinaryReadContext {
private final DataInputStream in;
@@ -6,10 +6,9 @@ import java.io.IOException;
/**
* Context used to write binary message (like RemoteTransactionEvent).
*/
public class BinaryWriteContext {
public final class BinaryWriteContext {
private final DataOutputStream out;
private long counter;
public BinaryWriteContext(DataOutputStream out) {
@@ -4,11 +4,7 @@ import io.ebeaninternal.server.persist.MultiValueWrapper;
import io.ebeaninternal.server.querydefn.NaturalKeyBindParam;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
/**
@@ -17,35 +13,28 @@ import java.util.Map.Entry;
* Supports ordered or named parameters.
* </p>
*/
public class BindParams implements Serializable {
public final class BindParams implements Serializable {
private static final long serialVersionUID = 4541081933302086285L;
private final List<Param> positionedParameters = new ArrayList<>();
private final Map<String, Param> namedParameters = new LinkedHashMap<>();
/**
* This is the sql. For named parameters this is the sql after the named
* parameters have been replaced with question mark place holders and the
* parameters have been ordered by addNamedParamInOrder().
*/
private String preparedSql;
/**
* Bind hash and count used to detect when the bind values have changed such
* that the generated SQL (with named parameters) needs to be recalculated.
*/
private String bindHash;
/**
* Helper to add positioned parameters in order.
*/
private int addPos;
public BindParams() {
}
/**
* Reset positioned parameters (usually due to bind parameter expansion).
*/
@@ -54,12 +43,11 @@ public class BindParams implements Serializable {
positionedParameters.clear();
}
public int queryBindHash() {
int hc = namedParameters.hashCode();
for (Param positionedParameter : positionedParameters) {
hc = hc * 92821 + positionedParameter.hashCode();
public void queryBindHash(BindValuesKey key) {
key.add(positionedParameters.size());
for (Param param : positionedParameters) {
param.queryBindHash(key);
}
return hc;
}
/**
@@ -424,7 +412,14 @@ public class BindParams implements Serializable {
@Override
public boolean equals(Object o) {
return o != null && (o == this || (o instanceof Param) && hashCode() == o.hashCode());
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Param param = (Param) o;
return isInParam == param.isInParam && isOutParam == param.isOutParam && type == param.type && Objects.equals(inValue, param.inValue);
}
void queryBindHash(BindValuesKey key) {
key.add(isInParam).add(isOutParam).add(type).add(inValue);
}
/**
@@ -0,0 +1,35 @@
package io.ebeaninternal.api;
import java.util.ArrayList;
import java.util.List;
/**
* BindValues used for L2 query cache key matching.
* <p>
* The equals/hashCode implementation must meet the requirement that the query bind values
* match for L2 query cache hit (given the query plan hash is already a match).
*/
public final class BindValuesKey {
private final List<Object> values = new ArrayList<>();
/**
* Add a bind value.
*/
public BindValuesKey add(Object value) {
values.add(value);
return this;
}
@Override
public boolean equals(Object obj) {
return obj instanceof BindValuesKey && ((BindValuesKey) obj).values.equals(values);
}
@Override
public int hashCode() {
return values.hashCode();
}
}
@@ -11,10 +11,9 @@ import java.util.Set;
/**
* Used for bean cache lookup with where ids in expression.
*/
public class CacheIdLookupMany<T> implements CacheIdLookup<T> {
public final class CacheIdLookupMany<T> implements CacheIdLookup<T> {
private final IdInExpression idInExpression;
private int remaining;
public CacheIdLookupMany(IdInExpression idInExpression) {
@@ -7,7 +7,7 @@ import java.util.List;
/**
* Used for bean cache lookup with a single id value.
*/
public class CacheIdLookupSingle<T> implements CacheIdLookup<T> {
public final class CacheIdLookupSingle<T> implements CacheIdLookup<T> {
private final Object idValue;
private boolean found;
@@ -1,16 +1,12 @@
package io.ebeaninternal.api;
import io.ebean.annotation.Platform;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Helper to indicate that an EbeanServer should come up offline
* typically for DDL generation purposes.
*/
public class DbOffline {
private static final Logger logger = LoggerFactory.getLogger(DbOffline.class);
public final class DbOffline {
private static final String KEY = "ebean.dboffline";
@@ -73,7 +69,6 @@ public class DbOffline {
public static void reset() {
generateMigration = false;
System.clearProperty(KEY);
logger.debug("reset");
}
}
@@ -8,7 +8,7 @@ import io.ebean.metric.TimedMetric;
/**
* Extra metrics collected to measure internal behaviour.
*/
public class ExtraMetrics {
public final class ExtraMetrics {
private final TimedMetric bindCapture;
private final TimedMetric planCollect;
@@ -3,18 +3,17 @@ package io.ebeaninternal.api;
/**
* A hash key for a query including both the query plan and bind values.
*/
public class HashQuery {
public final class HashQuery {
private final CQueryPlanKey planHash;
private final int bindHash;
private final BindValuesKey bindValuesKey;
/**
* Create the HashQuery.
*/
public HashQuery(CQueryPlanKey planHash, int bindHash) {
public HashQuery(CQueryPlanKey planHash, BindValuesKey bindValuesKey) {
this.planHash = planHash;
this.bindHash = bindHash;
this.bindValuesKey = bindValuesKey;
}
@Override
@@ -25,7 +24,7 @@ public class HashQuery {
@Override
public int hashCode() {
int hc = 92821 * planHash.hashCode();
hc = 92821 * hc + bindHash;
hc = 92821 * hc + bindValuesKey.hashCode();
return hc;
}
@@ -37,8 +36,7 @@ public class HashQuery {
if (!(obj instanceof HashQuery)) {
return false;
}
HashQuery e = (HashQuery) obj;
return e.bindHash == bindHash && e.planHash.equals(planHash);
return e.bindValuesKey.equals(bindValuesKey) && e.planHash.equals(planHash);
}
}
@@ -6,7 +6,7 @@ import io.ebean.TxScope;
/**
* Helper object to make AOP generated code simpler.
*/
public class HelpScopeTrans {
public final class HelpScopeTrans {
private static boolean enabled = true;
/**
@@ -13,16 +13,12 @@ import java.util.Set;
/**
* Request for loading ManyToOne and OneToOne relationships.
*/
public class LoadBeanRequest extends LoadRequest {
public final class LoadBeanRequest extends LoadRequest {
private final List<EntityBeanIntercept> batch;
private final LoadBeanBuffer loadBuffer;
private final String lazyLoadProperty;
private final boolean loadCache;
private boolean loadedFromCache;
/**
@@ -92,9 +88,7 @@ public class LoadBeanRequest extends LoadRequest {
* Return the list of Id values for the beans in the lazy load buffer.
*/
public List<Object> getIdList() {
List<Object> idList = new ArrayList<>();
BeanDescriptor<?> desc = loadBuffer.getBeanDescriptor();
for (EntityBeanIntercept ebi : batch) {
idList.add(desc.getId(ebi.getOwner()));
@@ -106,10 +100,8 @@ public class LoadBeanRequest extends LoadRequest {
* Configure the query for lazy loading execution.
*/
public void configureQuery(SpiQuery<?> query, List<Object> idList) {
query.setMode(SpiQuery.Mode.LAZYLOAD_BEAN);
query.setPersistenceContext(loadBuffer.getPersistenceContext());
String mode = isLazy() ? "+lazy" : "+query";
query.setLoadDescription(mode, getDescription());
@@ -117,9 +109,7 @@ public class LoadBeanRequest extends LoadRequest {
// cascade the batch size (if set) for further lazy loading
query.setLazyLoadBatchSize(getBatchSize());
}
loadBuffer.configureQuery(query, lazyLoadProperty);
if (idList.size() == 1) {
query.where().idEq(idList.get(0));
} else {
@@ -131,19 +121,16 @@ public class LoadBeanRequest extends LoadRequest {
* Load the beans into the L2 cache if that is requested and check for load failures due to deletes.
*/
public void postLoad(List<?> list) {
Set<Object> loadedIds = new HashSet<>();
BeanDescriptor<?> desc = loadBuffer.getBeanDescriptor();
// collect Ids and maybe load bean cache
for (Object aList : list) {
EntityBean loadedBean = (EntityBean) aList;
for (Object bean : list) {
EntityBean loadedBean = (EntityBean) bean;
loadedIds.add(desc.getId(loadedBean));
}
if (isLoadCache()) {
desc.cacheBeanPutAll(list);
}
if (lazyLoadProperty != null) {
for (EntityBeanIntercept ebi : batch) {
// check if the underlying row in DB was deleted. Mark the bean as 'failed' if
@@ -15,16 +15,13 @@ import java.util.List;
/**
* Request for loading Associated Many Beans.
*/
public class LoadManyRequest extends LoadRequest {
public final class LoadManyRequest extends LoadRequest {
private static final Logger logger = LoggerFactory.getLogger(LoadManyRequest.class);
private final List<BeanCollection<?>> batch;
private final LoadManyBuffer loadContext;
private final boolean onlyIds;
private final boolean loadCache;
/**
@@ -17,16 +17,13 @@ import java.util.TreeSet;
* Holds the joins needs to support the many where predicates.
* These joins are independent of any 'fetch' joins on the many.
*/
public class ManyWhereJoins implements Serializable {
public final class ManyWhereJoins implements Serializable {
private static final long serialVersionUID = -6490181101871795417L;
private final TreeMap<String, PropertyJoin> joins = new TreeMap<>();
private List<String> formulaJoinProperties;
private boolean aggregation;
/**
* 'Mode' indicating that joins added while this is true are required to be outer joins.
*/
@@ -1,12 +0,0 @@
package io.ebeaninternal.api;
import java.io.Serializable;
/**
* Object used as a synchronization monitor that is serializable.
*/
public class Monitor implements Serializable {
private static final long serialVersionUID = -2741687226680981940L;
}
@@ -11,7 +11,7 @@ import java.util.Map;
/**
* Natural key entry with name value pairs for each of the properties making up the key.
*/
class NaturalKeyEntryBasic implements NaturalKeyEntry {
final class NaturalKeyEntryBasic implements NaturalKeyEntry {
private final Map<String,Object> map = new HashMap<>();
private final String key;
@@ -1,6 +1,6 @@
package io.ebeaninternal.api;
class NaturalKeyEntrySimple implements NaturalKeyEntry {
final class NaturalKeyEntrySimple implements NaturalKeyEntry {
private final String key;
private final Object val;
@@ -3,7 +3,7 @@ package io.ebeaninternal.api;
/**
* A property value pair in a natural key lookup.
*/
public class NaturalKeyEq {
public final class NaturalKeyEq {
final String property;
final Object value;
@@ -11,28 +11,22 @@ import java.util.Set;
/**
* Collects the data for processing the natural key cache processing.
*/
public class NaturalKeyQueryData<T> {
public final class NaturalKeyQueryData<T> {
private final BeanNaturalKey naturalKey;
/**
* Only one of IN or IN PAIRS is allowed.
*/
private boolean hasIn;
// IN Pairs clause - only one allowed
private String inProperty0, inProperty1;
private List<Pairs.Entry> inPairs;
// IN clause - only one allowed
private List<Object> inValues;
private String inProperty;
// normal EQ expressions
private List<NaturalKeyEq> eqList;
private NaturalKeySet set;
private int hitCount;
public NaturalKeyQueryData(BeanNaturalKey naturalKey) {
@@ -4,8 +4,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
public class NaturalKeySet {
public final class NaturalKeySet {
private final Map<Object, NaturalKeyEntry> map = new LinkedHashMap<>();
@@ -2,7 +2,7 @@ package io.ebeaninternal.api;
import io.ebeaninternal.server.type.bindcapture.BindCapture;
class NoopQueryBindCapture implements SpiQueryBindCapture {
final class NoopQueryBindCapture implements SpiQueryBindCapture {
@Override
public boolean collectFor(long timeMicros) {
@@ -6,7 +6,7 @@ import io.ebean.meta.QueryPlanRequest;
import java.util.Collections;
import java.util.List;
class NoopQueryPlanManager implements QueryPlanManager {
final class NoopQueryPlanManager implements QueryPlanManager {
@Override
public void setDefaultThreshold(long thresholdMicros) {
@@ -3,7 +3,7 @@ package io.ebeaninternal.api;
import io.ebean.annotation.Platform;
import io.ebean.util.StringHelper;
public class PlatformMatch {
public final class PlatformMatch {
/**
* Return true if the script platforms is a match/supported for the given platform.
@@ -15,7 +15,6 @@ public class PlatformMatch {
if (platforms == null || platforms.trim().isEmpty()) {
return true;
}
// match on base platform name and platform name
for (String name : StringHelper.splitNames(platforms)) {
if (name.equalsIgnoreCase(platform.base().name()) || name.equalsIgnoreCase(platform.name())) {
@@ -5,16 +5,9 @@ import io.ebeaninternal.server.query.SqlJoinType;
/**
* Represents a join required for a given property and whether than needs to be an outer join.
*/
public class PropertyJoin {
public final class PropertyJoin {
/**
* The property name.
*/
private final String property;
/**
* Set to true if the property needs to be an outer join.
*/
private final SqlJoinType joinType;
public PropertyJoin(String property, SqlJoinType joinType) {
@@ -7,7 +7,7 @@ import java.util.ArrayList;
/**
* Used internally to handle the scoping of transactions for methods.
*/
public class ScopeTrans {
public final class ScopeTrans {
private static final int OPCODE_ATHROW = 191;
@@ -15,43 +15,32 @@ public class ScopeTrans {
* The transaction in scope (can be null).
*/
private final SpiTransaction transaction;
/**
* If true by default rollback on Checked exceptions.
*/
private final boolean rollbackOnChecked;
/**
* True if the transaction was created and hence should be committed
* on finally if it hasn't already been rolled back.
*/
private final boolean created;
/**
* Explicit set of Exceptions that DO NOT cause a rollback to occur.
*/
private final ArrayList<Class<? extends Throwable>> noRollbackFor;
/**
* Explicit set of Exceptions that DO cause a rollback to occur.
*/
private final ArrayList<Class<? extends Throwable>> rollbackFor;
private Boolean restoreBatch;
private Boolean restoreBatchOnCascade;
private int restoreBatchSize;
private Boolean restoreBatchGeneratedKeys;
private boolean restoreBatchFlushOnQuery;
/**
* Flag set when a rollback has occurred.
*/
private boolean rolledBack;
/**
* Flag set when nested commit has occurred.
*/
@@ -10,15 +10,13 @@ import javax.persistence.PersistenceException;
*
* These can be nested and internally they are pushed and popped from a stack.
*/
public class ScopedTransaction extends SpiTransactionProxy {
public final class ScopedTransaction extends SpiTransactionProxy {
private final TransactionScopeManager manager;
/**
* Stack of 'nested' transactions.
*/
private final ArrayStack<ScopeTrans> stack = new ArrayStack<>();
private ScopeTrans current;
/**
@@ -8,6 +8,7 @@ import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
import io.ebean.meta.MetricVisitor;
import io.ebeaninternal.api.SpiQuery.Type;
import io.ebeaninternal.server.core.SpiResultSet;
import io.ebeaninternal.server.core.timezone.DataTimeZone;
import io.ebeaninternal.server.deploy.BeanDescriptor;
@@ -149,7 +150,7 @@ public interface SpiEbeanServer extends ExtendedServer, EbeanServer, BeanCollect
/**
* Compile a query.
*/
<T> CQuery<T> compileQuery(Query<T> query, Transaction t);
<T> CQuery<T> compileQuery(Type type, Query<T> query, Transaction t);
/**
* Execute the findId's query but without copying the query.
@@ -54,9 +54,9 @@ public interface SpiExpression extends Expression {
void queryPlanHash(StringBuilder builder);
/**
* Return the hash value for the values that will be bound.
* Build the key for bind values of the query.
*/
int queryBindHash();
void queryBindKey(BindValuesKey key);
/**
* Return true if the expression is the same with respect to bind values.
@@ -8,10 +8,9 @@ import java.util.Set;
/**
* Property expression validation request for a given root bean type.
*/
public class SpiExpressionValidation {
public final class SpiExpressionValidation {
private final BeanType<?> desc;
private final LinkedHashSet<String> unknown = new LinkedHashSet<>();
public SpiExpressionValidation(BeanType<?> desc) {
@@ -84,7 +84,7 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
/**
* Find single attribute.
*/
ATTRIBUTE(FIND_ATTRIBUTE, "findAttribute"),
ATTRIBUTE(FIND_ATTRIBUTE, "findAttribute", false, false),
/**
* Find rowCount.
@@ -92,9 +92,14 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
COUNT(FIND_COUNT, "findCount"),
/**
* A subquery used as part of a where clause.
* A subquery used as part of an exists where clause.
*/
SUBQUERY(FIND_SUBQUERY, "subquery"),
SQ_EXISTS(FIND_SUBQUERY, "sqExists", false, false),
/**
* A subquery used as part of an in where clause.
*/
SQ_IN(FIND_SUBQUERY, "sqIn", false, false),
/**
* Delete query.
@@ -107,17 +112,21 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
UPDATE(FIND_UPDATE, "update", true);
private final boolean update;
private final boolean defaultSelect;
private final String profileEventId;
private final String label;
Type(String profileEventId, String label) {
this(profileEventId, label, false);
this(profileEventId, label, false, true);
}
Type(String profileEventId, String label, boolean update) {
this(profileEventId, label, update, true);
}
Type(String profileEventId, String label, boolean update, boolean defaultSelect) {
this.profileEventId = profileEventId;
this.label = label;
this.update = update;
this.defaultSelect = defaultSelect;
}
/**
@@ -127,6 +136,13 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
return update;
}
/**
* Return true if this allows default select clause.
*/
public boolean defaultSelect() {
return defaultSelect;
}
public String profileEventId() {
return profileEventId;
}
@@ -629,13 +645,11 @@ public interface SpiQuery<T> extends Query<T>, SpiQueryFetch, TxnProfileEventCod
CQueryPlanKey prepare(SpiOrmQueryRequest<T> request);
/**
* Calculate a hash based on the bind values used in the query.
* Build the key for the bind values used in the query (for l2 query cache).
* <p>
* Combined with queryPlanHash() to return getQueryHash (a unique hash for a
* query).
* </p>
* Combined with queryPlanHash() to return queryHash (a unique key for a query).
*/
int queryBindHash();
void queryBindKey(BindValuesKey key);
/**
* Identifies queries that are exactly the same including bind variables.
@@ -20,7 +20,7 @@ public interface SpiQueryPlan {
/**
* The hash of the sql.
*/
long getSqlHash();
String getHash();
/**
* The SQL for the query plan.
@@ -20,7 +20,7 @@ import java.util.List;
* to the TransactionEventManager.
* </p>
*/
public class TransactionEvent implements Serializable {
public final class TransactionEvent implements Serializable {
private static final long serialVersionUID = 7230903304106097120L;
@@ -29,13 +29,9 @@ public class TransactionEvent implements Serializable {
* the cluster).
*/
private final transient boolean local;
private TransactionEventTable eventTables;
private transient List<PersistRequestBean<?>> listenerNotify;
private transient DeleteByIdMap deleteByIdMap;
private transient CacheChangeSet changeSet;
/**
@@ -110,11 +106,9 @@ public class TransactionEvent implements Serializable {
* Build and return the cache changeSet.
*/
public CacheChangeSet buildCacheChanges(TransactionManager manager) {
if (changeSet == null && deleteByIdMap == null && eventTables == null) {
return null;
}
if (changeSet == null) {
changeSet = new CacheChangeSet();
}
@@ -28,20 +28,17 @@ public final class TransactionEventTable implements Serializable, BinaryWritable
}
public void add(TransactionEventTable table) {
for (TableIUD iud : table.values()) {
add(iud);
}
}
public void add(String table, boolean insert, boolean update, boolean delete) {
table = table.toUpperCase();
add(new TableIUD(table, insert, update, delete));
}
public void add(TableIUD newTableIUD) {
TableIUD existingTableIUD = map.put(newTableIUD.getTableName(), newTableIUD);
if (existingTableIUD != null) {
newTableIUD.add(existingTableIUD);
@@ -56,7 +53,7 @@ public final class TransactionEventTable implements Serializable, BinaryWritable
return map.values();
}
public static class TableIUD implements Serializable, BulkTableEvent, BinaryWritable {
public static final class TableIUD implements Serializable, BulkTableEvent, BinaryWritable {
private static final long serialVersionUID = -1958317571064162089L;
@@ -73,12 +70,10 @@ public final class TransactionEventTable implements Serializable, BinaryWritable
}
public static TableIUD readBinaryMessage(BinaryReadContext dataInput) throws IOException {
String table = dataInput.readUTF();
boolean insert = dataInput.readBoolean();
boolean update = dataInput.readBoolean();
boolean delete = dataInput.readBoolean();
return new TableIUD(table, insert, update, delete);
}
@@ -17,7 +17,7 @@ import java.util.Set;
/**
* Utility that converts between JSON content and simple java Maps/Lists.
*/
public class DJsonService implements SpiJsonService {
public final class DJsonService implements SpiJsonService {
/**
* Write the nested Map/List as json.
@@ -14,7 +14,7 @@ import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
class EJsonReader {
final class EJsonReader {
static final JsonFactory json = new JsonFactory();
@@ -14,7 +14,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
class EJsonWriter {
final class EJsonWriter {
/**
* Base jsonFactory implementation used when it is not passed in.
@@ -7,7 +7,7 @@ import java.io.Serializable;
/**
* Detects when content has been modified and as such needs to be persisted (included in an update).
*/
public class ModifyAwareFlag implements ModifyAwareType, Serializable {
public final class ModifyAwareFlag implements ModifyAwareType, Serializable {
private static final long serialVersionUID = 1;
@@ -7,10 +7,9 @@ import java.util.Iterator;
/**
* Wraps an iterator for the purposes of detecting modifications.
*/
public class ModifyAwareIterator<E> implements Iterator<E> {
public final class ModifyAwareIterator<E> implements Iterator<E> {
private final ModifyAwareType owner;
private final Iterator<E> it;
/**
@@ -13,12 +13,11 @@ import java.util.Objects;
/**
* Modify aware wrapper of a list.
*/
public class ModifyAwareList<E> implements List<E>, ModifyAwareType, Serializable {
public final class ModifyAwareList<E> implements List<E>, ModifyAwareType, Serializable {
private static final long serialVersionUID = 1;
final List<E> list;
final ModifyAwareType owner;
public ModifyAwareList(List<E> list) {
@@ -7,10 +7,9 @@ import java.util.ListIterator;
/**
* Modify aware wrapper of a ListIterator.
*/
public class ModifyAwareListIterator<E> implements ListIterator<E> {
public final class ModifyAwareListIterator<E> implements ListIterator<E> {
final ModifyAwareType owner;
final ListIterator<E> iterator;
public ModifyAwareListIterator(ModifyAwareType owner, ListIterator<E> iterator) {
@@ -12,15 +12,11 @@ import java.util.Set;
/**
* Map that is wraps an underlying map for the purpose of detecting changes.
*/
public class ModifyAwareMap<K, V> implements Map<K, V>, ModifyAwareType, Serializable {
public final class ModifyAwareMap<K, V> implements Map<K, V>, ModifyAwareType, Serializable {
private static final long serialVersionUID = 1;
final ModifyAwareType owner;
/**
* The underlying map.
*/
final Map<K, V> map;
public ModifyAwareMap(Map<K, V> underlying) {
@@ -11,13 +11,12 @@ import java.util.Set;
/**
* Wraps a Set for the purposes of detecting modifications.
*/
public class ModifyAwareSet<E> implements Set<E>, ModifyAwareType, Serializable {
public final class ModifyAwareSet<E> implements Set<E>, ModifyAwareType, Serializable {
private static final long serialVersionUID = 1;
protected final ModifyAwareType owner;
protected final Set<E> set;
private final ModifyAwareType owner;
private final Set<E> set;
/**
* Create as top level with it's own ModifyAwareOwner instance wrapping the given Set.
@@ -8,7 +8,7 @@ import io.ebeaninternal.server.core.DefaultContainer;
/**
* Default container factory found via service loader.
*/
public class DContainerFactory implements SpiContainerFactory {
public final class DContainerFactory implements SpiContainerFactory {
@Override
public SpiContainer create(ContainerConfig containerConfig) {
@@ -5,7 +5,7 @@ import io.ebeaninternal.api.SpiQuery;
/**
* Noop service when AutoTuneService is not available.
*/
public class NoAutoTuneService implements AutoTuneService {
public final class NoAutoTuneService implements AutoTuneService {
@Override
public void startup() {
@@ -8,10 +8,9 @@ import java.util.Collection;
/**
* Change to remove bean from L2 cache.
*/
class CacheChangeBeanRemove implements CacheChange {
final class CacheChangeBeanRemove implements CacheChange {
private final BeanDescriptor<?> descriptor;
private final Collection<Object> ids;
CacheChangeBeanRemove(Object id, BeanDescriptor<?> descriptor) {
@@ -7,7 +7,7 @@ import java.util.Map;
/**
* Put a new bean entry into the cache.
*/
class CacheChangeBeanUpdate implements CacheChange {
final class CacheChangeBeanUpdate implements CacheChange {
private final BeanDescriptor<?> desc;
private final String key;
@@ -5,7 +5,7 @@ import io.ebeaninternal.server.deploy.BeanDescriptor;
/**
* Change the natural key mapping for a bean.
*/
class CacheChangeNaturalKeyPut implements CacheChange {
final class CacheChangeNaturalKeyPut implements CacheChange {
private final BeanDescriptor<?> descriptor;
private final String key;
@@ -14,18 +14,13 @@ import java.util.Set;
/**
* List of changes to be applied to L2 cache.
*/
public class CacheChangeSet {
public final class CacheChangeSet {
private final List<CacheChange> entries = new ArrayList<>();
private final Set<String> touchedTables = new HashSet<>();
private final Set<BeanDescriptor<?>> queryCaches = new HashSet<>();
private final Set<BeanDescriptor<?>> beanCaches = new HashSet<>();
private final Map<BeanDescriptor<?>, CacheChangeBeanRemove> beanRemoveMap = new HashMap<>();
private final Map<ManyKey, ManyChange> manyChangeMap = new HashMap<>();
/**
@@ -173,14 +168,11 @@ public class CacheChangeSet {
/**
* Changes for a specific many property.
*/
private static class ManyChange implements CacheChange {
private static final class ManyChange implements CacheChange {
final ManyKey key;
final Set<Object> removes = new HashSet<>();
final Map<Object, CachedManyIds> puts = new LinkedHashMap<>();
boolean clear;
ManyChange(ManyKey key) {
@@ -229,10 +221,9 @@ public class CacheChangeSet {
/**
* Key for changes on a many property.
*/
private static class ManyKey {
private static final class ManyKey {
private final BeanDescriptor<?> desc;
private final String manyProperty;
ManyKey(BeanDescriptor<?> desc, String manyProperty) {
@@ -10,18 +10,13 @@ import io.ebeaninternal.server.cluster.ClusterManager;
/**
* Configuration options when creating the default cache manager.
*/
public class CacheManagerOptions {
public final class CacheManagerOptions {
private final ClusterManager clusterManager;
private final DatabaseConfig databaseConfig;
private final boolean localL2Caching;
private CurrentTenantProvider currentTenantProvider;
private QueryCacheEntryValidate queryCacheEntryValidate;
private ServerCacheFactory cacheFactory = new DefaultServerCacheFactory();
private ServerCacheOptions beanDefault = new ServerCacheOptions();
private ServerCacheOptions queryDefault = new ServerCacheOptions();
@@ -11,13 +11,12 @@ import java.util.Map;
/**
* Data held in the bean cache for cached beans.
*/
public class CachedBeanData implements Externalizable {
public final class CachedBeanData implements Externalizable {
private long whenCreated;
private long version;
private String discValue;
private Map<String, Object> data;
/**
* The sharable bean is effectively transient (near cache only).
*/
@@ -9,10 +9,9 @@ import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
import java.util.LinkedHashMap;
import java.util.Map;
public class CachedBeanDataFromBean {
public final class CachedBeanDataFromBean {
public static CachedBeanData extract(BeanDescriptor<?> desc, EntityBean bean) {
EntityBeanIntercept ebi = bean._ebean_getIntercept();
Map<String, Object> data = new LinkedHashMap<>();
@@ -46,7 +45,6 @@ public class CachedBeanDataFromBean {
}
private static EntityBean createSharableBean(BeanDescriptor<?> desc, EntityBean bean, EntityBeanIntercept beanEbi) {
if (!desc.isCacheSharableBeans() || !beanEbi.isFullyLoadedBean()) {
return null;
}
@@ -7,30 +7,24 @@ import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.BeanProperty;
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
public class CachedBeanDataToBean {
public final class CachedBeanDataToBean {
public static void load(BeanDescriptor<?> desc, EntityBean bean, CachedBeanData cacheBeanData, PersistenceContext context) {
EntityBeanIntercept ebi = bean._ebean_getIntercept();
// any future lazy loading skips L2 bean cache
ebi.setLoadedFromCache(true);
BeanProperty idProperty = desc.getIdProperty();
if (desc.getInheritInfo() != null) {
desc = desc.getInheritInfo().readType(bean.getClass()).desc();
}
if (idProperty != null) {
// load the id property
loadProperty(bean, cacheBeanData, ebi, idProperty, context);
}
// load the non-many properties
for (BeanProperty prop : desc.propertiesNonMany()) {
loadProperty(bean, cacheBeanData, ebi, prop, context);
}
for (BeanPropertyAssocMany<?> prop : desc.propertiesMany()) {
if (prop.isElementCollection()) {
loadProperty(bean, cacheBeanData, ebi, prop, context);
@@ -38,12 +32,10 @@ public class CachedBeanDataToBean {
prop.createReferenceIfNull(bean);
}
}
ebi.setLoadedLazy();
}
private static void loadProperty(EntityBean bean, CachedBeanData cacheBeanData, EntityBeanIntercept ebi, BeanProperty prop, PersistenceContext context) {
if (cacheBeanData.isLoaded(prop.getName())) {
if (!ebi.isLoadedProperty(prop.getPropertyIndex())) {
Object value = cacheBeanData.getData(prop.getName());
@@ -10,7 +10,7 @@ import java.io.ObjectOutput;
* <p>
* Put into L2 cache such that we know the type of a bean with inheritance.
*/
public class CachedBeanId implements Externalizable {
public final class CachedBeanId implements Externalizable {
private String discValue;
private Object id;
@@ -13,7 +13,7 @@ import java.util.List;
* This is effectively just the Id values for each of the beans in the collection.
* </p>
*/
public class CachedManyIds implements Externalizable {
public final class CachedManyIds implements Externalizable {
private List<Object> idList;
@@ -13,7 +13,7 @@ import java.util.List;
* Used to hide the Supplier part of the SpiCacheManager API from public use.
* </p>
*/
public class DefaultCacheAdapter implements ServerCacheManager {
public final class DefaultCacheAdapter implements ServerCacheManager {
private final SpiCacheManager cacheManager;
@@ -23,14 +23,13 @@ import java.util.concurrent.locks.ReentrantLock;
/**
* Manages the construction of caches.
*/
class DefaultCacheHolder {
final class DefaultCacheHolder {
private static final Logger log = LoggerFactory.getLogger("io.ebean.cache.ALL");
private final ReentrantLock lock = new ReentrantLock();
private final ConcurrentHashMap<String, ServerCache> allCaches = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Set<String>> collectIdCaches = new ConcurrentHashMap<>();
private final ServerCacheFactory cacheFactory;
private final ServerCacheOptions beanDefault;
private final ServerCacheOptions queryDefault;
@@ -76,7 +75,6 @@ class DefaultCacheHolder {
* Return the cache for a given bean type.
*/
private ServerCache getCacheInternal(Class<?> beanType, ServerCacheType type, String collectionProperty) {
String shortName = key(beanType.getSimpleName(), collectionProperty, type);
String fullKey = key(beanType.getName(), collectionProperty, type);
return allCaches.computeIfAbsent(fullKey, s -> createCache(beanType, type, fullKey, shortName));
@@ -143,10 +141,8 @@ class DefaultCacheHolder {
}
private ServerCacheOptions getBeanOptions(Class<?> cls) {
Cache cache = cls.getAnnotation(Cache.class);
boolean nearCache = (cache != null && cache.nearCache());
CacheBeanTuning tuning = cls.getAnnotation(CacheBeanTuning.class);
if (tuning != null) {
return new ServerCacheOptions(nearCache, tuning).applyDefaults(beanDefault);
@@ -11,6 +11,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
@@ -37,8 +38,7 @@ public class DefaultServerCache implements ServerCache {
/**
* The underlying map (ConcurrentHashMap or similar)
*/
protected final Map<Object, CacheEntry> map;
protected final Map<Object, SoftReference<CacheEntry>> map;
protected final CountMetric hitCount;
protected final CountMetric missCount;
protected final CountMetric putCount;
@@ -48,16 +48,11 @@ public class DefaultServerCache implements ServerCache {
protected final String name;
protected final String shortName;
private int maxSize;
private final int maxSize;
private final int trimFrequency;
private int maxIdleSecs;
private int maxSecsToLive;
private TenantAwareKey tenantAwareKey;
private final int maxIdleSecs;
private final int maxSecsToLive;
private final TenantAwareKey tenantAwareKey;
public DefaultServerCache(DefaultServerCacheConfig config) {
this.name = config.getName();
@@ -70,7 +65,6 @@ public class DefaultServerCache implements ServerCache {
this.trimFrequency = config.determineTrimFrequency();
MetricFactory factory = MetricFactory.get();
String prefix = "l2n.";
this.hitCount = factory.createCountMetric(prefix + shortName + ".hit");
this.missCount = factory.createCountMetric(prefix + shortName + ".miss");
@@ -81,9 +75,7 @@ public class DefaultServerCache implements ServerCache {
}
public void periodicTrim(BackgroundExecutor executor) {
EvictionRunnable trim = new EvictionRunnable();
// default to trimming the cache every 60 seconds
long trimFreqSecs = (trimFrequency == 0) ? 60 : trimFrequency;
executor.scheduleWithFixedDelay(trim, trimFreqSecs, trimFreqSecs, TimeUnit.SECONDS);
@@ -101,11 +93,9 @@ public class DefaultServerCache implements ServerCache {
@Override
public ServerCacheStatistics getStatistics(boolean reset) {
ServerCacheStatistics cacheStats = new ServerCacheStatistics();
cacheStats.setCacheName(name);
cacheStats.setMaxSize(maxSize);
cacheStats.setSize(size());
cacheStats.setHitCount(hitCount.get(reset));
cacheStats.setMissCount(missCount.get(reset));
@@ -113,7 +103,6 @@ public class DefaultServerCache implements ServerCache {
cacheStats.setRemoveCount(removeCount.get(reset));
cacheStats.setClearCount(clearCount.get(reset));
cacheStats.setEvictCount(evictCount.get(reset));
return cacheStats;
}
@@ -133,10 +122,8 @@ public class DefaultServerCache implements ServerCache {
@Override
public int getHitRatio() {
long mc = missCount.get(false);
long hc = hitCount.get(false);
long totalCount = hc + mc;
if (totalCount == 0) {
return 0;
@@ -177,7 +164,6 @@ public class DefaultServerCache implements ServerCache {
*/
@Override
public Object get(Object id) {
CacheEntry entry = getCacheEntry(id);
if (entry == null) {
missCount.increment();
@@ -199,7 +185,8 @@ public class DefaultServerCache implements ServerCache {
* Get the cache entry - override for query cache to validate dependent tables.
*/
protected CacheEntry getCacheEntry(Object id) {
return map.get(key(id));
final SoftReference<CacheEntry> ref = map.get(key(id));
return ref != null ? ref.get() : null;
}
@Override
@@ -213,7 +200,7 @@ public class DefaultServerCache implements ServerCache {
@Override
public void put(Object id, Object value) {
Object key = key(id);
map.put(key, new CacheEntry(key, value));
map.put(key, new SoftReference<>(new CacheEntry(key, value)));
putCount.increment();
}
@@ -222,8 +209,8 @@ public class DefaultServerCache implements ServerCache {
*/
@Override
public void remove(Object id) {
CacheEntry entry = map.remove(key(id));
if (entry != null) {
SoftReference<CacheEntry> entry = map.remove(key(id));
if (entry != null && entry.get() != null) {
removeCount.increment();
}
}
@@ -250,74 +237,69 @@ public class DefaultServerCache implements ServerCache {
* Run the eviction based on Idle time, Time to live and LRU last access.
*/
public void runEviction() {
long trimForMaxSize;
if (maxSize == 0) {
trimForMaxSize = 0;
} else {
trimForMaxSize = size() - maxSize;
}
if (maxIdleSecs == 0 && maxSecsToLive == 0 && trimForMaxSize < 0) {
// nothing to trim on this cache
return;
}
long startNanos = System.nanoTime();
long trimmedByIdle = 0;
long trimmedByGC = 0;
long trimmedByTTL = 0;
long trimmedByLRU = 0;
List<CacheEntry> activeList = new ArrayList<>(map.size());
long idleExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxIdleSecs);
long ttlExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxSecsToLive);
Iterator<CacheEntry> it = map.values().iterator();
Iterator<SoftReference<CacheEntry>> it = map.values().iterator();
while (it.hasNext()) {
CacheEntry cacheEntry = it.next();
if (maxIdleSecs > 0 && idleExpireNano > cacheEntry.getLastAccessTime()) {
SoftReference<CacheEntry> ref = it.next();
final CacheEntry cacheEntry = ref.get();
if (cacheEntry == null) {
it.remove();
trimmedByGC++;
} else if (maxIdleSecs > 0 && idleExpireNano > cacheEntry.getLastAccessTime()) {
it.remove();
trimmedByIdle++;
} else if (maxSecsToLive > 0 && ttlExpireNano > cacheEntry.getCreateTime()) {
it.remove();
trimmedByTTL++;
} else if (trimForMaxSize > 0) {
activeList.add(cacheEntry);
}
}
if (trimForMaxSize > 0) {
trimmedByLRU = activeList.size() - maxSize;
if (trimmedByLRU > 0) {
// sort into last access time ascending
activeList.sort(BY_LAST_ACCESS);
int trimSize = getTrimSize();
for (int i = trimSize; i < activeList.size(); i++) {
// remove if still in the cache
map.remove(activeList.get(i).getKey());
if (trimForMaxSize > 0 && activeList.size() > maxSize) {
// sort into last access time ascending
activeList.sort(BY_LAST_ACCESS);
int trimSize = getTrimSize();
for (int i = trimSize; i < activeList.size(); i++) {
// remove if still in the cache
if (map.remove(activeList.get(i).getKey()) != null) {
trimmedByLRU++;
}
}
}
evictCount.add(trimmedByIdle);
evictCount.add(trimmedByGC);
evictCount.add(trimmedByTTL);
evictCount.add(trimmedByLRU);
if (logger.isTraceEnabled()) {
long exeMicros = TimeUnit.MICROSECONDS.convert(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
logger.trace("Executed trim of cache {} in [{}]millis idle[{}] timeToLive[{}] accessTime[{}]"
, name, exeMicros, trimmedByIdle, trimmedByTTL, trimmedByLRU);
logger.trace("Executed trim of cache {} in [{}]millis idle[{}] timeToLive[{}] accessTime[{}] gc[{}]",
name, exeMicros, trimmedByIdle, trimmedByTTL, trimmedByLRU, trimmedByGC);
}
}
/**
* Runnable that calls the eviction routine.
*/
public class EvictionRunnable implements Runnable {
public final class EvictionRunnable implements Runnable {
@Override
public void run() {
@@ -328,7 +310,7 @@ public class DefaultServerCache implements ServerCache {
/**
* Comparator for sorting by last access time.
*/
public static class CompareByLastAccess implements Comparator<CacheEntry>, Serializable {
public static final class CompareByLastAccess implements Comparator<CacheEntry>, Serializable {
private static final long serialVersionUID = 1L;
@@ -341,7 +323,7 @@ public class DefaultServerCache implements ServerCache {
/**
* Wraps the value to additionally hold createTime and lastAccessTime and hit counter.
*/
public static class CacheEntry {
public static final class CacheEntry {
private final Object key;
private final Object value;
@@ -4,26 +4,26 @@ import io.ebean.cache.QueryCacheEntryValidate;
import io.ebean.cache.ServerCacheConfig;
import io.ebean.cache.ServerCacheOptions;
import io.ebean.config.CurrentTenantProvider;
import io.ebeaninternal.server.cache.DefaultServerCache.CacheEntry;
import java.lang.ref.SoftReference;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class DefaultServerCacheConfig {
public final class DefaultServerCacheConfig {
private final ServerCacheConfig config;
private int maxSize;
private int maxIdleSecs;
private int maxSecsToLive;
private int trimFrequency;
private Map<Object, DefaultServerCache.CacheEntry> map;
private final int maxSize;
private final int maxIdleSecs;
private final int maxSecsToLive;
private final int trimFrequency;
private final Map<Object, SoftReference<CacheEntry>> map;
public DefaultServerCacheConfig(ServerCacheConfig config) {
this(config, new ConcurrentHashMap<>());
}
public DefaultServerCacheConfig(ServerCacheConfig config, Map<Object, DefaultServerCache.CacheEntry> map) {
public DefaultServerCacheConfig(ServerCacheConfig config, Map<Object, SoftReference<CacheEntry>> map) {
this.config = config;
this.map = map;
@@ -50,7 +50,7 @@ public class DefaultServerCacheConfig {
return config.getShortName();
}
public Map<Object, DefaultServerCache.CacheEntry> getMap() {
public Map<Object, SoftReference<CacheEntry>> getMap() {
return map;
}
@@ -11,7 +11,7 @@ import io.ebean.cache.ServerCacheNotify;
/**
* Default implementation of ServerCacheFactory.
*/
class DefaultServerCacheFactory implements ServerCacheFactory {
final class DefaultServerCacheFactory implements ServerCacheFactory {
private final BackgroundExecutor executor;
@@ -31,7 +31,6 @@ class DefaultServerCacheFactory implements ServerCacheFactory {
@Override
public ServerCache createCache(ServerCacheConfig config) {
DefaultServerCache cache;
if (config.isQueryCache()) {
// use a server cache aware of extra validation and QueryCacheEntry
@@ -19,18 +19,14 @@ import java.util.Map;
/**
* Manages the bean and query caches.
*/
public class DefaultServerCacheManager implements SpiCacheManager {
public final class DefaultServerCacheManager implements SpiCacheManager {
private static final Logger log = LoggerFactory.getLogger("io.ebean.cache.REGION");
private final Map<String, SpiCacheRegion> regionMap = new HashMap<>();
private final ClusterManager clusterManager;
private final DefaultCacheHolder cacheHolder;
private final boolean localL2Caching;
private final String serverName;
/**
@@ -8,7 +8,7 @@ import io.ebean.config.DatabaseConfig;
/**
* Default implementation of ServerCachePlugin.
*/
public class DefaultServerCachePlugin implements ServerCachePlugin {
public final class DefaultServerCachePlugin implements ServerCachePlugin {
/**
* Creates the default ServerCacheFactory.
@@ -3,6 +3,8 @@ package io.ebeaninternal.server.cache;
import io.ebean.cache.QueryCacheEntry;
import io.ebean.cache.QueryCacheEntryValidate;
import java.lang.ref.SoftReference;
/**
* Server cache for query caching.
* <p>
@@ -27,7 +29,8 @@ public class DefaultServerQueryCache extends DefaultServerCache {
@Override
protected CacheEntry getCacheEntry(Object id) {
Object key = key(id);
CacheEntry entry = map.get(key);
final SoftReference<CacheEntry> ref = map.get(key);
CacheEntry entry = ref != null ? ref.get() : null;
if (entry == null) {
return null;
}
@@ -12,11 +12,10 @@ import java.util.List;
/**
* Cache events broadcast across the cluster.
*/
public class RemoteCacheEvent implements BinaryWritable {
public final class RemoteCacheEvent implements BinaryWritable {
private boolean clearAll;
private List<String> clearCaches;
private final boolean clearAll;
private final List<String> clearCaches;
/**
* Clear all the caches.
@@ -57,10 +56,8 @@ public class RemoteCacheEvent implements BinaryWritable {
}
public static RemoteCacheEvent readBinaryMessage(BinaryReadContext dataInput) throws IOException {
boolean clearAll = dataInput.readBoolean();
int size = dataInput.readInt();
List<String> clearCache = null;
if (size > 0) {
clearCache = new ArrayList<>(size);
@@ -68,7 +65,6 @@ public class RemoteCacheEvent implements BinaryWritable {
clearCache.add(dataInput.readUTF());
}
}
return new RemoteCacheEvent(clearAll, clearCache);
}
@@ -14,21 +14,14 @@ import java.util.Map;
/**
* Builds JSON document for a bean change.
*/
class ChangeJsonBuilder {
final class ChangeJsonBuilder {
protected final JsonFactory jsonFactory = new JsonFactory();
protected final JsonContext json;
ChangeJsonBuilder(JsonContext json) {
this.json = json;
}
private final JsonFactory jsonFactory = new JsonFactory();
/**
* Write the bean change as JSON.
*/
void writeBeanJson(Writer writer, BeanChange bean, ChangeSet changeSet) throws IOException {
try (JsonGenerator generator = jsonFactory.createGenerator(writer)) {
writeBeanChange(generator, bean, changeSet);
generator.flush();
@@ -39,9 +32,7 @@ class ChangeJsonBuilder {
* Write the bean change as JSON document containing the transaction header details.
*/
private void writeBeanChange(JsonGenerator gen, BeanChange bean, ChangeSet changeSet) throws IOException {
gen.writeStartObject();
gen.writeNumberField("ts", bean.getEventTime());
gen.writeStringField("change", bean.getEvent().getCode());
gen.writeStringField("type", bean.getType());
@@ -49,9 +40,7 @@ class ChangeJsonBuilder {
if (bean.getTenantId() != null) {
gen.writeStringField("tenantId", bean.getTenantId().toString());
}
writeBeanTransactionDetails(gen, changeSet);
writeBeanValues(gen, bean);
gen.writeEndObject();
}
@@ -60,7 +49,6 @@ class ChangeJsonBuilder {
* Denormalise by writing the transaction header details.
*/
private void writeBeanTransactionDetails(JsonGenerator gen, ChangeSet changeSet) throws IOException {
String source = changeSet.getSource();
if (source != null) {
gen.writeStringField("source", source);
@@ -87,12 +75,10 @@ class ChangeJsonBuilder {
* For insert and update write the new/old values.
*/
private void writeBeanValues(JsonGenerator gen, BeanChange bean) throws IOException {
if (bean.getEvent() != ChangeType.DELETE) {
gen.writeFieldName("data");
gen.writeRaw(":");
gen.writeRaw(bean.getData());
String oldData = bean.getOldData();
if (oldData != null) {
gen.writeRaw(",\"oldData\":");
@@ -15,12 +15,12 @@ import java.util.Properties;
/**
* Simply logs the change sets in JSON form to logger named <code>io.ebean.ChangeLog</code>.
*/
public class DefaultChangeLogListener implements ChangeLogListener, Plugin {
public final class DefaultChangeLogListener implements ChangeLogListener, Plugin {
/**
* The usual application specific logger.
*/
protected static final Logger logger = LoggerFactory.getLogger(DefaultChangeLogListener.class);
private static final Logger logger = LoggerFactory.getLogger(DefaultChangeLogListener.class);
/**
* The named logger we send the change set payload to. Can be externally configured as desired.
@@ -45,8 +45,7 @@ public class DefaultChangeLogListener implements ChangeLogListener, Plugin {
*/
@Override
public void configure(SpiServer server) {
jsonBuilder = new ChangeJsonBuilder(server.json());
jsonBuilder = new ChangeJsonBuilder();
Properties properties = server.getServerConfig().getProperties();
if (properties != null) {
String bufferSize = properties.getProperty("ebean.changeLog.bufferSize");
@@ -11,7 +11,7 @@ import io.ebean.event.changelog.ChangeSet;
* on the changeSet.
* </p>
*/
public class DefaultChangeLogPrepare implements ChangeLogPrepare {
public final class DefaultChangeLogPrepare implements ChangeLogPrepare {
/**
* Just return true to send change set through to the logger.
@@ -14,10 +14,9 @@ import java.util.Set;
/**
* Default implementation of ChangeLogRegister.
*/
public class DefaultChangeLogRegister implements ChangeLogRegister {
public final class DefaultChangeLogRegister implements ChangeLogRegister {
private static final BasicFilter INCLUDE_INSERTS = new BasicFilter(true);
private static final BasicFilter EXCLUDE_INSERTS = new BasicFilter(false);
private final boolean defaultInsertsInclude;
@@ -31,20 +30,16 @@ public class DefaultChangeLogRegister implements ChangeLogRegister {
@Override
public ChangeLogFilter getChangeFilter(Class<?> beanType) {
ChangeLog changeLog = getChangeLog(beanType);
if (changeLog == null) {
return null;
}
String[] updatesThatInclude = changeLog.updatesThatInclude();
if (updatesThatInclude.length == 0) {
return insertModeInclude(changeLog.inserts()) ? INCLUDE_INSERTS : EXCLUDE_INSERTS;
}
Set<String> updateProps = new HashSet<>();
Collections.addAll(updateProps, updatesThatInclude);
return new UpdateFilter(insertModeInclude(changeLog.inserts()), updateProps);
}
@@ -23,25 +23,16 @@ import javax.persistence.PersistenceException;
public abstract class AbstractSqlQueryRequest implements CancelableQuery {
protected final SpiSqlBinding query;
protected final SpiEbeanServer server;
protected SpiTransaction transaction;
private boolean createdTransaction;
protected String sql;
protected ResultSet resultSet;
protected String bindLog = "";
protected PreparedStatement pstmt;
protected long startNano;
private final ReentrantLock lock = new ReentrantLock();
/**
* Create the BeanFindRequest.
*/
@@ -161,7 +152,8 @@ public abstract class AbstractSqlQueryRequest implements CancelableQuery {
this.bindLog = binder.bind(bindParams, pstmt, conn);
}
if (isLogSql()) {
transaction.logSql(Str.add(TrimLogSql.trim(sql), "; --bind(", bindLog, ")"));
long micros = (System.nanoTime() - startNano) / 1000L;
transaction.logSql(Str.add(TrimLogSql.trim(sql), "; --bind(", bindLog, ") --micros(", micros + ")"));
}
} finally {
lock.unlock();
@@ -33,7 +33,7 @@ public final class BindPadding {
* Extra padding on binding id's in order to get better hit ratio on DB prepared statements / query plans.
*/
static int padding(int size) {
if (size == 1) {
if (size <= 1) {
return 0;
}
if (size <= 5) {
@@ -17,7 +17,7 @@ import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
class DScriptRunner implements ScriptRunner {
final class DScriptRunner implements ScriptRunner {
private static final String NEWLINE = "\n";
@@ -36,9 +36,8 @@ import java.sql.SQLException;
/**
* Create a DatabasePlatform from the configuration.
* <p>
* Will used platform name or use the meta data from the JDBC driver to
* Will used platform name or use the metadata from the JDBC driver to
* determine the platform automatically.
* </p>
*/
public class DatabasePlatformFactory {
@@ -54,14 +53,12 @@ public class DatabasePlatformFactory {
logger.info("offline platform [{}]", offlinePlatform);
return byDatabaseName(offlinePlatform);
}
if (config.getDatabasePlatformName() != null) {
// choose based on dbName
return byDatabaseName(config.getDatabasePlatformName());
}
if (config.getDataSourceConfig().isOffline()) {
throw new PersistenceException("You must specify a DatabasePlatformName when you are offline");
throw new PersistenceException("DatabasePlatformName must be specified with offline mode");
}
// guess using meta data from driver
return byDataSource(config.getDataSource());
@@ -142,10 +139,10 @@ public class DatabasePlatformFactory {
* Find the platform by the metaData.getDatabaseProductName().
*/
private DatabasePlatform byDatabaseMeta(DatabaseMetaData metaData, Connection connection) throws SQLException {
String dbProductName = metaData.getDatabaseProductName().toLowerCase();
final int majorVersion = metaData.getDatabaseMajorVersion();
final int minorVersion = metaData.getDatabaseMinorVersion();
logger.debug("platform for productName[{}] version[{}.{}]", dbProductName, majorVersion, minorVersion);
if (dbProductName.contains("oracle")) {
return oracleVersion(majorVersion);
@@ -206,7 +203,6 @@ public class DatabasePlatformFactory {
} catch (SQLException e) {
logger.warn("Error running detection query on Postgres", e);
}
if (majorVersion <= 9) {
return new Postgres9Platform();
}
@@ -26,12 +26,11 @@ import java.util.List;
/**
* Helper to handle lazy loading and refreshing of beans.
*/
class DefaultBeanLoader {
final class DefaultBeanLoader {
private static final Logger logger = LoggerFactory.getLogger(DefaultBeanLoader.class);
private final DefaultServer server;
private final boolean onIterateUseExtraTxn;
DefaultBeanLoader(DefaultServer server) {
@@ -40,17 +39,14 @@ class DefaultBeanLoader {
}
void loadMany(LoadManyRequest loadRequest) {
SpiQuery<?> query = loadRequest.createQuery(server);
executeQuery(loadRequest, query);
loadRequest.postLoad();
}
void loadMany(BeanCollection<?> bc, boolean onlyIds) {
EntityBean parentBean = bc.getOwnerBean();
String propertyName = bc.getPropertyName();
loadManyInternal(parentBean, propertyName, null, false, onlyIds);
}
@@ -59,13 +55,10 @@ class DefaultBeanLoader {
}
private void loadManyInternal(EntityBean parentBean, String propertyName, Transaction t, boolean refresh, boolean onlyIds) {
EntityBeanIntercept ebi = parentBean._ebean_getIntercept();
PersistenceContext pc = ebi.getPersistenceContext();
BeanDescriptor<?> parentDesc = server.getBeanDescriptor(parentBean.getClass());
BeanPropertyAssocMany<?> many = (BeanPropertyAssocMany<?>) parentDesc.getBeanProperty(propertyName);
BeanCollection<?> beanCollection = null;
ExpressionList<?> filterMany = null;
@@ -126,7 +119,6 @@ class DefaultBeanLoader {
}
server.findOne(query, t);
if (beanCollection != null) {
if (beanCollection.checkEmptyLazyLoad()) {
if (logger.isDebugEnabled()) {
@@ -142,7 +134,6 @@ class DefaultBeanLoader {
* Load a batch of beans for +query or +lazy loading.
*/
void loadBean(LoadBeanRequest loadRequest) {
List<EntityBeanIntercept> batch = loadRequest.getBatch();
if (batch.isEmpty()) {
throw new RuntimeException("Nothing in batch?");
@@ -190,7 +181,6 @@ class DefaultBeanLoader {
}
private void refreshBeanInternal(EntityBean bean, SpiQuery.Mode mode, int embeddedOwnerIndex) {
EntityBeanIntercept ebi = bean._ebean_getIntercept();
PersistenceContext pc = ebi.getPersistenceContext();
if (Mode.REFRESH_BEAN == mode) {
@@ -203,12 +193,10 @@ class DefaultBeanLoader {
// lazy loading on an embedded bean property
EntityBean embeddedOwner = (EntityBean) ebi.getEmbeddedOwner();
int ownerIndex = ebi.getEmbeddedOwnerIndex();
refreshBeanInternal(embeddedOwner, mode, ownerIndex);
}
Object id = desc.getId(bean);
if (pc == null) {
// a reference with no existing persistenceContext
pc = new DefaultPersistenceContext();
@@ -216,7 +204,6 @@ class DefaultBeanLoader {
ebi.setPersistenceContext(pc);
}
boolean draft = desc.isDraftInstance(bean);
if (embeddedOwnerIndex == -1) {
if (desc.lazyLoadMany(ebi)) {
return;
@@ -246,16 +233,13 @@ class DefaultBeanLoader {
query.setPersistenceContext(pc);
query.setMode(mode);
query.setId(id);
if (embeddedOwnerIndex > -1 || mode == Mode.REFRESH_BEAN) {
// make sure the query doesn't use the cache
query.setUseCache(false);
}
if (ebi.isReadOnly()) {
query.setReadOnly(true);
}
if (Mode.REFRESH_BEAN == mode) {
// explicitly state to load all properties on REFRESH.
// Lobs default to fetch lazy so this forces lobs to be
@@ -268,7 +252,6 @@ class DefaultBeanLoader {
String msg = "Bean not found during lazy load or refresh." + " id[" + id + "] type[" + desc.getBeanType() + "]";
throw new EntityNotFoundException(msg);
}
desc.resetManyProperties(dbBean);
}
}
@@ -11,7 +11,7 @@ import java.util.Set;
/**
* Default implementation of BeanState.
*/
public class DefaultBeanState implements BeanState {
public final class DefaultBeanState implements BeanState {
private final EntityBeanIntercept intercept;
@@ -94,4 +94,8 @@ public class DefaultBeanState implements BeanState {
return intercept.getLoadErrors();
}
@Override
public int getSortOrder() {
return intercept.getSortOrder();
}
}
@@ -8,7 +8,7 @@ import java.util.Arrays;
/**
* Default CallStackFactory where the Hash function for StackTraceElement includes the line number.
*/
public class DefaultCallOriginFactory implements CallOriginFactory {
public final class DefaultCallOriginFactory implements CallOriginFactory {
private static final int IGNORE_LEADING_ELEMENTS = 5;
@@ -12,7 +12,7 @@ import java.sql.CallableStatement;
import java.sql.SQLException;
public class DefaultCallableSql implements Serializable, SpiCallableSql {
public final class DefaultCallableSql implements Serializable, SpiCallableSql {
private static final long serialVersionUID = 8984272253185424701L;
@@ -32,9 +32,9 @@ import java.util.concurrent.locks.ReentrantLock;
/**
* Default Server side implementation of ServerFactory.
*/
public class DefaultContainer implements SpiContainer {
public final class DefaultContainer implements SpiContainer {
private static final Logger logger = LoggerFactory.getLogger("io.ebean.internal.DefaultContainer");
private static final Logger logger = LoggerFactory.getLogger("io.ebean.DB");
private final ReentrantLock lock = new ReentrantLock();
private final ClusterManager clusterManager;
@@ -77,9 +77,10 @@ public class DefaultContainer implements SpiContainer {
public SpiEbeanServer createServer(DatabaseConfig config) {
lock.lock();
try {
long start = System.currentTimeMillis();
applyConfigServices(config);
setNamingConvention(config);
BootupClasses bootupClasses = getBootupClasses(config);
BootupClasses bootupClasses = bootupClasses(config);
boolean online = true;
if (config.isDocStoreOnly()) {
@@ -101,22 +102,18 @@ public class DefaultContainer implements SpiContainer {
// use a configured DbEncrypt rather than the platform default
config.getDatabasePlatform().setDbEncrypt(config.getDbEncrypt());
}
// inform the NamingConvention of the associated DatabasePlatform
config.getNamingConvention().setDatabasePlatform(config.getDatabasePlatform());
// executor and l2 caching service setup early (used during server construction)
SpiBackgroundExecutor executor = createBackgroundExecutor(config);
InternalConfiguration c = new InternalConfiguration(online, clusterManager, executor, config, bootupClasses);
DefaultServer server = new DefaultServer(c, c.cacheManager());
// generate and run DDL if required
// if there are any other tasks requiring action in their plugins, do them as well
// generate and run DDL if required plus other plugins
if (!DbOffline.isGenerateMigration()) {
startServer(online, server);
}
DbOffline.reset();
logger.info("started database[{}] platform[{}] in {}ms", config.getName(), config.getDatabasePlatform().getPlatform(), System.currentTimeMillis() - start);
return server;
} finally {
lock.unlock();
@@ -161,9 +158,8 @@ public class DefaultContainer implements SpiContainer {
* Get the entities, scalarTypes, Listeners etc combining the class registered
* ones with the already created instances.
*/
private BootupClasses getBootupClasses(DatabaseConfig config) {
BootupClasses bootup = getBootupClasses1(config);
private BootupClasses bootupClasses(DatabaseConfig config) {
BootupClasses bootup = bootupClasses1(config);
bootup.addIdGenerators(config.getIdGenerators());
bootup.addPersistControllers(config.getPersistControllers());
bootup.addPostLoaders(config.getPostLoaders());
@@ -173,7 +169,6 @@ public class DefaultContainer implements SpiContainer {
bootup.addQueryAdapters(config.getQueryAdapters());
bootup.addServerConfigStartup(config.getServerConfigStartupListeners());
bootup.addChangeLogInstances(config);
bootup.runServerConfigStartup(config);
return bootup;
}
@@ -181,14 +176,12 @@ public class DefaultContainer implements SpiContainer {
/**
* Get the class based entities, scalarTypes, Listeners etc.
*/
private BootupClasses getBootupClasses1(DatabaseConfig config) {
private BootupClasses bootupClasses1(DatabaseConfig config) {
List<Class<?>> entityClasses = config.getClasses();
if (config.isDisableClasspathSearch() || (entityClasses != null && !entityClasses.isEmpty())) {
// use classes we explicitly added via configuration
return new BootupClasses(entityClasses);
}
return BootupClassPathSearch.search(config);
}
@@ -205,7 +198,6 @@ public class DefaultContainer implements SpiContainer {
* Set the DatabasePlatform if it has not already been set.
*/
private void setDatabasePlatform(DatabaseConfig config) {
DatabasePlatform platform = config.getDatabasePlatform();
if (platform == null) {
if (config.getTenantMode().isDynamicDataSource()) {
@@ -215,7 +207,6 @@ public class DefaultContainer implements SpiContainer {
platform = new DatabasePlatformFactory().create(config);
config.setDatabasePlatform(platform);
}
logger.info("DatabasePlatform name:{} platform:{}", config.getName(), platform.getName());
platform.configure(config.getPlatformConfig());
}
@@ -255,6 +246,9 @@ public class DefaultContainer implements SpiContainer {
}
throw new RuntimeException("DataSource not set?");
}
if (config.skipDataSourceCheck()) {
return true;
}
try (Connection connection = config.getDataSource().getConnection()) {
if (connection.getAutoCommit()) {
logger.warn("DataSource [{}] has autoCommit defaulting to true!", config.getName());
@@ -19,7 +19,7 @@ import java.util.List;
/**
* DefaultServer based implementation of MetaInfoManager.
*/
public class DefaultMetaInfoManager implements MetaInfoManager {
final class DefaultMetaInfoManager implements MetaInfoManager {
private final DefaultServer server;
@@ -6,7 +6,7 @@ import io.ebean.meta.MetaQueryPlan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class DefaultQueryPlanListener implements QueryPlanListener {
final class DefaultQueryPlanListener implements QueryPlanListener {
static final QueryPlanListener INSTANT = new DefaultQueryPlanListener();
@@ -490,6 +490,11 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
}
@Override
public String toString() {
return "Database{" + serverName + "}";
}
/**
* Return the server name.
*/
@@ -526,8 +531,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
* Compile a query. Only valid for ORM queries.
*/
@Override
public <T> CQuery<T> compileQuery(Query<T> query, Transaction t) {
SpiOrmQueryRequest<T> qr = createQueryRequest(Type.SUBQUERY, query, t);
public <T> CQuery<T> compileQuery(Type type, Query<T> query, Transaction t) {
SpiOrmQueryRequest<T> qr = createQueryRequest(type, query, t);
OrmQueryRequest<T> orm = (OrmQueryRequest<T>) qr;
return cqueryEngine.buildQuery(orm);
}
@@ -2055,17 +2060,15 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return transactionManager;
}
public void register(BeanPersistController c) {
List<BeanDescriptor<?>> list = beanDescriptorManager.getBeanDescriptorList();
for (BeanDescriptor<?> aList : list) {
aList.register(c);
public void register(BeanPersistController controller) {
for (BeanDescriptor<?> desc : beanDescriptorManager.getBeanDescriptorList()) {
desc.register(controller);
}
}
public void deregister(BeanPersistController c) {
List<BeanDescriptor<?>> list = beanDescriptorManager.getBeanDescriptorList();
for (BeanDescriptor<?> aList : list) {
aList.deregister(c);
for (BeanDescriptor<?> desc : beanDescriptorManager.getBeanDescriptorList()) {
desc.deregister(c);
}
}
@@ -9,13 +9,12 @@ import org.slf4j.LoggerFactory;
/**
* Default slow query listener implementation that logs a warning message.
*/
class DefaultSlowQueryListener implements SlowQueryListener {
final class DefaultSlowQueryListener implements SlowQueryListener {
private static final Logger log = LoggerFactory.getLogger("io.ebean.SlowQuery");
@Override
public void process(SlowQueryEvent event) {
String firstStack = "";
ObjectGraphNode node = event.getOriginNode();
if (node != null) {
@@ -12,7 +12,7 @@ import java.util.Map;
* This intentionally does not include any OneToMany or ManyToMany properties.
* </p>
*/
public class DiffHelp {
public final class DiffHelp {
private DiffHelp() {
}
@@ -28,11 +28,9 @@ public class DiffHelp {
* </p>
*/
public static Map<String, ValuePair> diff(Object newBean, Object oldBean, BeanDescriptor<?> desc) {
if (!(newBean instanceof EntityBean)) {
throw new IllegalArgumentException("First bean expected to be an enhanced EntityBean? bean:" + newBean);
}
if (oldBean != null) {
if (!(oldBean instanceof EntityBean)) {
throw new IllegalArgumentException("Second bean expected to be an enhanced EntityBean? bean:" + oldBean);
@@ -41,11 +39,9 @@ public class DiffHelp {
throw new IllegalArgumentException("Second bean not assignable to the first bean?");
}
}
if (oldBean == null) {
return ((EntityBean) newBean)._ebean_getIntercept().getDirtyValues();
}
return desc.diff((EntityBean) newBean, (EntityBean) oldBean);
}

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