Compare commits

..
Author SHA1 Message Date
rob bygrave a80ab94479 [maven-release-plugin] prepare release ebean-parent-12.5.2 2020-11-11 22:47:12 +13:00
rob bygrave e6f0ab90dc #2094 - Refactor remove isJavaTimePresent() ... we are Java 8+ so removing effectively redundant code 2020-10-23 01:25:28 +13:00
rob bygrave 53f4739c8f #2093 - Refactor remove isJava7Present() ... we are Java 8+ so Java 7 types are always present - Removing effectively redundant code 2020-10-23 01:21:48 +13:00
rob bygrave c6e33ba3ac Modify pom names of modules for more consistency 2020-10-23 00:33:16 +13:00
rob bygrave 0e2528e542 #2092 - Add support for mocking Database interface to MockiEbean 2020-10-23 00:10:50 +13:00
rob bygrave 6ecc10a35c #2091 - Using Postgis types with query gives PersistenceException Caused by: java.sql.SQLException: Unhandled data type [6000] bind number[0] 2020-10-22 22:48:53 +13:00
rob bygrave 59bd2bb251 Add ebean-postgis module 2020-10-22 21:22:41 +13:00
rob bygrave 9fa83cdd5a Move into ebean-postgres sub directory 2020-10-22 21:18:18 +13:00
Rob BygraveandGitHub f383f3f759 Merge pull request #3 from tobias-/failing_test
Failing tests for query with postgis types
2020-10-22 20:56:22 +13:00
rob bygrave 0abcc9e06e #2085 - Refactor promote getDataSource() and getReadOnlyDataSource() to Database from plugin.SpiServer interface 2020-10-20 12:08:21 +13:00
rob bygrave 4a594b32ef Refactor modify SpiServer to extend Database (rather than EbeanServer) 2020-10-20 11:36:01 +13:00
rob bygrave 8b9f760cb2 Update tests for DatabaseFactory.create() with shutdown 2020-10-19 12:12:00 +13:00
rob bygrave 1d1cf76b5e Update poms adding name, description, change to use explicit snapshot version rather than project.version 2020-10-19 11:21:18 +13:00
rob bygrave 194c14b99a Post manual release of autotune, externalmapping-xml, querybean and test modules 2020-10-19 10:16:25 +13:00
rob bygrave fa8c6839dd [maven-release-plugin] prepare for next development iteration 2020-10-19 09:44:18 +13:00
rob bygrave f8e4ce6b4c [maven-release-plugin] prepare release ebean-test-12.5.1 2020-10-19 09:44:07 +13:00
rob bygrave cce496016d [maven-release-plugin] prepare for next development iteration 2020-10-19 09:38:53 +13:00
rob bygrave 2c4d5dc304 [maven-release-plugin] prepare release ebean-querybean-12.5.1 2020-10-19 09:38:42 +13:00
rob bygrave 1c981130b6 [maven-release-plugin] prepare for next development iteration 2020-10-19 09:34:13 +13:00
rob bygrave c18d1fa288 [maven-release-plugin] prepare release ebean-externalmapping-xml-12.5.1 2020-10-19 09:34:01 +13:00
rob bygrave 5287d93a58 [maven-release-plugin] prepare for next development iteration 2020-10-19 09:30:52 +13:00
rob bygrave 6e6055fb84 [maven-release-plugin] prepare release ebean-autotune-12.5.1 2020-10-19 09:30:40 +13:00
rob bygrave c2ea8b3d56 Prepare manual release of autotune, externalmapping-xml, querybean and test modules 2020-10-19 09:29:54 +13:00
rob bygrave 5885d724c4 Prepare manual release of autotune, externalmapping-xml, querybean and test modules 2020-10-19 09:27:58 +13:00
rob bygrave 90d028640d No effective change - bump maven tiles plugin to 2.18 2020-10-16 18:11:01 +13:00
rob bygrave b8d92f1846 [maven-release-plugin] prepare for next development iteration 2020-10-16 16:08:33 +13:00
rob bygrave e41d2eed7f [maven-release-plugin] prepare release ebean-parent-12.5.1 2020-10-16 16:08:22 +13:00
rob bygrave 8c7a84be9c No effective change - tidy tests that create unregistered Database instances (shutdown) 2020-10-16 16:04:52 +13:00
rob bygrave 63116f25ec Bump ebean-datasource to 6.1 2020-10-16 15:39:29 +13:00
rob bygrave eac05571c8 Update tests for kotlin-querybean-generator to use junit5 2020-10-16 15:38:52 +13:00
rob bygrave a6ad043142 #2082 - Test scope for kotlin-querybean-generator ebean-querybean dependency 2020-10-16 12:23:59 +13:00
SnōwballandGitHub bcc8040afe Scalar type querybeans generics error (#2082)
* Add failing test case for generic querybeans

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

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

* Fix problem with generics in scalar type arg

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

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-10-13 11:51:36 +13:00
rob bygrave fc4ee15a2a Reset poms for externalmapping-xml querybean and ebean-test modules after manual release 2020-10-13 11:45:46 +13:00
rob bygrave 6cb21f3e73 [maven-release-plugin] prepare for next development iteration 2020-10-13 11:17:39 +13:00
rob bygrave 18663c8983 [maven-release-plugin] prepare release ebean-externalmapping-xml-12.5.0 2020-10-13 11:17:27 +13:00
rob bygrave 0d9094984a Manually release ebean-externalmapping-xml module 12.5.0 by itself 2020-10-13 11:16:52 +13:00
rob bygrave bd05f2c2ba [maven-release-plugin] prepare for next development iteration 2020-10-13 11:09:06 +13:00
rob bygrave 1cc167341b [maven-release-plugin] prepare release ebean-test-12.5.0 2020-10-13 11:08:54 +13:00
rob bygrave 4a313245b5 Manually release ebean-test module 12.5.0 by itself 2020-10-13 11:08:21 +13:00
rob bygrave 8744435eb6 [maven-release-plugin] prepare for next development iteration 2020-10-13 11:04:13 +13:00
rob bygrave dfdcdcf321 [maven-release-plugin] prepare release ebean-querybean-12.5.0 2020-10-13 11:04:02 +13:00
rob bygrave e203d4d191 Try to release ebean-querybean module 12.5.0 by itself 2020-10-13 11:03:18 +13:00
rob bygrave d4c345b989 Try to release ebean-querybean module 12.5.0 by itself
For some unknown reason this module is missing from central after the release.
2020-10-13 11:01:16 +13:00
Tobias 85b21a02e8 Failing testcase for ebean query serializer 2020-10-12 13:23:49 +02:00
rob bygrave 541271efb7 Bump tiles etc to newly released 12.5.0 2020-10-12 23:42:08 +13:00
Tobias 4313fb6f58 Add .editorconfig 2020-10-12 11:51:44 +02:00
rob bygrave 489781f89d [maven-release-plugin] prepare for next development iteration 2020-10-12 22:35:21 +13:00
rob bygrave ee19fd17fa [maven-release-plugin] prepare for next development iteration 2020-09-18 01:22:40 +12:00
rob bygrave a7c6f9835a [maven-release-plugin] prepare release ebean-postgis-12.4.1 2020-09-18 01:22:29 +12:00
rob bygrave 06b1babed9 Bump to 12.4.1 2020-09-18 01:21:50 +12:00
rob bygrave 73ea91d4c9 [maven-release-plugin] prepare for next development iteration 2020-03-13 11:23:01 +13:00
rob bygrave 14839f0c0f [maven-release-plugin] prepare release ebean-postgis-12.2.1 2020-03-13 11:22:51 +13:00
rob bygrave db8f4e141d Bump to 12.2.1 2020-03-13 11:22:22 +13:00
rob bygrave 09fa406f84 [maven-release-plugin] prepare for next development iteration 2019-10-14 15:18:46 +13:00
rob bygrave 50d22ba357 [maven-release-plugin] prepare release ebean-postgis-12.1.1 2019-10-14 15:18:37 +13:00
rob bygrave c6f9d193be Bump to sync to Ebean 12.1.1 2019-10-14 15:18:01 +13:00
rob bygrave 5e1aa47c05 No effective change - update application-test.yml with dbSchema and ddlMode 2018-08-02 12:10:48 +12:00
rob bygrave 21dd8cee37 [maven-release-plugin] prepare for next development iteration 2018-08-02 11:51:10 +12:00
rob bygrave ece82996c2 [maven-release-plugin] prepare release ebean-postgis-11.1.1 2018-08-02 11:50:57 +12:00
rob bygrave fa520c95ea Bump to 11.1.1-SNAPSHOT 2018-08-02 11:50:25 +12:00
rob bygrave a6685141a4 #2 - No effective change - for running tests update to use docker postgis and application-test.yml 2018-08-02 11:48:49 +12:00
rob bygrave 78ab0ad923 No effective change - test logging config update 2018-08-02 11:44:25 +12:00
rob bygrave 4fb67a4c8c #1 - Support Ebean 11.x API - due to Ebean #1153 - Refactor move ExtraTypeFactory out of io.ebean.plugin into io.ebeaninternal 2018-08-02 11:43:52 +12:00
Rob Bygrave dd94e60d16 [maven-release-plugin] prepare for next development iteration 2016-12-13 21:59:31 +13:00
Rob Bygrave aa70e17657 [maven-release-plugin] prepare release ebean-postgis-0.1.3 2016-12-13 21:59:22 +13:00
Rob Bygrave 016cd3fb71 Update for Ebean 10.1.1 2016-12-13 21:58:56 +13:00
Rob Bygrave 17f28ba0aa [maven-release-plugin] prepare for next development iteration 2016-12-01 01:11:15 +13:00
Rob Bygrave ab88a879e9 [maven-release-plugin] prepare release ebean-postgis-0.1.2 2016-12-01 01:11:05 +13:00
Rob Bygrave 5b85f3c8dd Bump to java8 parent, update scm to ssh 2016-12-01 01:10:28 +13:00
Rob Bygrave 16a5100f35 Modify ScalarTypePgisBase to support the older protocol / objects when reading 2016-12-01 01:07:55 +13:00
Rob Bygrave 86b2c5d5b5 [maven-release-plugin] prepare for next development iteration 2016-10-25 22:53:16 +13:00
Rob Bygrave e0c3198ee6 [maven-release-plugin] prepare release ebean-postgis-0.1.1 2016-10-25 22:53:08 +13:00
Rob Bygrave 12bdd847b5 Update pom for initial release 2016-10-25 22:42:17 +13:00
Rob Bygrave 9860816ab7 Update 2016-10-25 22:36:38 +13:00
Rob Bygrave e17283726a Initial add 2016-10-21 02:37:13 +13:00
Rob Bygrave eff61ae5fc Initial commit 2016-10-21 01:32:47 +13:00
163 changed files with 3156 additions and 981 deletions
+9 -6
View File
@@ -1,17 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.5.0</version>
<version>12.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<name>ebean api</name>
<description>ebean api</description>
<artifactId>ebean-api</artifactId>
<properties>
<jackson-core.version>2.10.0</jackson-core.version>
<jackson-databind.version>2.10.0</jackson-databind.version>
<jackson-core.version>2.11.3</jackson-core.version>
<jackson-databind.version>2.11.3</jackson-databind.version>
</properties>
<dependencies>
@@ -30,7 +32,7 @@
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-config</artifactId>
<version>1.0</version>
<version>1.1</version>
</dependency>
<!--
@@ -65,7 +67,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-datasource</artifactId>
<version>5.1</version>
<version>6.1</version>
</dependency>
<dependency>
@@ -79,6 +81,7 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-core.version}</version>
<optional>true</optional>
</dependency>
<!-- provided scope for JsonNode support -->
+7
View File
@@ -70,6 +70,13 @@ public final class DB {
private DB() {
}
/**
* Backdoor for registering a mock implementation of Database as the default database.
*/
protected static Database mock(String name, Database server, boolean defaultServer) {
return context.mock(name, server, defaultServer);
}
/**
* Return the default database.
*/
@@ -14,6 +14,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import javax.sql.DataSource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -121,6 +122,16 @@ public interface Database {
*/
AutoTune getAutoTune();
/**
* Return the associated DataSource for this Database instance.
*/
DataSource getDataSource();
/**
* Return the associated read only DataSource for this Database instance (can be null).
*/
DataSource getReadOnlyDataSource();
/**
* Return the name. This is used with {@link DB#byName(String)} to get a
* Database that was registered with the DB singleton.
@@ -9,6 +9,7 @@ import javax.persistence.PersistenceException;
import java.util.Iterator;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.concurrent.locks.ReentrantLock;
/**
* Creates Database instances.
@@ -30,6 +31,7 @@ import java.util.ServiceLoader;
*/
public class DatabaseFactory {
private static final ReentrantLock lock = new ReentrantLock(false);
private static SpiContainer container;
static {
@@ -42,44 +44,63 @@ public class DatabaseFactory {
* Call this prior to creating any Database instances or alternatively set the
* ContainerConfig on the DatabaseConfig when creating the first Database instance.
*/
public static synchronized void initialiseContainer(ContainerConfig containerConfig) {
getContainer(containerConfig);
public static void initialiseContainer(ContainerConfig containerConfig) {
lock.lock();
try {
getContainer(containerConfig);
} finally {
lock.unlock();
}
}
/**
* Create using properties to configure the database.
*/
public static synchronized Database create(String name) {
// construct based on loading properties files
return getContainer(null).createServer(name);
public static Database create(String name) {
lock.lock();
try {
return getContainer(null).createServer(name);
} finally {
lock.unlock();
}
}
/**
* Create using the DatabaseConfig object to configure the database.
*/
public static synchronized Database create(DatabaseConfig config) {
if (config.getName() == null) {
throw new PersistenceException("The name is null (it is required)");
public static Database create(DatabaseConfig config) {
lock.lock();
try {
if (config.getName() == null) {
throw new PersistenceException("The name is null (it is required)");
}
Database server = createInternal(config);
if (config.isRegister()) {
DbPrimary.setSkip(true);
DbContext.getInstance().register(server, config.isDefaultServer());
}
return server;
} finally {
lock.unlock();
}
Database server = createInternal(config);
if (config.isRegister()) {
DbPrimary.setSkip(true);
DbContext.getInstance().register(server, config.isDefaultServer());
}
return server;
}
/**
* Create using the DatabaseConfig additionally specifying a classLoader to use as the context class loader.
*/
public static synchronized Database createWithContextClassLoader(DatabaseConfig config, ClassLoader classLoader) {
ClassLoader currentContextLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
public static Database createWithContextClassLoader(DatabaseConfig config, ClassLoader classLoader) {
lock.lock();
try {
return DatabaseFactory.create(config);
ClassLoader currentContextLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
try {
return DatabaseFactory.create(config);
} finally {
// set the currentContextLoader back
Thread.currentThread().setContextClassLoader(currentContextLoader);
}
} finally {
// set the currentContextLoader back
Thread.currentThread().setContextClassLoader(currentContextLoader);
lock.unlock();
}
}
@@ -89,8 +110,13 @@ public class DatabaseFactory {
* This is typically invoked via JVM shutdown hook and not explicitly called.
* </p>
*/
public static synchronized void shutdown() {
container.shutdown();
public static void shutdown() {
lock.lock();
try {
container.shutdown();
} finally {
lock.unlock();
}
}
private static Database createInternal(DatabaseConfig config) {
@@ -103,8 +129,7 @@ public class DatabaseFactory {
* @param containerConfig the configuration controlling clustering communication
*/
private static SpiContainer getContainer(ContainerConfig containerConfig) {
// thread safe in that all calling methods are synchronized
// thread safe in that all calling methods hold lock
if (container != null) {
return container;
}
@@ -123,7 +148,6 @@ public class DatabaseFactory {
* Create the container instance using the configuration.
*/
protected static SpiContainer createContainer(ContainerConfig containerConfig) {
Iterator<SpiContainerFactory> factories = ServiceLoader.load(SpiContainerFactory.class).iterator();
if (factories.hasNext()) {
return factories.next().create(containerConfig);
+12 -13
View File
@@ -8,6 +8,7 @@ import org.slf4j.LoggerFactory;
import javax.persistence.PersistenceException;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
/**
* Holds Database instances.
@@ -22,17 +23,11 @@ final class DbContext {
private static final DbContext INSTANCE = new DbContext();
/**
* Cache for fast concurrent read access.
*/
private final ConcurrentHashMap<String, Database> concMap = new ConcurrentHashMap<>();
/**
* Cache for synchronized read, creation and put. Protected by the monitor object.
*/
private final HashMap<String, Database> syncMap = new HashMap<>();
private final Object monitor = new Object();
private final ReentrantLock lock = new ReentrantLock(false);
/**
* The 'default' Database.
@@ -91,27 +86,28 @@ final class DbContext {
if (name == null || name.isEmpty()) {
return defaultDatabase;
}
// non-synchronized read
Database server = concMap.get(name);
if (server != null) {
return server;
}
// synchronized read, create and put
return getWithCreate(name);
}
/**
* Synchronized read, create and put of Databases.
* Read, create and put of Databases.
*/
private Database getWithCreate(String name) {
synchronized (monitor) {
lock.lock();
try {
Database server = syncMap.get(name);
if (server == null) {
// register when creating server this way
server = EbeanServerFactory.create(name);
server = DatabaseFactory.create(name);
register(server, false);
}
return server;
} finally {
lock.unlock();
}
}
@@ -123,12 +119,15 @@ final class DbContext {
}
private void registerWithName(String name, Database server, boolean isDefault) {
synchronized (monitor) {
lock.lock();
try {
concMap.put(name, server);
syncMap.put(name, server);
if (isDefault) {
defaultDatabase = server;
}
} finally {
lock.unlock();
}
}
+33 -13
View File
@@ -3,6 +3,7 @@ package io.ebean;
import io.avaje.config.Config;
import java.util.Properties;
import java.util.concurrent.locks.ReentrantLock;
/**
* Provides singleton state for the default database.
@@ -11,47 +12,66 @@ import java.util.Properties;
*/
class DbPrimary {
private static final ReentrantLock lock = new ReentrantLock(false);
private static String defaultServerName;
private static boolean skip;
/**
* Set whether to skip automatically creating the primary database.
*/
static synchronized void setSkip(boolean skip) {
DbPrimary.skip = skip;
static void setSkip(boolean skip) {
lock.lock();
try {
DbPrimary.skip = skip;
} finally {
lock.unlock();
}
}
/**
* Return true to skip automatically creating the primary database.
*/
static synchronized boolean isSkip() {
return skip;
static boolean isSkip() {
lock.lock();
try {
return skip;
} finally {
lock.unlock();
}
}
/**
* Return the default database name.
*/
static synchronized String getDefaultServerName() {
getProperties();
return defaultServerName;
static String getDefaultServerName() {
lock.lock();
try {
getProperties();
return defaultServerName;
} finally {
lock.unlock();
}
}
/**
* Return the default configuration Properties.
*/
static synchronized Properties getProperties() {
if (defaultServerName == null) {
defaultServerName = determineDefaultServerName();
static Properties getProperties() {
lock.lock();
try {
if (defaultServerName == null) {
defaultServerName = determineDefaultServerName();
}
return Config.asProperties();
} finally {
lock.unlock();
}
return Config.asProperties();
}
/**
* Determine and return the default server name checking system environment variables and then global properties.
*/
private static String determineDefaultServerName() {
String defaultServerName = System.getenv("EBEAN_DB");
defaultServerName = System.getProperty("db", defaultServerName);
defaultServerName = System.getProperty("ebean_db", defaultServerName);
@@ -39,28 +39,28 @@ public class EbeanServerFactory {
* Call this prior to creating any EbeanServer instances or alternatively set the
* ContainerConfig on the ServerConfig when creating the first EbeanServer instance.
*/
public static synchronized void initialiseContainer(ContainerConfig containerConfig) {
public static void initialiseContainer(ContainerConfig containerConfig) {
DatabaseFactory.initialiseContainer(containerConfig);
}
/**
* Create using ebean.properties to configure the database.
*/
public static synchronized EbeanServer create(String name) {
public static EbeanServer create(String name) {
return (EbeanServer)DatabaseFactory.create(name);
}
/**
* Create using the ServerConfig object to configure the database.
*/
public static synchronized EbeanServer create(ServerConfig config) {
public static EbeanServer create(ServerConfig config) {
return (EbeanServer)DatabaseFactory.create(config);
}
/**
* Create using the ServerConfig additionally specifying a classLoader to use as the context class loader.
*/
public static synchronized EbeanServer createWithContextClassLoader(ServerConfig config, ClassLoader classLoader) {
public static EbeanServer createWithContextClassLoader(ServerConfig config, ClassLoader classLoader) {
return (EbeanServer)DatabaseFactory.createWithContextClassLoader(config, classLoader);
}
@@ -70,7 +70,7 @@ public class EbeanServerFactory {
* This is typically invoked via JVM shutdown hook and not explicitly called.
* </p>
*/
public static synchronized void shutdown() {
public static void shutdown() {
DatabaseFactory.shutdown();
}
@@ -1,5 +1,7 @@
package io.ebean.bean;
import java.util.concurrent.locks.Lock;
/**
* Loads a entity bean.
* <p>
@@ -18,4 +20,9 @@ public interface BeanLoader {
*/
void loadBean(EntityBeanIntercept ebi);
/**
* Obtain a lock on the loader.
*/
Lock lock();
}
@@ -14,6 +14,8 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* This is the object added to every entity bean using byte code enhancement.
@@ -30,6 +32,8 @@ public final class EntityBeanIntercept implements Serializable {
private static final int STATE_REFERENCE = 1;
private static final int STATE_LOADED = 2;
private transient final ReentrantLock lock = new ReentrantLock(false);
private transient NodeUsageCollector nodeUsageCollector;
private transient PersistenceContext persistenceContext;
@@ -803,7 +807,8 @@ public final class EntityBeanIntercept implements Serializable {
* Load the bean when it is a reference.
*/
protected void loadBean(int loadProperty) {
synchronized (this) {
lock.lock();
try {
if (beanLoader == null) {
final Database database = DB.byName(ebeanServerName);
if (database == null) {
@@ -811,14 +816,19 @@ public final class EntityBeanIntercept implements Serializable {
}
// For stand alone reference bean or after deserialisation lazy load
// using the ebeanServer. Synchronise only on the bean.
loadBeanInternal(loadProperty, database.getPluginApi());
loadBeanInternal(loadProperty, database.getPluginApi().beanLoader());
return;
}
} finally {
lock.unlock();
}
synchronized (beanLoader) {
final Lock lock = beanLoader.lock();
try {
// Lazy loading using LoadBeanContext which supports batch loading
// Synchronise on the beanLoader (a 'node' of the LoadBeanContext 'tree')
loadBeanInternal(loadProperty, beanLoader);
} finally {
lock.unlock();
}
}
@@ -2,11 +2,16 @@ package io.ebean.bean;
import io.ebean.Database;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* BeanLoader used when single beans are loaded (which is usually not ideal / N+1).
*/
public abstract class SingleBeanLoader implements BeanLoader {
private final ReentrantLock lock = new ReentrantLock(false);
protected final Database database;
SingleBeanLoader(Database database) {
@@ -18,6 +23,12 @@ public abstract class SingleBeanLoader implements BeanLoader {
return database.getName();
}
@Override
public Lock lock() {
lock.lock();
return lock;
}
/**
* Single bean lazy loaded when bean from L2 cache.
*/
@@ -45,4 +56,18 @@ public abstract class SingleBeanLoader implements BeanLoader {
database.getPluginApi().loadBeanRef(ebi);
}
}
/**
* Single bean lazy loaded when a reference bean.
*/
public static class Dflt extends SingleBeanLoader {
public Dflt(Database database) {
super(database);
}
@Override
public void loadBean(EntityBeanIntercept ebi) {
database.getPluginApi().loadBean(ebi);
}
}
}
@@ -7,6 +7,7 @@ import io.ebean.bean.BeanCollectionLoader;
import io.ebean.bean.EntityBean;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
/**
* Base class for List Set and Map implementations of BeanCollection.
@@ -15,6 +16,8 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
private static final long serialVersionUID = 3365725236140187588L;
protected final ReentrantLock lock = new ReentrantLock(false);
protected boolean readOnly;
protected boolean disableLazyLoad;
@@ -115,7 +115,8 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
}
private void initClear() {
synchronized (this) {
lock.lock();
try {
if (list == null) {
if (!disableLazyLoad && modifyListening) {
lazyLoadCollection(true);
@@ -123,11 +124,14 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
list = new ArrayList<>();
}
}
} finally {
lock.unlock();
}
}
private void init() {
synchronized (this) {
lock.lock();
try {
if (list == null) {
if (disableLazyLoad) {
list = new ArrayList<>();
@@ -135,6 +139,8 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
lazyLoadCollection(false);
}
}
} finally {
lock.unlock();
}
}
@@ -121,7 +121,8 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
}
private void initClear() {
synchronized (this) {
lock.lock();
try {
if (map == null) {
if (!disableLazyLoad && modifyListening) {
lazyLoadCollection(true);
@@ -129,11 +130,14 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
map = new LinkedHashMap<>();
}
}
} finally {
lock.unlock();
}
}
private void init() {
synchronized (this) {
lock.lock();
try {
if (map == null) {
if (disableLazyLoad) {
map = new LinkedHashMap<>();
@@ -141,6 +145,8 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
lazyLoadCollection(false);
}
}
} finally {
lock.unlock();
}
}
@@ -114,7 +114,8 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
}
private void initClear() {
synchronized (this) {
lock.lock();
try {
if (set == null) {
if (!disableLazyLoad && modifyListening) {
lazyLoadCollection(true);
@@ -122,11 +123,14 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
set = new LinkedHashSet<>();
}
}
} finally {
lock.unlock();
}
}
private void init() {
synchronized (this) {
lock.lock();
try {
if (set == null) {
if (disableLazyLoad) {
set = new LinkedHashSet<>();
@@ -134,6 +138,8 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
lazyLoadCollection(true);
}
}
} finally {
lock.unlock();
}
}
@@ -6,25 +6,27 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
/**
* List that copies itself on first write access. Needed to keep memory footprint low and the ability
* to modify lists from cache.
*
*
* @author Roland Praml, FOCONIS AG
*/
public final class CopyOnFirstWriteList<E> extends AbstractList<E> implements List<E>, Serializable {
private static final long serialVersionUID = 1L;
private final ReentrantLock lock = new ReentrantLock(false);
/**
* The underlying List implementation.
*/
private List<E> list;
public CopyOnFirstWriteList(List<E> list) {
super();
this.list = list;
@@ -166,14 +168,17 @@ public final class CopyOnFirstWriteList<E> extends AbstractList<E> implements Li
public int lastIndexOf(Object o) {
return list.lastIndexOf(o);
}
private void checkCopyOnWrite() {
if (!copied) {
synchronized (this) {
lock.lock();
try {
if (!copied) {
list = new ArrayList<>(list);
copied = true;
}
} finally {
lock.unlock();
}
}
}
@@ -26,20 +26,6 @@ public class ClassLoadConfig {
this.context = new ClassLoaderContext(classLoader);
}
/**
* Return true if the Java.time types are available and should be supported.
*/
public boolean isJavaTimePresent() {
return isPresent("java.time.LocalDate");
}
/**
* Return true if Java7 is present.
*/
public boolean isJava7Present() {
return isPresent("java.nio.file.Path");
}
/**
* Return true if the Joda types are available and should be supported.
*/
@@ -69,6 +55,10 @@ public class ClassLoadConfig {
return isPresent("com.fasterxml.jackson.annotation.JsonIgnore");
}
public boolean isJacksonCorePresent() {
return isPresent("com.fasterxml.jackson.core.JsonParser");
}
/**
* Return true if Jackson ObjectMapper is present.
*/
@@ -16,6 +16,7 @@ import java.util.Collections;
import java.util.List;
import java.util.NavigableSet;
import java.util.TreeSet;
import java.util.concurrent.locks.ReentrantLock;
/**
* Database sequence based IdGenerator.
@@ -24,15 +25,9 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
protected static final Logger logger = LoggerFactory.getLogger("io.ebean.SEQ");
/**
* Used to synchronise the idList access.
*/
protected final Object monitor = new Object();
private final ReentrantLock lock = new ReentrantLock(false);
/**
* Used to synchronise background loading (loadBatchInBackground).
*/
protected final Object backgroundLoadMonitor = new Object();
private final ReentrantLock loadLock = new ReentrantLock(false);
/**
* The actual sequence name.
@@ -97,7 +92,8 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
*/
@Override
public Object nextId(Transaction t) {
synchronized (monitor) {
lock.lock();
try {
int size = idList.size();
if (size > 0) {
maybeLoadMoreInBackground(size);
@@ -105,6 +101,8 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
loadMore(allocationSize);
}
return idList.pollFirst();
} finally {
lock.unlock();
}
}
@@ -118,8 +116,11 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
private void loadMore(int requestSize) {
List<Long> newIds = getMoreIds(requestSize);
synchronized (monitor) {
lock.lock();
try {
idList.addAll(newIds);
} finally {
lock.unlock();
}
}
@@ -127,23 +128,26 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
* Load another batch of Id's using a background thread.
*/
protected void loadInBackground(final int requestSize) {
// single threaded processing...
synchronized (backgroundLoadMonitor) {
loadLock.lock();
try {
if (currentlyBackgroundLoading) {
// skip as already background loading
logger.debug("... skip background sequence load (another load in progress)");
return;
}
currentlyBackgroundLoading = true;
backgroundExecutor.execute(() -> {
loadMore(requestSize);
synchronized (backgroundLoadMonitor) {
loadLock.lock();
try {
currentlyBackgroundLoading = false;
} finally {
loadLock.unlock();
}
});
} finally {
loadLock.lock();
}
}
@@ -11,6 +11,7 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
/**
* Manages the shutdown of the JVM Runtime.
@@ -22,6 +23,8 @@ public final class ShutdownManager {
private static final Logger logger = LoggerFactory.getLogger(ShutdownManager.class);
private static final ReentrantLock lock = new ReentrantLock(false);
private static final List<Database> databases = new ArrayList<>();
private static final ShutdownHook shutdownHook = new ShutdownHook();
@@ -56,9 +59,11 @@ public final class ShutdownManager {
* Return true if the system is in the process of stopping.
*/
public static boolean isStopping() {
//noinspection SynchronizationOnStaticField
synchronized (databases) {
lock.lock();
try {
return stopping;
} finally {
lock.unlock();
}
}
@@ -74,15 +79,15 @@ public final class ShutdownManager {
* </p>
*/
public static void deregisterShutdownHook() {
//noinspection SynchronizationOnStaticField
synchronized (databases) {
try {
Runtime.getRuntime().removeShutdownHook(shutdownHook);
} catch (IllegalStateException ex) {
if (!ex.getMessage().equals("Shutdown in progress")) {
throw ex;
}
lock.lock();
try {
Runtime.getRuntime().removeShutdownHook(shutdownHook);
} catch (IllegalStateException ex) {
if (!ex.getMessage().equals("Shutdown in progress")) {
throw ex;
}
} finally {
lock.unlock();
}
}
@@ -90,18 +95,18 @@ public final class ShutdownManager {
* Register the shutdown hook with the Runtime.
*/
protected static void registerShutdownHook() {
//noinspection SynchronizationOnStaticField
synchronized (databases) {
try {
String value = System.getProperty("ebean.registerShutdownHook");
if (value == null || !value.trim().equalsIgnoreCase("false")) {
Runtime.getRuntime().addShutdownHook(shutdownHook);
}
} catch (IllegalStateException ex) {
if (!ex.getMessage().equals("Shutdown in progress")) {
throw ex;
}
lock.lock();
try {
String value = System.getProperty("ebean.registerShutdownHook");
if (value == null || !value.trim().equalsIgnoreCase("false")) {
Runtime.getRuntime().addShutdownHook(shutdownHook);
}
} catch (IllegalStateException ex) {
if (!ex.getMessage().equals("Shutdown in progress")) {
throw ex;
}
} finally {
lock.unlock();
}
}
@@ -112,8 +117,8 @@ public final class ShutdownManager {
* </p>
*/
public static void shutdown() {
//noinspection SynchronizationOnStaticField
synchronized (databases) {
lock.lock();
try {
if (stopping) {
// Already run shutdown...
return;
@@ -157,6 +162,8 @@ public final class ShutdownManager {
if ("true".equalsIgnoreCase(System.getProperty("ebean.datasource.deregisterAllDrivers", "false"))) {
deregisterAllJdbcDrivers();
}
} finally {
lock.unlock();
}
}
@@ -178,9 +185,11 @@ public final class ShutdownManager {
* Register an ebeanServer to be shutdown when the JVM is shutdown.
*/
public static void registerDatabase(Database server) {
//noinspection SynchronizationOnStaticField
synchronized (databases) {
lock.lock();
try {
databases.add(server);
} finally {
lock.unlock();
}
}
@@ -191,9 +200,11 @@ public final class ShutdownManager {
* </p>
*/
public static void unregisterDatabase(Database server) {
//noinspection SynchronizationOnStaticField
synchronized (databases) {
lock.lock();
try {
databases.remove(server);
} finally {
lock.unlock();
}
}
@@ -1,6 +1,6 @@
package io.ebean.plugin;
import io.ebean.EbeanServer;
import io.ebean.Database;
import io.ebean.bean.BeanLoader;
import io.ebean.bean.EntityBeanIntercept;
import io.ebean.config.DatabaseConfig;
@@ -12,7 +12,7 @@ import java.util.List;
/**
* Extensions to Database API made available to plugins.
*/
public interface SpiServer extends EbeanServer, BeanLoader {
public interface SpiServer extends Database {
/**
* Return the DatabaseConfig.
@@ -45,14 +45,9 @@ public interface SpiServer extends EbeanServer, BeanLoader {
BeanType<?> getBeanTypeForQueueId(String queueId);
/**
* Return the associated DataSource for this Database instance.
* Return a BeanLoader.
*/
DataSource getDataSource();
/**
* Return the associated read only DataSource for this Database instance (can be null).
*/
DataSource getReadOnlyDataSource();
BeanLoader beanLoader();
/**
* Invoke lazy loading on this single bean (reference bean).
+18 -5
View File
@@ -1,12 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.5.0</version>
<version>12.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<!-- <parent>-->
<!-- <groupId>org.avaje</groupId>-->
<!-- <artifactId>java8-oss</artifactId>-->
<!-- <version>2.2</version>-->
<!-- </parent>-->
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-parent-12.5.2</tag>
</scm>
<name>ebean autotune</name>
<description>ebean automatic query tuning module</description>
<artifactId>ebean-autotune</artifactId>
<dependencies>
@@ -14,7 +26,8 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
<scope>provided</scope>
</dependency>
<!-- needed for java 11+ -->
@@ -39,12 +52,12 @@
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.17</version>
<version>2.18</version>
<extensions>true</extensions>
<configuration>
<tiles>
<!-- other tiles ... -->
<tile>io.ebean.tile:enhancement:12.4.2</tile>
<tile>io.ebean.tile:enhancement:12.5.0</tile>
</tiles>
</configuration>
</plugin>
@@ -14,6 +14,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* Implementation of the AutoTuneService which is comprised of profiling and query tuning.
@@ -22,6 +23,8 @@ public class DefaultAutoTuneService implements AutoTuneService {
private static final Logger logger = LoggerFactory.getLogger(DefaultAutoTuneService.class);
private final ReentrantLock lock = new ReentrantLock(false);
private final SpiEbeanServer server;
private final long defaultGarbageCollectionWait;
@@ -127,8 +130,8 @@ public class DefaultAutoTuneService implements AutoTuneService {
* Collect profiling, check for new/diff to existing tuning and apply changes.
*/
private void runtimeTuningUpdate() {
synchronized (this) {
lock.lock();
try {
try {
long start = System.currentTimeMillis();
@@ -150,12 +153,14 @@ public class DefaultAutoTuneService implements AutoTuneService {
} catch (Throwable e) {
logger.error("Error collecting or applying automatic query tuning", e);
}
} finally {
lock.unlock();
}
}
private void saveProfilingOnShutdown(boolean reset) {
synchronized (this) {
lock.lock();
try {
if (isRuntimeTuningUpdates()) {
runtimeTuningUpdate();
outputAllTuning();
@@ -174,6 +179,8 @@ public class DefaultAutoTuneService implements AutoTuneService {
logger.info("writing new:{} diff:{} profiling entries for server:{}", event.getNewCount(), event.getDiffCount(), serverName);
}
}
} finally {
lock.unlock();
}
}
@@ -11,12 +11,15 @@ import io.ebeaninternal.server.deploy.BeanDescriptor;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
/**
* Manages the collection of object graph usage profiling.
*/
public class ProfileManager implements ProfilingListener {
private final ReentrantLock lock = new ReentrantLock(false);
private final boolean queryTuningAddVersion;
/**
@@ -32,8 +35,6 @@ public class ProfileManager implements ProfilingListener {
*/
private final Map<String, ProfileOrigin> profileMap = new ConcurrentHashMap<>();
private final Object monitor = new Object();
private final SpiEbeanServer server;
public ProfileManager(AutoTuneConfig config, SpiEbeanServer server) {
@@ -101,8 +102,11 @@ public class ProfileManager implements ProfilingListener {
}
private ProfileOrigin getProfileOrigin(ObjectGraphOrigin originQueryPoint) {
synchronized (monitor) {
lock.lock();
try {
return profileMap.computeIfAbsent(originQueryPoint.getKey(), k -> new ProfileOrigin(originQueryPoint, queryTuningAddVersion, profilingBase, profilingRate));
} finally {
lock.unlock();
}
}
@@ -12,9 +12,12 @@ import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
public class ProfileOrigin {
private final ReentrantLock lock = new ReentrantLock(false);
private static final long RESET_COUNT = -1000000000L;
private final ObjectGraphOrigin origin;
@@ -29,8 +32,6 @@ public class ProfileOrigin {
private final Map<String, ProfileOriginNodeUsage> nodeUsageMap = new ConcurrentHashMap<>();
private final Object monitor = new Object();
private final AtomicLong requestCount = new AtomicLong();
private final AtomicLong profileCount = new AtomicLong();
@@ -74,8 +75,8 @@ public class ProfileOrigin {
* Collect profiling information with the option to reset the underlying profiling detail.
*/
public void profilingCollection(BeanDescriptor<?> rootDesc, AutoTuneCollection req, boolean reset) {
synchronized (monitor) {
lock.lock();
try {
if (nodeUsageMap.isEmpty()) {
return;
}
@@ -94,6 +95,8 @@ public class ProfileOrigin {
profileCount.set(0);
}
}
} finally {
lock.unlock();
}
}
@@ -155,8 +158,8 @@ public class ProfileOrigin {
}
private ProfileOriginNodeUsage getNodeStats(String path) {
synchronized (monitor) {
lock.lock();
try {
// handle null paths as using ConcurrentHashMap
path = (path == null) ? "" : path;
ProfileOriginNodeUsage nodeStats = nodeUsageMap.get(path);
@@ -165,6 +168,8 @@ public class ProfileOrigin {
nodeUsageMap.put(path, nodeStats);
}
return nodeStats;
} finally {
lock.unlock();
}
}
@@ -12,6 +12,7 @@ import org.slf4j.LoggerFactory;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
/**
* Collects usages statistics for a given node in the object graph.
@@ -20,7 +21,7 @@ public class ProfileOriginNodeUsage {
private static final Logger logger = LoggerFactory.getLogger(ProfileOriginNodeUsage.class);
private final Object monitor = new Object();
private final ReentrantLock lock = new ReentrantLock(false);
private final String path;
@@ -38,9 +39,8 @@ public class ProfileOriginNodeUsage {
}
protected void buildTunedFetch(PathProperties pathProps, BeanDescriptor<?> rootDesc, boolean addVersionProperty) {
synchronized (monitor) {
lock.lock();
try {
BeanDescriptor<?> desc = rootDesc;
if (path != null) {
ElPropertyValue elGetValue = rootDesc.getElGetValue(path);
@@ -95,6 +95,8 @@ public class ProfileOriginNodeUsage {
ElPropertyValue assocOne = rootDesc.getElGetValue(path);
pathProps.addToPath(SplitName.parent(path), assocOne.getName());
}
} finally {
lock.unlock();
}
}
@@ -102,9 +104,8 @@ public class ProfileOriginNodeUsage {
* Collect usage from a node.
*/
protected void collectUsageInfo(NodeUsageCollector profile) {
synchronized (monitor) {
lock.lock();
try {
Set<String> used = profile.getUsed();
profileCount++;
@@ -115,6 +116,8 @@ public class ProfileOriginNodeUsage {
if (profile.isModified()) {
modified = true;
}
} finally {
lock.unlock();
}
}
+15 -13
View File
@@ -1,12 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.5.0</version>
<version>12.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<name>ebean bom</name>
<description>ebean bill of materials pom</description>
<artifactId>ebean-bom</artifactId>
<packaging>pom</packaging>
@@ -38,69 +40,69 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddlgen</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-xml</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-autotune</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>kotlin-querybean-generator</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
<scope>test</scope>
</dependency>
+12 -17
View File
@@ -3,23 +3,24 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.5.0</version>
<version>12.5.2</version>
</parent>
<artifactId>ebean-core</artifactId>
<packaging>jar</packaging>
<name>ebean-core</name>
<url>http://ebean-orm.github.io/</url>
<name>ebean core</name>
<description>ebean core module</description>
<url>https://ebean.io/</url>
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-parent-12.5.0</tag>
<tag>ebean-parent-12.5.2</tag>
</scm>
<properties>
<jackson-core.version>2.10.0</jackson-core.version>
<jackson-databind.version>2.10.0</jackson-databind.version>
<jackson-core.version>2.11.3</jackson-core.version>
<jackson-databind.version>2.11.3</jackson-databind.version>
</properties>
<profiles>
@@ -51,7 +52,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddlgen</artifactId>
<version>12.4.1</version>
<version>12.5.0</version>
<scope>test</scope>
</dependency>
<!-- test scope for supporting ebean-ddlgen -->
@@ -65,13 +66,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
</dependency>
<dependency>
@@ -91,12 +92,6 @@
<scope>provided</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>io.ebean</groupId>-->
<!-- <artifactId>ebean-migration</artifactId>-->
<!-- <version>12.1.4</version>-->
<!-- </dependency>-->
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
@@ -131,9 +126,9 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-core.version}</version>
<optional>true</optional>
</dependency>
<!-- provided scope for JsonNode support -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
@@ -267,7 +262,7 @@
<plugin>
<groupId>io.ebean</groupId>
<artifactId>ebean-maven-plugin</artifactId>
<version>12.4.2</version>
<version>12.5.0</version>
<executions>
<execution>
<id>test</id>
@@ -0,0 +1,15 @@
package io.ebeaninternal.api;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.server.type.GeoTypeBinder;
/**
* Provider of Geometry type binder support.
*/
public interface GeoTypeProvider {
/**
* Create a binder for binding geometry types.
*/
GeoTypeBinder createBinder(DatabaseConfig config);
}
@@ -18,6 +18,7 @@ import org.slf4j.LoggerFactory;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.locks.ReentrantLock;
/**
* Manages the construction of caches.
@@ -26,17 +27,14 @@ class DefaultCacheHolder {
private static final Logger log = LoggerFactory.getLogger("io.ebean.cache.ALL");
private final ReentrantLock lock = new ReentrantLock(false);
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;
private final CurrentTenantProvider tenantProvider;
private final QueryCacheEntryValidate queryCacheEntryValidate;
DefaultCacheHolder(CacheManagerOptions builder) {
@@ -87,8 +85,11 @@ class DefaultCacheHolder {
private ServerCache createCache(Class<?> beanType, ServerCacheType type, String key, String shortName) {
ServerCacheOptions options = getCacheOptions(beanType, type);
if (type == ServerCacheType.COLLECTION_IDS) {
synchronized (this) {
lock.lock();
try {
collectIdCaches.computeIfAbsent(beanType.getName(), s -> new ConcurrentSkipListSet<>()).add(key);
} finally {
lock.unlock();
}
}
return cacheFactory.createCache(new ServerCacheConfig(type, key, shortName, options, tenantProvider, queryCacheEntryValidate));
@@ -9,6 +9,7 @@ import org.slf4j.LoggerFactory;
import java.util.Iterator;
import java.util.ServiceLoader;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
/**
* Manages the cluster service.
@@ -17,6 +18,8 @@ public class ClusterManager implements ServerLookup {
private static final Logger clusterLogger = LoggerFactory.getLogger("io.ebean.Cluster");
private final ReentrantLock lock = new ReentrantLock(false);
private final ConcurrentHashMap<String, EbeanServer> serverMap = new ConcurrentHashMap<>();
private final Object monitor = new Object();
@@ -51,18 +54,24 @@ public class ClusterManager implements ServerLookup {
}
public void registerServer(EbeanServer server) {
synchronized (monitor) {
lock.lock();
try {
serverMap.put(server.getName(), server);
if (!started) {
startup();
}
} finally {
lock.unlock();
}
}
@Override
public EbeanServer getServer(String name) {
synchronized (monitor) {
lock.lock();
try {
return serverMap.get(name);
} finally {
lock.unlock();
}
}
@@ -102,7 +102,7 @@ class DScriptRunner implements ScriptRunner {
private Connection obtainConnection() {
try {
return server.getPluginApi().getDataSource().getConnection();
return server.getDataSource().getConnection();
} catch (SQLException e) {
throw new PersistenceException("Failed to obtain connection to run script", e);
}
@@ -26,6 +26,7 @@ import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.ServiceLoader;
import java.util.concurrent.locks.ReentrantLock;
/**
* Default Server side implementation of ServerFactory.
@@ -34,6 +35,7 @@ public class DefaultContainer implements SpiContainer {
private static final Logger logger = LoggerFactory.getLogger("io.ebean.internal.DefaultContainer");
private final ReentrantLock lock = new ReentrantLock(false);
private final ClusterManager clusterManager;
public DefaultContainer(ContainerConfig containerConfig) {
@@ -72,7 +74,8 @@ public class DefaultContainer implements SpiContainer {
*/
@Override
public SpiEbeanServer createServer(DatabaseConfig config) {
synchronized (this) {
lock.lock();
try {
applyConfigServices(config);
setNamingConvention(config);
BootupClasses bootupClasses = getBootupClasses(config);
@@ -114,6 +117,8 @@ public class DefaultContainer implements SpiContainer {
}
DbOffline.reset();
return server;
} finally {
lock.unlock();
}
}
@@ -36,11 +36,13 @@ import io.ebean.Version;
import io.ebean.annotation.Platform;
import io.ebean.annotation.TxIsolation;
import io.ebean.bean.BeanCollection;
import io.ebean.bean.BeanLoader;
import io.ebean.bean.CallOrigin;
import io.ebean.bean.EntityBean;
import io.ebean.bean.EntityBeanIntercept;
import io.ebean.bean.PersistenceContext;
import io.ebean.bean.PersistenceContext.WithOption;
import io.ebean.bean.SingleBeanLoader;
import io.ebean.cache.ServerCacheManager;
import io.ebean.common.CopyOnFirstWriteList;
import io.ebean.config.CurrentTenantProvider;
@@ -142,6 +144,7 @@ import java.util.Optional;
import java.util.Set;
import java.util.Spliterator;
import java.util.concurrent.Callable;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -157,98 +160,47 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
private static final Logger logger = LoggerFactory.getLogger(DefaultServer.class);
private final ReentrantLock lock = new ReentrantLock(false);
private final DatabaseConfig config;
private final String serverName;
private final DatabasePlatform databasePlatform;
private final TransactionManager transactionManager;
private final QueryPlanManager queryPlanManager;
private final ExtraMetrics extraMetrics;
private final DataTimeZone dataTimeZone;
/**
* Clock to use for WhenModified and WhenCreated.
*/
private final ClockService clockService;
private final CallOriginFactory callStackFactory;
/**
* Handles the save, delete, updateSql CallableSql.
*/
private final Persister persister;
private final OrmQueryEngine queryEngine;
private final RelationalQueryEngine relationalQueryEngine;
private final DtoQueryEngine dtoQueryEngine;
private final ServerCacheManager serverCacheManager;
private final DtoBeanManager dtoBeanManager;
private final BeanDescriptorManager beanDescriptorManager;
private final AutoTuneService autoTuneService;
private final ReadAuditPrepare readAuditPrepare;
private final ReadAuditLogger readAuditLogger;
private final CQueryEngine cqueryEngine;
private final List<Plugin> serverPlugins;
private final SpiDdlGenerator ddlGenerator;
private final ScriptRunner scriptRunner;
private final ExpressionFactory expressionFactory;
private final SpiBackgroundExecutor backgroundExecutor;
private final DefaultBeanLoader beanLoader;
private final EncryptKeyManager encryptKeyManager;
private final SpiJsonContext jsonContext;
private final DocumentStore documentStore;
private final MetaInfoManager metaInfoManager;
private final CurrentTenantProvider currentTenantProvider;
private final SpiLogManager logManager;
/**
* The default PersistenceContextScope used if it is not explicitly set on a query.
*/
private final PersistenceContextScope defaultPersistenceContextScope;
/**
* Flag set when the server has shutdown.
*/
private boolean shutdown;
/**
* The default batch size for lazy loading beans or collections.
*/
private final int lazyLoadBatchSize;
private final int queryBatchSize;
private final boolean updateAllPropertiesInBatch;
private final long slowQueryMicros;
private final SlowQueryListener slowQueryListener;
private final boolean disableL2Cache;
private boolean shutdown;
/**
* Create the DefaultServer.
@@ -452,8 +404,11 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
public void shutdown() {
synchronized (this) {
lock.lock();
try {
shutdownInternal(true, false);
} finally {
lock.unlock();
}
}
@@ -462,10 +417,12 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
*/
@Override
public void shutdown(boolean shutdownDataSource, boolean deregisterDriver) {
synchronized (this) {
// Unregister from JVM Shutdown hook
lock.lock();
try {
ShutdownManager.unregisterDatabase(this);
shutdownInternal(shutdownDataSource, deregisterDriver);
} finally {
lock.unlock();
}
}
@@ -575,6 +532,11 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
beanLoader.loadBean(loadRequest);
}
@Override
public BeanLoader beanLoader() {
return new SingleBeanLoader.Dflt(this);
}
@Override
public void loadBean(EntityBeanIntercept ebi) {
beanLoader.loadBean(ebi);
@@ -1,6 +1,7 @@
package io.ebeaninternal.server.core;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantLock;
/**
* Used to reduce memory consumption of strings used in deployment processing.
@@ -12,6 +13,8 @@ public final class InternString {
private static final HashMap<String, String> map = new HashMap<>();
private static final ReentrantLock lock = new ReentrantLock(false);
/**
* Return the shared instance of this string.
*/
@@ -19,8 +22,8 @@ public final class InternString {
if (s == null) {
return null;
}
//noinspection SynchronizationOnStaticField
synchronized (map) {
lock.lock();
try {
String v = map.get(s);
if (v != null) {
return v;
@@ -28,6 +31,8 @@ public final class InternString {
map.put(s, s);
return s;
}
} finally {
lock.unlock();
}
}
}
@@ -118,69 +118,41 @@ public class InternalConfiguration {
private static final Logger logger = LoggerFactory.getLogger(InternalConfiguration.class);
private final TableModState tableModState;
private final boolean online;
private final DatabaseConfig config;
private final BootupClasses bootupClasses;
private final DatabasePlatform databasePlatform;
private final DeployInherit deployInherit;
private final TypeManager typeManager;
private final DtoBeanManager dtoBeanManager;
private final ClockService clockService;
private final DataTimeZone dataTimeZone;
private final Binder binder;
private final DeployCreateProperties deployCreateProperties;
private final DeployUtil deployUtil;
private final BeanDescriptorManager beanDescriptorManager;
private final CQueryEngine cQueryEngine;
private final ClusterManager clusterManager;
private final SpiCacheManager cacheManager;
private final ServerCachePlugin serverCachePlugin;
private ServerCacheNotify cacheNotify;
private boolean localL2Caching;
private final boolean jacksonCorePresent;
private final ExpressionFactory expressionFactory;
private final SpiBackgroundExecutor backgroundExecutor;
private final JsonFactory jsonFactory;
private final DocStoreFactory docStoreFactory;
/**
* List of plugins (that ultimately the DefaultServer configures late in construction).
*/
private final List<Plugin> plugins = new ArrayList<>();
private final MultiValueBind multiValueBind;
private final SpiLogManager logManager;
private final ExtraMetrics extraMetrics = new ExtraMetrics();
private ServerCacheNotify cacheNotify;
private boolean localL2Caching;
InternalConfiguration(boolean online, ClusterManager clusterManager, SpiBackgroundExecutor backgroundExecutor,
DatabaseConfig config, BootupClasses bootupClasses) {
this.online = online;
this.config = config;
this.jacksonCorePresent = config.getClassLoadConfig().isJacksonCorePresent();
this.clockService = new ClockService(config.getClock());
this.tableModState = new TableModState();
this.logManager = initLogManager();
@@ -210,6 +182,10 @@ public class InternalConfiguration {
this.cQueryEngine = new CQueryEngine(config, databasePlatform, binder, asOfTableMapping, draftTableMap);
}
public boolean isJacksonCorePresent() {
return jacksonCorePresent;
}
private InternalConfigXmlMap initExternalMapping() {
final List<XmapEbean> xmEbeans = readExternalMapping();
return new InternalConfigXmlMap(xmEbeans, config.getClassLoadConfig().getClassLoader());
@@ -307,7 +283,7 @@ public class InternalConfiguration {
* Return the ChangeLogListener to use with a default implementation if none defined.
*/
public ChangeLogListener changeLogListener(ChangeLogListener listener) {
return plugin((listener != null) ? listener : new DefaultChangeLogListener());
return plugin((listener != null) ? listener : jacksonCorePresent ? new DefaultChangeLogListener() : null);
}
/**
@@ -315,7 +291,7 @@ public class InternalConfiguration {
*/
ReadAuditLogger getReadAuditLogger() {
ReadAuditLogger found = bootupClasses.getReadAuditLogger();
return plugin(found != null ? found : new DefaultReadAuditLogger());
return plugin(found != null ? found : jacksonCorePresent? new DefaultReadAuditLogger(): null);
}
/**
@@ -356,7 +332,7 @@ public class InternalConfiguration {
}
SpiJsonContext createJsonContext(SpiEbeanServer server) {
return new DJsonContext(server, jsonFactory, typeManager);
return jacksonCorePresent ? new DJsonContext(server, jsonFactory, typeManager) : null;
}
AutoTuneService createAutoTuneService(SpiEbeanServer server) {
@@ -432,7 +432,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
boolean noRelationships = propertiesOne.length + propertiesMany.length == 0;
this.cacheSharableBeans = noRelationships && deploy.getCacheOptions().isReadOnly();
this.cacheHelp = new BeanDescriptorCacheHelp<>(this, owner.getCacheManager(), deploy.getCacheOptions(), cacheSharableBeans, propertiesOneImported);
this.jsonHelp = new BeanDescriptorJsonHelp<>(this);
this.jsonHelp = initJsonHelp();
this.draftHelp = new BeanDescriptorDraftHelp<>(this);
this.docStoreAdapter = owner.createDocStoreBeanAdapter(this, deploy);
this.docStoreQueueId = docStoreAdapter.getQueueId();
@@ -469,6 +469,14 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
}
}
public boolean isJacksonCorePresent() {
return owner.isJacksonCorePresent();
}
private BeanDescriptorJsonHelp<T> initJsonHelp() {
return isJacksonCorePresent() ? new BeanDescriptorJsonHelp<>(this) : null;
}
/**
* Return true if the bean should be treated as a reference bean when it only has its id populated.
* To be true it has other scalar properties that are not generated on insert.
@@ -95,87 +95,47 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
private static final BeanDescComparator beanDescComparator = new BeanDescComparator();
private final ReadAnnotations readAnnotations;
private final TransientProperties transientProperties;
/**
* Helper to derive inheritance information.
*/
private final DeployInherit deplyInherit;
private final BeanPropertyAccess beanPropertyAccess = new EnhanceBeanPropertyAccess();
private final DeployUtil deployUtil;
private final PersistControllerManager persistControllerManager;
private final PostLoadManager postLoadManager;
private final PostConstructManager postConstructManager;
private final BeanFinderManager beanFinderManager;
private final PersistListenerManager persistListenerManager;
private final BeanQueryAdapterManager beanQueryAdapterManager;
private final NamingConvention namingConvention;
private final DeployCreateProperties createProperties;
private final BeanManagerFactory beanManagerFactory;
private final DatabaseConfig config;
private final ChangeLogListener changeLogListener;
private final ChangeLogRegister changeLogRegister;
private final ChangeLogPrepare changeLogPrepare;
private final DocStoreFactory docStoreFactory;
private final MultiValueBind multiValueBind;
private final TypeManager typeManager;
private int entityBeanCount;
private final BootupClasses bootupClasses;
private final String serverName;
private final Map<Class<?>, BeanTable> beanTableMap = new HashMap<>();
private final Map<String, BeanDescriptor<?>> descMap = new HashMap<>();
private final Map<String, BeanDescriptor<?>> descQueueMap = new HashMap<>();
private final Map<String, BeanManager<?>> beanManagerMap = new HashMap<>();
private final Map<String, List<BeanDescriptor<?>>> tableToDescMap = new HashMap<>();
private final Map<String, List<BeanDescriptor<?>>> tableToViewDescMap = new HashMap<>();
private List<BeanDescriptor<?>> immutableDescriptorList;
private final DbIdentity dbIdentity;
private final DataSource dataSource;
private final DatabasePlatform databasePlatform;
private final SpiCacheManager cacheManager;
private final BackgroundExecutor backgroundExecutor;
private final EncryptKeyManager encryptKeyManager;
private final IdBinderFactory idBinderFactory;
private final BeanLifecycleAdapterFactory beanLifecycleAdapterFactory;
private final String asOfViewSuffix;
private final boolean jacksonCorePresent;
private final int queryPlanTTLSeconds;
private int entityBeanCount;
private List<BeanDescriptor<?>> immutableDescriptorList;
/**
* Map of base tables to 'with history views' used to support 'as of' queries.
@@ -187,8 +147,6 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
*/
private final Map<String, String> draftTableMap = new HashMap<>();
private final int queryPlanTTLSeconds;
// temporary collections used during startup and then cleared
private Map<Class<?>, DeployBeanInfo<?>> deployInfoMap = new HashMap<>();
@@ -232,6 +190,12 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
this.changeLogPrepare = config.changeLogPrepare(bootupClasses.getChangeLogPrepare());
this.changeLogListener = config.changeLogListener(bootupClasses.getChangeLogListener());
this.changeLogRegister = config.changeLogRegister(bootupClasses.getChangeLogRegister());
this.jacksonCorePresent = config.isJacksonCorePresent();
}
@Override
public boolean isJacksonCorePresent() {
return jacksonCorePresent;
}
/**
@@ -71,4 +71,9 @@ public interface BeanDescriptorMap {
* Return the scalarType for the given logical type.
*/
ScalarType<?> getScalarType(String cast);
/**
* Return true if Jackson core is present on the classpath.
*/
boolean isJacksonCorePresent();
}
@@ -144,7 +144,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
}
this.inverseJoin = deploy.createInverseTableJoin();
this.modifyListenMode = deploy.getModifyListenMode();
this.jsonHelp = new BeanPropertyAssocManyJsonHelp(this);
this.jsonHelp = descriptor.isJacksonCorePresent() ? new BeanPropertyAssocManyJsonHelp(this) : null;
}
@Override
@@ -26,12 +26,10 @@ class InsertTimestampFactory {
map.put(Long.class, longTime);
map.put(long.class, longTime);
if (classLoadConfig.isJavaTimePresent()) {
map.put(Instant.class, new GeneratedInsertJavaTime.InstantDT());
map.put(LocalDateTime.class, new GeneratedInsertJavaTime.LocalDT());
map.put(OffsetDateTime.class, new GeneratedInsertJavaTime.OffsetDT());
map.put(ZonedDateTime.class, new GeneratedInsertJavaTime.ZonedDT());
}
map.put(Instant.class, new GeneratedInsertJavaTime.InstantDT());
map.put(LocalDateTime.class, new GeneratedInsertJavaTime.LocalDT());
map.put(OffsetDateTime.class, new GeneratedInsertJavaTime.OffsetDT());
map.put(ZonedDateTime.class, new GeneratedInsertJavaTime.ZonedDT());
if (classLoadConfig.isJodaTimePresent()) {
map.put(org.joda.time.LocalDateTime.class, new GeneratedInsertJodaTime.LocalDT());
map.put(org.joda.time.DateTime.class, new GeneratedInsertJodaTime.DateTimeDT());
@@ -26,12 +26,11 @@ class UpdateTimestampFactory {
map.put(Long.class, longTime);
map.put(long.class, longTime);
if (classLoadConfig.isJavaTimePresent()) {
map.put(Instant.class, new GeneratedUpdateJavaTime.InstantDT());
map.put(LocalDateTime.class, new GeneratedUpdateJavaTime.LocalDT());
map.put(OffsetDateTime.class, new GeneratedUpdateJavaTime.OffsetDT());
map.put(ZonedDateTime.class, new GeneratedUpdateJavaTime.ZonedDT());
}
map.put(Instant.class, new GeneratedUpdateJavaTime.InstantDT());
map.put(LocalDateTime.class, new GeneratedUpdateJavaTime.LocalDT());
map.put(OffsetDateTime.class, new GeneratedUpdateJavaTime.OffsetDT());
map.put(ZonedDateTime.class, new GeneratedUpdateJavaTime.ZonedDT());
if (classLoadConfig.isJodaTimePresent()) {
map.put(org.joda.time.LocalDateTime.class, new GeneratedUpdateJodaTime.LocalDT());
map.put(org.joda.time.DateTime.class, new GeneratedUpdateJodaTime.DateTimeDT());
@@ -7,6 +7,7 @@ import java.security.SecureRandom;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,6 +45,8 @@ public class UuidV1RndIdGenerator implements PlatformIdGenerator {
private AtomicLong nanoToMilliOffset = new AtomicLong(currentUuidTime());
private final ReentrantLock lock = new ReentrantLock(false);
/**
* Returns the uuid epoch.
@@ -106,7 +109,8 @@ public class UuidV1RndIdGenerator implements PlatformIdGenerator {
logger.info("Clock skew of {} ms detected", delta / -10000);
// The clock was adjusted back about 2 seconds, or we were generating a lot of ids too fast
// if so, we try to set the current as last and also increment the clockSeq.
synchronized (this) {
lock.lock();
try {
if (clockSeq.compareAndSet(seq, seq + 1)) {
timeStamp.set(current);
saveState();
@@ -114,6 +118,8 @@ public class UuidV1RndIdGenerator implements PlatformIdGenerator {
} else {
continue;
}
} finally {
lock.unlock();
}
}
// If current is in the future (most of the cases) try to set it.
@@ -6,6 +6,7 @@ import org.slf4j.LoggerFactory;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* A "CachedThreadPool" based on Daemon threads.
@@ -16,6 +17,8 @@ public final class DaemonExecutorService {
private static final Logger logger = LoggerFactory.getLogger(DaemonExecutorService.class);
private final ReentrantLock lock = new ReentrantLock(false);
private final String namePrefix;
private final int shutdownWaitSeconds;
@@ -49,7 +52,8 @@ public final class DaemonExecutorService {
* </p>
*/
public void shutdown() {
synchronized (this) {
lock.lock();
try {
if (service.isShutdown()) {
logger.debug("DaemonExecutorService[{}] already shut down", namePrefix);
return;
@@ -66,6 +70,8 @@ public final class DaemonExecutorService {
logger.error("Error during shutdown of DaemonThreadPool[" + namePrefix + "]", e);
e.printStackTrace();
}
} finally {
lock.unlock();
}
}
@@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* Daemon based ScheduleThreadPool.
@@ -16,6 +17,8 @@ public final class DaemonScheduleThreadPool extends ScheduledThreadPoolExecutor
private static final Logger logger = LoggerFactory.getLogger(DaemonScheduleThreadPool.class);
private final ReentrantLock lock = new ReentrantLock(false);
private final String namePrefix;
private final int shutdownWaitSeconds;
@@ -38,7 +41,8 @@ public final class DaemonScheduleThreadPool extends ScheduledThreadPoolExecutor
*/
@Override
public void shutdown() {
synchronized (this) {
lock.lock();
try {
if (super.isShutdown()) {
logger.debug("DaemonScheduleThreadPool {} already shut down", namePrefix);
return;
@@ -55,6 +59,8 @@ public final class DaemonScheduleThreadPool extends ScheduledThreadPoolExecutor
logger.error("Error during shutdown of " + namePrefix, e);
e.printStackTrace();
}
} finally {
lock.unlock();
}
}
}
@@ -7,11 +7,15 @@ import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.querydefn.OrmQueryProperties;
import java.util.concurrent.locks.ReentrantLock;
/**
* Base class for Bean and BeanCollection loading (lazy loading and query join loading).
*/
abstract class DLoadBaseContext {
protected final ReentrantLock lock = new ReentrantLock(false);
protected final DLoadContext parent;
protected final BeanDescriptor<?> desc;
@@ -17,6 +17,8 @@ import io.ebeaninternal.server.querydefn.OrmQueryProperties;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* ToOne bean load context.
@@ -86,11 +88,11 @@ class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext {
@Override
public void loadSecondaryQuery(OrmQueryRequest<?> parentRequest, boolean forEach) {
if (!queryFetch) {
throw new IllegalStateException("Not expecting loadSecondaryQuery() to be called?");
}
synchronized (this) {
lock.lock();
try {
if (bufferList != null) {
for (LoadBuffer loadBuffer : bufferList) {
if (!loadBuffer.list.isEmpty()) {
@@ -108,6 +110,8 @@ class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext {
}
}
}
} finally {
lock.unlock();
}
}
@@ -116,6 +120,7 @@ class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext {
*/
static class LoadBuffer implements BeanLoader, LoadBeanBuffer {
private final ReentrantLock bufferLock = new ReentrantLock(false);
private final DLoadBeanContext context;
private final int batchSize;
private final List<EntityBeanIntercept> list;
@@ -127,6 +132,12 @@ class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext {
this.list = new ArrayList<>(batchSize);
}
@Override
public Lock lock() {
bufferLock.lock();
return bufferLock;
}
@Override
public int getBatchSize() {
return batchSize;
@@ -182,7 +193,7 @@ class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext {
@Override
public void loadBean(EntityBeanIntercept ebi) {
// A synchronized (this) is effectively held by EntityBeanIntercept.loadBean()
// A lock is effectively held by EntityBeanIntercept.loadBean()
if (context.desc.lazyLoadMany(ebi, context)) {
// lazy load property was a Many
return;
@@ -16,6 +16,7 @@ import io.ebeaninternal.server.querydefn.OrmQueryProperties;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
/**
* ToMany bean load context.
@@ -94,11 +95,11 @@ class DLoadManyContext extends DLoadBaseContext implements LoadManyContext {
@Override
public void loadSecondaryQuery(OrmQueryRequest<?> parentRequest, boolean forEach) {
if (!queryFetch) {
throw new IllegalStateException("Not expecting loadSecondaryQuery() to be called?");
}
synchronized (this) {
lock.lock();
try {
if (bufferList != null) {
for (LoadBuffer loadBuffer : bufferList) {
if (!loadBuffer.list.isEmpty()) {
@@ -118,6 +119,8 @@ class DLoadManyContext extends DLoadBaseContext implements LoadManyContext {
this.bufferList = null;
}
}
} finally {
lock.unlock();
}
}
@@ -127,6 +130,7 @@ class DLoadManyContext extends DLoadBaseContext implements LoadManyContext {
*/
static class LoadBuffer implements BeanCollectionLoader, LoadManyBuffer {
private final ReentrantLock lock = new ReentrantLock(false);
private final PersistenceContext persistenceContext;
private final DLoadManyContext context;
private final int batchSize;
@@ -208,7 +212,8 @@ class DLoadManyContext extends DLoadBaseContext implements LoadManyContext {
@Override
public void loadMany(BeanCollection<?> bc, boolean onlyIds) {
synchronized (this) {
lock.lock();
try {
boolean useCache = !onlyIds && context.hitCache && context.property.isUseCache();
if (useCache) {
EntityBean ownerBean = bc.getOwnerBean();
@@ -231,6 +236,8 @@ class DLoadManyContext extends DLoadBaseContext implements LoadManyContext {
LoadManyRequest req = new LoadManyRequest(this, onlyIds, useCache);
context.parent.getEbeanServer().loadMany(req);
} finally {
lock.unlock();
}
}
@@ -8,6 +8,7 @@ import io.ebeaninternal.server.expression.platform.DbExpressionHandler;
import io.ebeaninternal.server.persist.platform.MultiValueBind;
import io.ebeaninternal.server.type.DataBind;
import io.ebeaninternal.server.type.DataReader;
import io.ebeaninternal.server.type.GeoTypeBinder;
import io.ebeaninternal.server.type.PostgresHelper;
import io.ebeaninternal.server.type.RsetDataReader;
import io.ebeaninternal.server.type.ScalarType;
@@ -35,26 +36,18 @@ public class Binder {
private static final Logger logger = LoggerFactory.getLogger(Binder.class);
private final TypeManager typeManager;
private final int asOfBindCount;
private final boolean asOfStandardsBased;
private final DbExpressionHandler dbExpressionHandler;
private final DataTimeZone dataTimeZone;
private final MultiValueBind multiValueBind;
private final boolean enableBindLog;
private final GeoTypeBinder geoTypeBinder;
/**
* Set the PreparedStatement with which to bind variables to.
*/
public Binder(TypeManager typeManager, SpiLogManager logManager, int asOfBindCount, boolean asOfStandardsBased,
DbExpressionHandler dbExpressionHandler, DataTimeZone dataTimeZone, MultiValueBind multiValueBind) {
this.typeManager = typeManager;
this.geoTypeBinder = typeManager.getGeoTypeBinder();
this.asOfBindCount = asOfBindCount;
this.asOfStandardsBased = asOfStandardsBased;
this.dbExpressionHandler = dbExpressionHandler;
@@ -88,9 +81,7 @@ public class Binder {
* Bind the values to the Prepared Statement.
*/
public void bind(BindValues bindValues, DataBind dataBind, StringBuilder bindBuf) throws SQLException {
String logPrefix = "";
ArrayList<BindValues.Value> list = bindValues.values();
for (BindValues.Value bindValue : list) {
Object val = bindValue.getValue();
@@ -124,7 +115,6 @@ public class Binder {
* Bind the list of positionedParameters in BindParams.
*/
private String bind(BindParams bindParams, DataBind dataBind) throws SQLException {
StringBuilder bindLog = new StringBuilder();
bind(bindParams, dataBind, bindLog);
return bindLog.toString();
@@ -134,7 +124,6 @@ public class Binder {
* Bind the list of positionedParameters in BindParams.
*/
public void bind(BindParams bindParams, DataBind dataBind, StringBuilder bindLog) throws SQLException {
bind(bindParams.positionedParameters(), dataBind, bindLog);
}
@@ -142,13 +131,10 @@ public class Binder {
* Bind the list of parameters..
*/
private void bind(List<BindParams.Param> list, DataBind dataBind, StringBuilder bindLog) throws SQLException {
CallableStatement cstmt = null;
if (dataBind.getPstmt() instanceof CallableStatement) {
cstmt = (CallableStatement) dataBind.getPstmt();
}
// the iterator is assumed to be in the correct order
Object value = null;
try {
@@ -211,7 +197,6 @@ public class Binder {
* Bind an Object with unknown data type.
*/
public Object bindObject(DataBind dataBind, Object value) throws SQLException {
if (value == null) {
// null of unknown type
bindObject(dataBind, null, Types.OTHER);
@@ -233,9 +218,7 @@ public class Binder {
// convert to a JDBC native type
value = type.toJdbcType(value);
}
int dbType = type.getJdbcType();
bindObject(dataBind, value, dbType);
bindObject(dataBind, value, type.getJdbcType());
return value;
}
}
@@ -261,12 +244,10 @@ public class Binder {
* </p>
*/
private void bindObject(DataBind dataBind, Object data, int dbType) throws SQLException {
if (data == null) {
dataBind.setNull(dbType);
return;
}
switch (dbType) {
case java.sql.Types.LONGVARCHAR:
bindLongVarChar(dataBind, data);
@@ -293,7 +274,6 @@ public class Binder {
* Binds the value to the statement according to the data type.
*/
private void bindSimpleData(DataBind b, int dataType, Object data) {
try {
switch (dataType) {
case java.sql.Types.BOOLEAN:
@@ -370,6 +350,15 @@ public class Binder {
b.setObject(PostgresHelper.asInet(data.toString()));
break;
case DbPlatformType.POINT:
case DbPlatformType.POLYGON:
case DbPlatformType.MULTIPOINT:
case DbPlatformType.LINESTRING:
case DbPlatformType.MULTILINESTRING:
case DbPlatformType.MULTIPOLYGON:
geoTypeBinder.bind(b, dataType, data);
break;
case java.sql.Types.OTHER:
b.setObject(data, dataType);
break;
@@ -393,7 +382,6 @@ public class Binder {
* Bind String data to a LONGVARCHAR column.
*/
private void bindLongVarChar(DataBind dataBind, Object data) throws SQLException {
dataBind.setClob((String) data);
}
@@ -401,7 +389,6 @@ public class Binder {
* Bind byte[] data to a LONGVARBINARY column.
*/
private void bindLongVarBinary(DataBind dataBind, Object data) throws SQLException {
dataBind.setBlob((byte[]) data);
}
@@ -409,7 +396,6 @@ public class Binder {
* Bind String data to a CLOB column.
*/
private void bindClob(DataBind dataBind, Object data) throws SQLException {
dataBind.setClob((String) data);
}
@@ -417,7 +403,6 @@ public class Binder {
* Bind byte[] data to a BLOB column.
*/
private void bindBlob(DataBind dataBind, Object data) throws SQLException {
dataBind.setBlob((byte[]) data);
}
@@ -39,6 +39,7 @@ import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
/**
* An object that represents a SqlSelect statement.
@@ -58,6 +59,8 @@ public class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfileTran
private static final CQueryCollectionAddNoop NOOP_ADD = new CQueryCollectionAddNoop();
private final ReentrantLock lock = new ReentrantLock(false);
/**
* The resultSet rows read.
*/
@@ -288,7 +291,8 @@ public class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfileTran
@Override
public void cancel() {
synchronized (this) {
lock.lock();
try {
this.cancelled = true;
if (pstmt != null) {
try {
@@ -298,6 +302,8 @@ public class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfileTran
throw new PersistenceException(msg, e);
}
}
} finally {
lock.unlock();
}
}
@@ -326,8 +332,8 @@ public class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfileTran
}
ResultSet prepareResultSet(boolean forwardOnlyHint) throws SQLException {
synchronized (this) {
lock.lock();
try {
if (cancelled || query.isCancelled()) {
// cancelled before we started
cancelled = true;
@@ -370,6 +376,8 @@ public class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfileTran
// executeQuery
return pstmt.executeQuery();
} finally {
lock.unlock();
}
}
@@ -524,8 +532,8 @@ public class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfileTran
}
boolean hasNext() throws SQLException {
synchronized (this) {
lock.lock();
try {
if (noMoreRows || cancelled) {
return false;
}
@@ -534,6 +542,8 @@ public class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfileTran
}
hasNextCache = readNextBean();
return hasNextCache;
} finally {
lock.unlock();
}
}
@@ -5,10 +5,13 @@ import io.ebeaninternal.api.SpiQueryBindCapture;
import io.ebeaninternal.api.SpiQueryPlan;
import io.ebeaninternal.server.type.bindcapture.BindCapture;
import java.util.concurrent.locks.ReentrantLock;
class CQueryBindCapture implements SpiQueryBindCapture {
private static final double multiplier = 1.3d;
private final ReentrantLock lock = new ReentrantLock(false);
private final CQueryPlanManager manager;
private final SpiQueryPlan queryPlan;
@@ -35,13 +38,16 @@ class CQueryBindCapture implements SpiQueryBindCapture {
@Override
public void setBind(BindCapture bindCapture, long queryTimeMicros, long startNanos) {
synchronized (this) {
lock.lock();
try {
this.thresholdMicros = Math.round(queryTimeMicros * multiplier);
this.captureCount++;
this.bindCapture = bindCapture;
this.queryTimeMicros = queryTimeMicros;
lastBindCapture = System.currentTimeMillis();
manager.notifyBindCapture(this, startNanos);
} finally {
lock.unlock();
}
}
@@ -1,31 +1,29 @@
package io.ebeaninternal.server.query;
import io.ebean.PagedList;
import io.ebeaninternal.api.Monitor;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import javax.persistence.PersistenceException;
import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.locks.ReentrantLock;
/**
* PagedList implementation based on limit offset types of queries.
*
* @param <T> the entity bean type
*/
public class LimitOffsetPagedList<T> implements PagedList<T> {
private final transient SpiEbeanServer server;
private final transient ReentrantLock lock = new ReentrantLock(false);
private final SpiQuery<T> query;
private final int firstRow;
private final int maxRows;
private final Monitor monitor = new Monitor();
private int foregroundTotalRowCount = -1;
private Future<Integer> futureRowCount;
@@ -49,21 +47,27 @@ public class LimitOffsetPagedList<T> implements PagedList<T> {
@Override
public Future<Integer> getFutureCount() {
synchronized (monitor) {
lock.lock();
try {
if (futureRowCount == null) {
futureRowCount = server.findFutureCount(query, null);
}
return futureRowCount;
} finally {
lock.unlock();
}
}
@Override
public List<T> getList() {
synchronized (monitor) {
lock.lock();
try {
if (list == null) {
list = server.findList(query, null);
}
return list;
} finally {
lock.unlock();
}
}
@@ -77,7 +81,6 @@ public class LimitOffsetPagedList<T> implements PagedList<T> {
@Override
public int getTotalPageCount() {
int rowCount = getTotalCount();
if (rowCount == 0) {
return 0;
@@ -88,7 +91,8 @@ public class LimitOffsetPagedList<T> implements PagedList<T> {
@Override
public int getTotalCount() {
synchronized (monitor) {
lock.lock();
try {
if (futureRowCount != null) {
try {
// background query already initiated so get it with a wait
@@ -103,6 +107,8 @@ public class LimitOffsetPagedList<T> implements PagedList<T> {
// just using foreground thread
foregroundTotalRowCount = server.findCount(query, null);
return foregroundTotalRowCount;
} finally {
lock.unlock();
}
}
@@ -123,11 +129,9 @@ public class LimitOffsetPagedList<T> implements PagedList<T> {
@Override
public String getDisplayXtoYofZ(String to, String of) {
int first = firstRow + 1;
int last = firstRow + getList().size();
int total = getTotalCount();
return first + to + last + of + total;
}
@@ -71,6 +71,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
@@ -88,6 +89,8 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
private static final FetchConfig FETCH_LAZY = new FetchConfig().lazy();
private final ReentrantLock lock = new ReentrantLock(false);
private final Class<T> beanType;
private final ExpressionFactory expressionFactory;
@@ -1992,8 +1995,11 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
@Override
public void setCancelableQuery(CancelableQuery cancelableQuery) {
synchronized (this) {
lock.lock();
try {
this.cancelableQuery = cancelableQuery;
} finally {
lock.unlock();
}
}
@@ -2026,18 +2032,24 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
@Override
public void cancel() {
synchronized (this) {
lock.lock();
try {
cancelled = true;
if (cancelableQuery != null) {
cancelableQuery.cancel();
}
} finally {
lock.unlock();
}
}
@Override
public boolean isCancelled() {
synchronized (this) {
lock.lock();
try {
return cancelled;
} finally {
lock.unlock();
}
}
@@ -1,12 +1,12 @@
package io.ebeaninternal.server.transaction;
import io.ebean.bean.PersistenceContext;
import io.ebeaninternal.api.Monitor;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
/**
* Default implementation of PersistenceContext.
@@ -32,7 +32,7 @@ public final class DefaultPersistenceContext implements PersistenceContext {
*/
private final HashMap<Class<?>, ClassContext> typeCache = new HashMap<>();
private final Monitor monitor = new Monitor();
private final ReentrantLock lock = new ReentrantLock(false);
private int putCount;
@@ -68,7 +68,8 @@ public final class DefaultPersistenceContext implements PersistenceContext {
}
public boolean resetLimit() {
synchronized (monitor) {
lock.lock();
try {
if (putCount < 100) {
return false;
}
@@ -80,6 +81,8 @@ public final class DefaultPersistenceContext implements PersistenceContext {
}
// checking after another 100 puts
return false;
} finally {
lock.unlock();
}
}
@@ -88,17 +91,23 @@ public final class DefaultPersistenceContext implements PersistenceContext {
*/
@Override
public void put(Class<?> rootType, Object id, Object bean) {
synchronized (monitor) {
lock.lock();
try {
putCount++;
getClassContext(rootType).put(id, bean);
} finally {
lock.unlock();
}
}
@Override
public Object putIfAbsent(Class<?> rootType, Object id, Object bean) {
synchronized (monitor) {
lock.lock();
try {
putCount++;
return getClassContext(rootType).putIfAbsent(id, bean);
} finally {
lock.unlock();
}
}
@@ -107,15 +116,21 @@ public final class DefaultPersistenceContext implements PersistenceContext {
*/
@Override
public Object get(Class<?> rootType, Object id) {
synchronized (monitor) {
lock.lock();
try {
return getClassContext(rootType).get(id);
} finally {
lock.unlock();
}
}
@Override
public WithOption getWithOption(Class<?> rootType, Object id) {
synchronized (monitor) {
lock.lock();
try {
return getClassContext(rootType).getWithOption(id);
} finally {
lock.unlock();
}
}
@@ -124,9 +139,12 @@ public final class DefaultPersistenceContext implements PersistenceContext {
*/
@Override
public int size(Class<?> rootType) {
synchronized (monitor) {
lock.lock();
try {
ClassContext classMap = typeCache.get(rootType);
return classMap == null ? 0 : classMap.size();
} finally {
lock.unlock();
}
}
@@ -135,45 +153,60 @@ public final class DefaultPersistenceContext implements PersistenceContext {
*/
@Override
public void clear() {
synchronized (monitor) {
lock.lock();
try {
typeCache.clear();
} finally {
lock.unlock();
}
}
@Override
public void clear(Class<?> rootType) {
synchronized (monitor) {
lock.lock();
try {
ClassContext classMap = typeCache.get(rootType);
if (classMap != null) {
classMap.clear();
}
} finally {
lock.unlock();
}
}
@Override
public void deleted(Class<?> rootType, Object id) {
synchronized (monitor) {
lock.lock();
try {
ClassContext classMap = typeCache.get(rootType);
if (classMap != null && id != null) {
classMap.deleted(id);
}
} finally {
lock.unlock();
}
}
@Override
public void clear(Class<?> rootType, Object id) {
synchronized (monitor) {
lock.lock();
try {
ClassContext classMap = typeCache.get(rootType);
if (classMap != null && id != null) {
classMap.remove(id);
}
} finally {
lock.unlock();
}
}
@Override
public String toString() {
synchronized (monitor) {
lock.lock();
try {
return typeCache.toString();
} finally {
lock.unlock();
}
}
@@ -21,6 +21,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
import static java.time.temporal.ChronoField.HOUR_OF_DAY;
@@ -65,6 +66,8 @@ public class DefaultProfileHandler implements SpiProfileHandler, Plugin {
private final ExecutorService executor;
private final ReentrantLock lock = new ReentrantLock(false);
private final File dir;
private final long minMicros;
@@ -117,7 +120,8 @@ public class DefaultProfileHandler implements SpiProfileHandler, Plugin {
}
private void flushCurrentFile() {
synchronized (this) {
lock.lock();
try {
if (out != null) {
try {
out.close();
@@ -126,6 +130,8 @@ public class DefaultProfileHandler implements SpiProfileHandler, Plugin {
log.error("Failed to flush and close transaction profiling file ", e);
}
}
} finally {
lock.unlock();
}
}
@@ -133,7 +139,8 @@ public class DefaultProfileHandler implements SpiProfileHandler, Plugin {
* Move to the next file to write to.
*/
private void incrementFile() {
synchronized (this) {
lock.lock();
try {
flushCurrentFile();
try {
String now = DTF.format(LocalDateTime.now());
@@ -142,6 +149,8 @@ public class DefaultProfileHandler implements SpiProfileHandler, Plugin {
} catch (IOException e) {
log.error("Not expected", e);
}
} finally {
lock.unlock();
}
}
@@ -19,6 +19,7 @@ import io.ebean.types.Inet;
import io.ebean.util.AnnotationUtil;
import io.ebeaninternal.api.ExtraTypeFactory;
import io.ebeaninternal.api.DbOffline;
import io.ebeaninternal.api.GeoTypeProvider;
import io.ebeaninternal.server.core.bootup.BootupClasses;
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
import io.ebeanservice.docstore.api.mapping.DocPropertyType;
@@ -145,8 +146,6 @@ public final class DefaultTypeManager implements TypeManager {
private final Object objectMapper;
private final boolean java7Present;
private final boolean objectMapperPresent;
private final boolean postgres;
@@ -180,13 +179,12 @@ public final class DefaultTypeManager implements TypeManager {
private final PlatformArrayTypeFactory arrayTypeListFactory;
private final PlatformArrayTypeFactory arrayTypeSetFactory;
private GeoTypeBinder geoTypeBinder;
/**
* Create the DefaultTypeManager.
*/
public DefaultTypeManager(DatabaseConfig config, BootupClasses bootupClasses) {
this.java7Present = config.getClassLoadConfig().isJava7Present();
this.jsonDateTime = config.getJsonDateTime();
this.jsonDate = config.getJsonDate();
this.typeMap = new ConcurrentHashMap<>();
@@ -211,6 +209,7 @@ public final class DefaultTypeManager implements TypeManager {
initialiseJacksonTypes(config);
loadTypesFromProviders(config, objectMapper);
loadGeoTypeBinder(config);
if (bootupClasses != null) {
initialiseCustomScalarTypes(bootupClasses);
@@ -219,6 +218,13 @@ public final class DefaultTypeManager implements TypeManager {
}
}
private void loadGeoTypeBinder(DatabaseConfig config) {
final GeoTypeProvider provider = config.service(GeoTypeProvider.class);
if (provider != null) {
geoTypeBinder = provider.createBinder(config);
}
}
/**
* Return the factory to use to support DB ARRAY types.
*/
@@ -335,19 +341,17 @@ public final class DefaultTypeManager implements TypeManager {
}
private ScalarType<?> checkInterfaceTypes(Class<?> type) {
if (java7Present) {
return checkJava7InterfaceTypes(type);
}
return null;
}
private ScalarType<?> checkJava7InterfaceTypes(Class<?> type) {
if (java.nio.file.Path.class.isAssignableFrom(type)) {
return typeMap.get(java.nio.file.Path.class);
}
return null;
}
@Override
public GeoTypeBinder getGeoTypeBinder() {
return geoTypeBinder;
}
@Override
public ScalarType<?> getDbMapScalarType() {
return (postgres) ? hstoreType : ScalarTypeJsonMap.typeFor(false, Types.VARCHAR);
@@ -882,33 +886,25 @@ public final class DefaultTypeManager implements TypeManager {
}
private void initialiseJavaTimeTypes(DatabaseConfig config) {
if (java7Present) {
typeMap.put(java.nio.file.Path.class, new ScalarTypePath());
}
if (config.getClassLoadConfig().isJavaTimePresent()) {
logger.debug("Registering java.time data types");
addType(java.time.Period.class, new ScalarTypePeriod());
addType(java.time.LocalDate.class, new ScalarTypeLocalDate(jsonDate));
addType(java.time.LocalDateTime.class, new ScalarTypeLocalDateTime(jsonDateTime));
addType(OffsetDateTime.class, new ScalarTypeOffsetDateTime(jsonDateTime));
addType(ZonedDateTime.class, new ScalarTypeZonedDateTime(jsonDateTime));
addType(Instant.class, new ScalarTypeInstant(jsonDateTime));
addType(DayOfWeek.class, new ScalarTypeDayOfWeek());
addType(Month.class, new ScalarTypeMonth());
addType(Year.class, new ScalarTypeYear());
addType(YearMonth.class, new ScalarTypeYearMonthDate(jsonDate));
addType(MonthDay.class, new ScalarTypeMonthDay());
addType(OffsetTime.class, new ScalarTypeOffsetTime());
addType(ZoneId.class, new ScalarTypeZoneId());
addType(ZoneOffset.class, new ScalarTypeZoneOffset());
boolean localTimeNanos = config.isLocalTimeWithNanos();
addType(java.time.LocalTime.class, (localTimeNanos) ? new ScalarTypeLocalTimeWithNanos() : new ScalarTypeLocalTime());
boolean durationNanos = config.isDurationWithNanos();
addType(Duration.class, (durationNanos) ? new ScalarTypeDurationWithNanos() : new ScalarTypeDuration());
}
typeMap.put(java.nio.file.Path.class, new ScalarTypePath());
addType(java.time.Period.class, new ScalarTypePeriod());
addType(java.time.LocalDate.class, new ScalarTypeLocalDate(jsonDate));
addType(java.time.LocalDateTime.class, new ScalarTypeLocalDateTime(jsonDateTime));
addType(OffsetDateTime.class, new ScalarTypeOffsetDateTime(jsonDateTime));
addType(ZonedDateTime.class, new ScalarTypeZonedDateTime(jsonDateTime));
addType(Instant.class, new ScalarTypeInstant(jsonDateTime));
addType(DayOfWeek.class, new ScalarTypeDayOfWeek());
addType(Month.class, new ScalarTypeMonth());
addType(Year.class, new ScalarTypeYear());
addType(YearMonth.class, new ScalarTypeYearMonthDate(jsonDate));
addType(MonthDay.class, new ScalarTypeMonthDay());
addType(OffsetTime.class, new ScalarTypeOffsetTime());
addType(ZoneId.class, new ScalarTypeZoneId());
addType(ZoneOffset.class, new ScalarTypeZoneOffset());
boolean localTimeNanos = config.isLocalTimeWithNanos();
addType(java.time.LocalTime.class, (localTimeNanos) ? new ScalarTypeLocalTimeWithNanos() : new ScalarTypeLocalTime());
boolean durationNanos = config.isDurationWithNanos();
addType(Duration.class, (durationNanos) ? new ScalarTypeDurationWithNanos() : new ScalarTypeDuration());
}
private void addType(Class<?> clazz, ScalarType<?> scalarType) {
@@ -0,0 +1,14 @@
package io.ebeaninternal.server.type;
import java.sql.SQLException;
/**
* Binder for Geometry types.
*/
public interface GeoTypeBinder {
/**
* Bind the geometry type.
*/
void bind(DataBind b, int dataType, Object data) throws SQLException;
}
@@ -18,6 +18,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.locks.ReentrantLock;
import static java.util.Collections.EMPTY_LIST;
@@ -33,6 +34,7 @@ public class ScalarTypeArrayList extends ScalarTypeArrayBase<List> implements Sc
static class Factory implements PlatformArrayTypeFactory {
private final ReentrantLock lock = new ReentrantLock(false);
private final Map<String, ScalarTypeArrayList> cache = new HashMap<>();
/**
@@ -40,7 +42,8 @@ public class ScalarTypeArrayList extends ScalarTypeArrayBase<List> implements Sc
*/
@Override
public ScalarTypeArrayList typeFor(Type valueType, boolean nullable) {
synchronized (this) {
lock.lock();
try {
String key = valueType + ":" + nullable;
if (valueType.equals(UUID.class)) {
return cache.computeIfAbsent(key, s -> new ScalarTypeArrayList(nullable, "uuid", DocPropertyType.UUID, ArrayElementConverter.UUID));
@@ -58,6 +61,8 @@ public class ScalarTypeArrayList extends ScalarTypeArrayBase<List> implements Sc
return cache.computeIfAbsent(key, s -> new ScalarTypeArrayList(nullable, "varchar", DocPropertyType.TEXT, ArrayElementConverter.STRING));
}
throw new IllegalArgumentException("Type [" + valueType + "] not supported for @DbArray mapping");
} finally {
lock.unlock();
}
}
@@ -9,6 +9,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.locks.ReentrantLock;
import static java.util.Collections.EMPTY_LIST;
@@ -24,6 +25,7 @@ class ScalarTypeArrayListH2 extends ScalarTypeArrayList {
static class Factory implements PlatformArrayTypeFactory {
private final ReentrantLock lock = new ReentrantLock(false);
private final Map<String, ScalarTypeArrayListH2> cache = new HashMap<>();
/**
@@ -31,7 +33,8 @@ class ScalarTypeArrayListH2 extends ScalarTypeArrayList {
*/
@Override
public ScalarType<?> typeFor(Type valueType, boolean nullable) {
synchronized (this) {
lock.lock();
try {
String key = valueType + ":" + nullable;
if (valueType.equals(UUID.class)) {
return cache.computeIfAbsent(key, s -> new ScalarTypeArrayListH2(nullable, "uuid", DocPropertyType.UUID, ArrayElementConverter.UUID));
@@ -49,6 +52,8 @@ class ScalarTypeArrayListH2 extends ScalarTypeArrayList {
return cache.computeIfAbsent(key, s -> new ScalarTypeArrayListH2(nullable, "varchar", DocPropertyType.TEXT, ArrayElementConverter.STRING));
}
throw new IllegalArgumentException("Type [" + valueType + "] not supported for @DbArray mapping");
} finally {
lock.unlock();
}
}
@@ -18,6 +18,7 @@ import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.locks.ReentrantLock;
import static java.util.Collections.EMPTY_SET;
@@ -33,6 +34,7 @@ public class ScalarTypeArraySet extends ScalarTypeArrayBase<Set> implements Scal
static class Factory implements PlatformArrayTypeFactory {
private final ReentrantLock lock = new ReentrantLock(false);
private final Map<String, ScalarTypeArraySet> cache = new HashMap<>();
/**
@@ -40,7 +42,8 @@ public class ScalarTypeArraySet extends ScalarTypeArrayBase<Set> implements Scal
*/
@Override
public ScalarType<?> typeFor(Type valueType, boolean nullable) {
synchronized (this) {
lock.lock();
try {
String key = valueType + ":" + nullable;
if (valueType.equals(UUID.class)) {
return cache.computeIfAbsent(key, s -> new ScalarTypeArraySet(nullable, "uuid", DocPropertyType.UUID, ArrayElementConverter.UUID));
@@ -58,6 +61,8 @@ public class ScalarTypeArraySet extends ScalarTypeArrayBase<Set> implements Scal
return cache.computeIfAbsent(key, s -> new ScalarTypeArraySet(nullable, "varchar", DocPropertyType.TEXT, ArrayElementConverter.STRING));
}
throw new IllegalArgumentException("Type [" + valueType + "] not supported for @DbArray mapping");
} finally {
lock.unlock();
}
}
@@ -9,6 +9,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.locks.ReentrantLock;
import static java.util.Collections.EMPTY_SET;
@@ -24,6 +25,7 @@ class ScalarTypeArraySetH2 extends ScalarTypeArraySet {
static class Factory implements PlatformArrayTypeFactory {
private final ReentrantLock lock = new ReentrantLock(false);
private final Map<String, ScalarTypeArraySetH2> cache = new HashMap<>();
/**
@@ -31,7 +33,8 @@ class ScalarTypeArraySetH2 extends ScalarTypeArraySet {
*/
@Override
public ScalarType<?> typeFor(Type valueType, boolean nullable) {
synchronized (this) {
lock.lock();
try {
String key = valueType + ":" + nullable;
if (valueType.equals(UUID.class)) {
return cache.computeIfAbsent(key, s -> new ScalarTypeArraySetH2(nullable, "uuid", DocPropertyType.UUID, ArrayElementConverter.UUID));
@@ -49,6 +52,8 @@ class ScalarTypeArraySetH2 extends ScalarTypeArraySet {
return cache.computeIfAbsent(key, s -> new ScalarTypeArraySetH2(nullable, "varchar", DocPropertyType.TEXT, ArrayElementConverter.STRING));
}
throw new IllegalArgumentException("Type [" + valueType + "] not supported for @DbArray mapping");
} finally {
lock.unlock();
}
}
@@ -69,4 +69,9 @@ public interface TypeManager {
* Return the ScalarType used to handle HSTORE (Map<String,String>).
*/
ScalarType<?> getDbMapScalarType();
/**
* Return the Geometry type binder if provided.
*/
GeoTypeBinder getGeoTypeBinder();
}
@@ -1,7 +1,7 @@
package io.ebean;
import io.ebean.config.CurrentTenantProvider;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.TenantCatalogProvider;
import io.ebean.config.TenantDataSourceProvider;
import io.ebean.config.TenantMode;
@@ -29,7 +29,7 @@ public class EbeanServerFactory_MultiTenancy_Test extends BaseTestCase {
TenantDataSourceProvider dataSourceProvider = Mockito.mock(TenantDataSourceProvider.class);
Mockito.doReturn(mockedDataSource).when(dataSourceProvider).dataSource(tenant);
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("multiTenantDb");
config.loadFromProperties();
config.setRegister(false);
@@ -45,7 +45,8 @@ public class EbeanServerFactory_MultiTenancy_Test extends BaseTestCase {
//config.setDdlRun(false);
config.setDatabasePlatform(new PostgresPlatform());
EbeanServerFactory.create(config);
final Database database = DatabaseFactory.create(config);
database.shutdown();
}
@@ -63,9 +64,10 @@ public class EbeanServerFactory_MultiTenancy_Test extends BaseTestCase {
TenantSchemaProvider schemaProvider = Mockito.mock(TenantSchemaProvider.class);
Mockito.doReturn("tenant_schema").when(schemaProvider).schema(tenant);
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2");
config.loadFromProperties();
config.setName("multi-tenancy");
config.setRegister(false);
config.setDefaultServer(false);
@@ -76,7 +78,8 @@ public class EbeanServerFactory_MultiTenancy_Test extends BaseTestCase {
config.setDdlRun(false);
config.setDatabasePlatform(new MySqlPlatform());
EbeanServerFactory.create(config);
final Database database = DatabaseFactory.create(config);
database.shutdown();
}
/**
@@ -92,9 +95,10 @@ public class EbeanServerFactory_MultiTenancy_Test extends BaseTestCase {
TenantCatalogProvider catalogProvider = Mockito.mock(TenantCatalogProvider.class);
Mockito.doReturn("tenant_catalog").when(catalogProvider).catalog(tenant);
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2");
config.loadFromProperties();
config.setName("multi-tenancy");
config.setRegister(false);
config.setDefaultServer(false);
@@ -105,6 +109,7 @@ public class EbeanServerFactory_MultiTenancy_Test extends BaseTestCase {
config.setDdlRun(false);
config.setDatabasePlatform(new MySqlPlatform());
EbeanServerFactory.create(config);
final Database database = DatabaseFactory.create(config);
database.shutdown();
}
}
@@ -1,7 +1,6 @@
package io.ebean;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.ServerConfig;
import io.ebean.event.ServerConfigStartup;
import org.junit.Test;
import org.tests.model.basic.UTDetail;
@@ -13,7 +12,7 @@ public class EbeanServerFactory_ServerConfigStart_Test {
@Test
public void test() throws InterruptedException {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2");
config.loadFromProperties();
config.setName("h2other");
@@ -30,17 +29,17 @@ public class EbeanServerFactory_ServerConfigStart_Test {
OnStartup onStartup = new OnStartup();
config.addServerConfigStartup(onStartup);
EbeanServer ebeanServer = EbeanServerFactory.create(config);
Database db = DatabaseFactory.create(config);
assertThat(onStartup.calledWithConfig).isSameAs(config);
assertThat(OnStartupViaClass.calledWithConfig).isSameAs(config);
assertThat(ebeanServer).isNotNull();
assertThat(db).isNotNull();
// test server shutdown and restart using the same ServerConfig
ebeanServer.shutdown(true, false);
db.shutdown(true, false);
EbeanServer restartedServer = EbeanServerFactory.create(config);
Database restartedServer = DatabaseFactory.create(config);
restartedServer.shutdown(true, false);
}
@@ -1,12 +1,13 @@
package io.ebean.config;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.Transaction;
import io.ebean.annotation.Platform;
import io.ebean.config.dbplatform.DbIdentity;
import io.ebean.config.dbplatform.IdType;
import io.ebean.config.dbplatform.h2.H2Platform;
import org.junit.AfterClass;
import org.junit.Test;
import org.tests.model.basic.EBasicVer;
import org.tests.model.draftable.BasicDraftableBean;
@@ -15,7 +16,12 @@ import static org.assertj.core.api.Assertions.assertThat;
public class PlatformNoGeneratedKeysTest {
static EbeanServer server = testH2Server();
static Database server = testH2Server();
@AfterClass
public static void shutdown() {
server.shutdown();
}
@Test
public void global_serverConfig_setDisableLazyLoading() {
@@ -79,9 +85,9 @@ public class PlatformNoGeneratedKeysTest {
assertThat(one.isDraft()).isFalse();
}
private static EbeanServer testH2Server() {
private static Database testH2Server() {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2_noGeneratedKeys");
OtherH2Platform platform = new OtherH2Platform();
@@ -108,7 +114,7 @@ public class PlatformNoGeneratedKeysTest {
config.getClasses().add(BasicDraftableBean.class);
return EbeanServerFactory.create(config);
return DatabaseFactory.create(config);
}
public static class OtherH2Platform extends H2Platform {
@@ -1,8 +1,8 @@
package io.ebean.config;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.annotation.ForPlatform;
import io.ebean.annotation.Platform;
import org.junit.Ignore;
@@ -26,7 +26,7 @@ public class ServerConfigSqlServerTest {
// no explicit databasePlatformName set ..
//props.setProperty("ebean.some_sqlserver.databasePlatformName", "sqlserver17");
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("some_sqlserver");
config.loadFromProperties(props);
@@ -38,9 +38,10 @@ public class ServerConfigSqlServerTest {
config.setRegister(false);
config.getClasses().add(EBasicVer.class);
EbeanServer sqlServer = EbeanServerFactory.create(config);
Database sqlServer = DatabaseFactory.create(config);
assertThat(sqlServer).isNotNull();
sqlServer.shutdown();
// javax.persistence.PersistenceException: java.lang.IllegalArgumentException: For SqlServer please choose the more specific sqlserver16 or sqlserver17 platform via ServerConfig.setDatabasePlatformName. Refer to issue #1340 for details
//
@@ -61,7 +62,7 @@ public class ServerConfigSqlServerTest {
String name = "testsqlserver17";
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName(name);
Properties props = props(name);
@@ -79,9 +80,10 @@ public class ServerConfigSqlServerTest {
config.loadFromProperties(props);
config.getClasses().add(EBasicVer.class);
EbeanServer sqlServer = EbeanServerFactory.create(config);
Database sqlServer = DatabaseFactory.create(config);
assertThat(sqlServer).isNotNull();
sqlServer.shutdown();
}
@Ignore
@@ -93,7 +95,7 @@ public class ServerConfigSqlServerTest {
Properties props = props(name);
//props.setProperty("ebean.testsqlserver16.databasePlatformName", "sqlserver16");
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setDefaultServer(false);
config.setRegister(false);
config.setDdlGenerate(true);
@@ -104,9 +106,10 @@ public class ServerConfigSqlServerTest {
config.loadFromProperties(props);
config.getClasses().add(EBasicVer.class);
EbeanServer sqlServer = EbeanServerFactory.create(config);
Database sqlServer = DatabaseFactory.create(config);
assertThat(sqlServer).isNotNull();
sqlServer.shutdown();
}
private Properties props(String dbName) {
@@ -27,7 +27,7 @@ public class SqlServerStepSequenceTest extends BaseTestCase {
server().sqlUpdate("create sequence sqls_testseq_9876 start with 1 increment by 50").execute();
BackgroundExecutor be = server().getBackgroundExecutor();
DataSource ds = server().getPluginApi().getDataSource();
DataSource ds = server().getDataSource();
SqlServerStepSequence s = new SqlServerStepSequence(be, ds, "sqls_testseq_9876", 50);
@@ -1,11 +1,11 @@
package io.ebean.event;
import io.ebean.BaseTestCase;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.bean.BeanCollection;
import io.ebean.common.BeanList;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import org.junit.Test;
import org.tests.example.ModUuidGenerator;
import org.tests.model.basic.EBasic;
@@ -23,7 +23,7 @@ public class BeanFindControllerTest extends BaseTestCase {
@Test
public void test() {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2otherfind");
config.loadFromProperties();
@@ -40,27 +40,27 @@ public class BeanFindControllerTest extends BaseTestCase {
EBasicFindController findController = new EBasicFindController();
config.getFindControllers().add(findController);
EbeanServer ebeanServer = EbeanServerFactory.create(config);
Database db = DatabaseFactory.create(config);
assertFalse(findController.calledInterceptFind);
ebeanServer.find(EBasic.class, 42);
db.find(EBasic.class, 42);
assertTrue(findController.calledInterceptFind);
findController.findIntercept = true;
EBasic eBasic = ebeanServer.find(EBasic.class, 42);
EBasic eBasic = db.find(EBasic.class, 42);
assertEquals(Integer.valueOf(47), eBasic.getId());
assertEquals("47", eBasic.getName());
assertFalse(findController.calledInterceptFindMany);
List<EBasic> list = ebeanServer.find(EBasic.class).where().eq("name", "AnInvalidNameSoEmpty").findList();
List<EBasic> list = db.find(EBasic.class).where().eq("name", "AnInvalidNameSoEmpty").findList();
assertEquals(0, list.size());
assertTrue(findController.calledInterceptFindMany);
findController.findManyIntercept = true;
list = ebeanServer.find(EBasic.class).where().eq("name", "AnInvalidNameSoEmpty").findList();
list = db.find(EBasic.class).where().eq("name", "AnInvalidNameSoEmpty").findList();
assertEquals(1, list.size());
eBasic = list.get(0);
@@ -68,8 +68,9 @@ public class BeanFindControllerTest extends BaseTestCase {
assertEquals("47", eBasic.getName());
ECustomId bean = new ECustomId("check");
ebeanServer.save(bean);
db.save(bean);
assertNotNull(bean.getId());
db.shutdown();
}
static class EBasicFindController implements BeanFindController {
@@ -1,10 +1,10 @@
package io.ebean.event;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.Transaction;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import org.junit.Test;
import org.tests.model.basic.EBasicVer;
import org.tests.model.basic.UTDetail;
@@ -18,22 +18,22 @@ import static org.assertj.core.api.Assertions.assertThat;
public class BeanPersistControllerTest {
private PersistAdapter continuePersistingAdapter = new PersistAdapter(true);
private final PersistAdapter continuePersistingAdapter = new PersistAdapter(true);
private PersistAdapter stopPersistingAdapter = new PersistAdapter(false);
private final PersistAdapter stopPersistingAdapter = new PersistAdapter(false);
@Test
public void issue_1341() {
EbeanServer ebeanServer = getEbeanServer(continuePersistingAdapter);
Database db = getDatabase(continuePersistingAdapter);
UTMaster bean0 = new UTMaster("one0");
UTDetail detail0 = new UTDetail("detail0", 12, 23D);
bean0.getDetails().add(detail0);
ebeanServer.save(bean0);
db.save(bean0);
UTMaster master = ebeanServer.find(UTMaster.class)
UTMaster master = db.find(UTMaster.class)
.setId(bean0.getId())
.fetch("details", "name, version")
.findOne();
@@ -41,79 +41,82 @@ public class BeanPersistControllerTest {
UTDetail utDetail = master.getDetails().get(0);
utDetail.setName("detail0 mod");
Transaction txn = ebeanServer.beginTransaction();
Transaction txn = db.beginTransaction();
try {
txn.setBatchMode(true);
ebeanServer.save(master);
db.save(master);
txn.commit();
} finally {
txn.end();
}
db.shutdown();
}
@Test
public void testInsertUpdateDelete_given_continuePersistingAdapter() {
EbeanServer ebeanServer = getEbeanServer(continuePersistingAdapter);
Database db = getDatabase(continuePersistingAdapter);
EBasicVer bean = new EBasicVer("testController");
ebeanServer.save(bean);
db.save(bean);
assertThat(continuePersistingAdapter.methodsCalled).hasSize(2);
assertThat(continuePersistingAdapter.methodsCalled).containsExactly("preInsert", "postInsert");
continuePersistingAdapter.methodsCalled.clear();
bean.setName("modified");
ebeanServer.save(bean);
db.save(bean);
assertThat(continuePersistingAdapter.methodsCalled).hasSize(2);
assertThat(continuePersistingAdapter.methodsCalled).containsExactly("preUpdate", "postUpdate");
continuePersistingAdapter.methodsCalled.clear();
ebeanServer.delete(bean);
db.delete(bean);
assertThat(continuePersistingAdapter.methodsCalled).hasSize(2);
assertThat(continuePersistingAdapter.methodsCalled).containsExactly("preDelete", "postDelete");
db.shutdown();
}
@Test
public void testInsertUpdateDelete_given_stopPersistingAdapter() {
EbeanServer ebeanServer = getEbeanServer(stopPersistingAdapter);
Database db = getDatabase(stopPersistingAdapter);
EBasicVer bean = new EBasicVer("testController");
ebeanServer.save(bean);
db.save(bean);
assertThat(stopPersistingAdapter.methodsCalled).hasSize(1);
assertThat(stopPersistingAdapter.methodsCalled).containsExactly("preInsert");
stopPersistingAdapter.methodsCalled.clear();
bean.setName("modified");
ebeanServer.update(bean);
db.update(bean);
assertThat(stopPersistingAdapter.methodsCalled).hasSize(1);
assertThat(stopPersistingAdapter.methodsCalled).containsExactly("preUpdate");
stopPersistingAdapter.methodsCalled.clear();
ebeanServer.delete(bean);
db.delete(bean);
assertThat(stopPersistingAdapter.methodsCalled).hasSize(1);
assertThat(stopPersistingAdapter.methodsCalled).containsExactly("preDelete");
stopPersistingAdapter.methodsCalled.clear();
ebeanServer.delete(EBasicVer.class, 22);
db.delete(EBasicVer.class, 22);
assertThat(stopPersistingAdapter.methodsCalled).hasSize(1);
assertThat(stopPersistingAdapter.methodsCalled).containsExactly("preDeleteById");
stopPersistingAdapter.methodsCalled.clear();
ebeanServer.deleteAll(EBasicVer.class, Arrays.asList(22,23,24));
db.deleteAll(EBasicVer.class, Arrays.asList(22,23,24));
assertThat(stopPersistingAdapter.methodsCalled).hasSize(3);
assertThat(stopPersistingAdapter.methodsCalled).containsExactly("preDeleteById", "preDeleteById", "preDeleteById");
stopPersistingAdapter.methodsCalled.clear();
db.shutdown();
}
private EbeanServer getEbeanServer(PersistAdapter persistAdapter) {
private Database getDatabase(PersistAdapter persistAdapter) {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2ebasicver");
config.loadFromProperties();
config.setDdlGenerate(true);
@@ -128,7 +131,7 @@ public class BeanPersistControllerTest {
config.add(persistAdapter);
return EbeanServerFactory.create(config);
return DatabaseFactory.create(config);
}
static class PersistAdapter extends BeanPersistAdapter {
@@ -3,12 +3,12 @@ package io.ebean.event;
import io.ebean.BaseTestCase;
import io.ebean.BeanState;
import io.ebean.Ebean;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.config.ServerConfig;
import org.tests.model.basic.EBasicVer;
import io.ebean.DB;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.config.DatabaseConfig;
import org.junit.Test;
import org.tests.model.basic.EBasicVer;
import java.util.ArrayList;
import java.util.List;
@@ -22,15 +22,15 @@ public class BeanPostLoadTest extends BaseTestCase {
@Test
public void testPostLoad() {
EbeanServer ebeanServer = getEbeanServer();
Database db = createDatabase();
EBasicVer bean = new EBasicVer("testPostLoad");
bean.setDescription("someDescription");
bean.setOther("other");
ebeanServer.save(bean);
db.save(bean);
EBasicVer found = ebeanServer.find(EBasicVer.class)
EBasicVer found = db.find(EBasicVer.class)
.select("name, other")
.setId(bean.getId())
.findOne();
@@ -40,13 +40,14 @@ public class BeanPostLoadTest extends BaseTestCase {
assertThat(postLoad.beanState.getLoadedProps()).containsExactly("id", "name", "other");
assertThat(postLoad.bean).isSameAs(found);
ebeanServer.delete(bean);
db.delete(bean);
db.shutdown();
}
private EbeanServer getEbeanServer() {
private Database createDatabase() {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2ebasicver");
config.loadFromProperties();
@@ -60,7 +61,7 @@ public class BeanPostLoadTest extends BaseTestCase {
config.add(postLoad);
return EbeanServerFactory.create(config);
return DatabaseFactory.create(config);
}
static class PostLoad implements BeanPostLoad {
@@ -90,7 +91,7 @@ public class BeanPostLoadTest extends BaseTestCase {
public void postLoad(Object bean) {
this.methodsCalled.add("postLoad");
this.bean = bean;
this.beanState = Ebean.getBeanState(bean);
this.beanState = DB.getBeanState(bean);
}
}
@@ -53,6 +53,7 @@ import io.ebeaninternal.server.transaction.RemoteTransactionEvent;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import javax.sql.DataSource;
import java.lang.reflect.Type;
import java.time.Clock;
import java.util.Collection;
@@ -336,6 +337,16 @@ public class TDSpiEbeanServer implements SpiEbeanServer {
return null;
}
@Override
public DataSource getDataSource() {
return null;
}
@Override
public DataSource getReadOnlyDataSource() {
return null;
}
@Override
public String getName() {
return name;
@@ -26,10 +26,13 @@ public class BeanDescriptor_registerTest {
config.getClasses().add(EBasic.class);
SpiEbeanServer ebeanServer = (SpiEbeanServer)DatabaseFactory.create(config);
BeanDescriptor<EBasic> desc = ebeanServer.getBeanDescriptor(EBasic.class);
persistListenerRegistrationTests(desc);
persistControllerRegistrationTests(desc);
try {
BeanDescriptor<EBasic> desc = ebeanServer.getBeanDescriptor(EBasic.class);
persistListenerRegistrationTests(desc);
persistControllerRegistrationTests(desc);
} finally {
ebeanServer.shutdown();
}
}
private void persistControllerRegistrationTests(BeanDescriptor<EBasic> desc) {
@@ -258,7 +258,7 @@ public class TestRawSqlBuilder extends BaseTestCase {
"join o_customer c on o.kcustomer_id = c.id " +
"where c.id = ? and o.id > ?";
final DataSource dataSource = DB.getDefault().getPluginApi().getDataSource();
final DataSource dataSource = DB.getDefault().getDataSource();
try (Connection connection = dataSource.getConnection()) {
try (PreparedStatement stmt = connection.prepareStatement(sql)) {
@@ -4,7 +4,6 @@ import io.ebean.BaseTestCase;
import io.ebean.DB;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.Ebean;
import io.ebean.Transaction;
import io.ebean.annotation.ForPlatform;
import io.ebean.annotation.Platform;
@@ -25,7 +24,7 @@ public class DefaultTransactionThreadLocalTest extends BaseTestCase {
@ForPlatform({Platform.H2})
@Test
public void get() {
Ebean.execute(() -> {
DB.execute(() -> {
SpiTransaction txn = getInScopeTransaction();
assertNotNull(txn);
});
@@ -38,12 +37,12 @@ public class DefaultTransactionThreadLocalTest extends BaseTestCase {
@Test
public void tryWithResources_expect_scopeCleanup() {
try (Transaction transaction = Ebean.beginTransaction()) {
try (Transaction transaction = DB.beginTransaction()) {
assertNotNull(transaction);
SpiTransaction txn = getInScopeTransaction();
assertSame(txn, transaction);
try (Transaction nested = Ebean.beginTransaction()) {
try (Transaction nested = DB.beginTransaction()) {
assertNotNull(nested);
SpiTransaction txnNested = getInScopeTransaction();
assertSame(txnNested, nested);
@@ -59,7 +58,7 @@ public class DefaultTransactionThreadLocalTest extends BaseTestCase {
@Test
public void afterCommit_expect_scopeCleanup() {
try (Transaction transaction = Ebean.beginTransaction()) {
try (Transaction transaction = DB.beginTransaction()) {
transaction.commit();
assertNull(getInScopeTransaction());
}
@@ -70,7 +69,7 @@ public class DefaultTransactionThreadLocalTest extends BaseTestCase {
@Test
public void afterRollback_expect_scopeCleanup() {
try (Transaction transaction = Ebean.beginTransaction()) {
try (Transaction transaction = DB.beginTransaction()) {
transaction.rollback();
assertNull(getInScopeTransaction());
@@ -82,8 +81,8 @@ public class DefaultTransactionThreadLocalTest extends BaseTestCase {
@Test
public void end_withoutActiveTransaction_isFine() {
assertNull(Ebean.currentTransaction());
Ebean.endTransaction();
assertNull(DB.currentTransaction());
DB.endTransaction();
}
@ForPlatform({Platform.H2})
@@ -106,28 +105,31 @@ public class DefaultTransactionThreadLocalTest extends BaseTestCase {
@ForPlatform(Platform.H2)
@Test
public void usingDatabase() {
// setup
Database otherDb = createOtherDatabase();
EBasicVer bean = new EBasicVer("TestUsingDatabase");
otherDb.save(bean);
try {
EBasicVer bean = new EBasicVer("TestUsingDatabase");
otherDb.save(bean);
// act
final EBasicVer foundOtherDb = DB.find(EBasicVer.class)
.usingDatabase(otherDb)
.where().eq("name", "TestUsingDatabase")
.findOne();
// act
final EBasicVer foundOtherDb = DB.find(EBasicVer.class)
.usingDatabase(otherDb)
.where().eq("name", "TestUsingDatabase")
.findOne();
assertNotNull(foundOtherDb);
assertThat(foundOtherDb.getId()).isEqualTo(bean.getId());
assertNotNull(foundOtherDb);
assertThat(foundOtherDb.getId()).isEqualTo(bean.getId());
final EBasicVer foundDefaultDb = DB.find(EBasicVer.class)
.where().eq("name", "TestUsingDatabase")
.findOne();
final EBasicVer foundDefaultDb = DB.find(EBasicVer.class)
.where().eq("name", "TestUsingDatabase")
.findOne();
assertNull(foundDefaultDb);
assertNull(foundDefaultDb);
otherDb.delete(bean);
otherDb.delete(bean);
} finally {
otherDb.shutdown();
}
}
+1 -1
View File
@@ -15,7 +15,7 @@ public class Main {
EbeanServer ms = Ebean.getServer("ms");
DataSource dataSource = ms.getPluginApi().getDataSource();
DataSource dataSource = ms.getDataSource();
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement("select next VALUE for j2_seq");
@@ -1,11 +1,11 @@
package org;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.Transaction;
import io.ebean.annotation.Cache;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.PlatformNoGeneratedKeysTest;
import io.ebean.config.ServerConfig;
import javax.persistence.Entity;
import javax.persistence.Id;
@@ -40,13 +40,13 @@ public class MainMemoryLeak {
PlatformNoGeneratedKeysTest.OtherH2Platform platform = new PlatformNoGeneratedKeysTest.OtherH2Platform();
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setDatabasePlatform(platform);
config.addClass(ECachedBean.class);
config.loadFromProperties();
EbeanServer server = EbeanServerFactory.create(config);
Database server = DatabaseFactory.create(config);
// create a string with 10k chars
char[] c = new char[10_000];
@@ -70,6 +70,6 @@ public class MainMemoryLeak {
System.out.println("Success, no mem limit detected");
txn.commit();
}
server.shutdown();
}
}
@@ -1,11 +1,12 @@
package org.multitenant.partition;
import io.ebean.BaseTestCase;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.config.ServerConfig;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.TenantMode;
import org.ebeantest.LoggedSqlCollector;
import org.junit.AfterClass;
import org.junit.Test;
import java.util.ArrayList;
@@ -16,7 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class MultiTenantPartitionTest extends BaseTestCase {
private static String[] names = {"Ace", "Base", "Case", "Dae", "Eva"};
private static final String[] names = {"Ace", "Base", "Case", "Dae", "Eva"};
static List<MtTenant> tenants() {
List<MtTenant> tenants = new ArrayList<>();
@@ -26,12 +27,16 @@ public class MultiTenantPartitionTest extends BaseTestCase {
return tenants;
}
private static EbeanServer server = init();
private static final Database server = init();
static {
server.saveAll(tenants());
}
@AfterClass
public static void shutdown() {
server.shutdown();
}
@Test
public void start() {
@@ -103,9 +108,9 @@ public class MultiTenantPartitionTest extends BaseTestCase {
}
private static EbeanServer init() {
private static Database init() {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2multitenant");
config.loadFromProperties();
@@ -120,6 +125,6 @@ public class MultiTenantPartitionTest extends BaseTestCase {
config.getClasses().add(MtTenant.class);
config.getClasses().add(MtContent.class);
return EbeanServerFactory.create(config);
return DatabaseFactory.create(config);
}
}
@@ -24,7 +24,7 @@ public class TestQueryUsingConnection extends BaseTestCase {
ResetBasicData.reset();
DataSource dataSource = DB.getDefault().getPluginApi().getDataSource();
DataSource dataSource = DB.getDefault().getDataSource();
try (Connection connection = dataSource.getConnection()) {
@@ -2,6 +2,7 @@ package org.tests.basic;
import io.ebean.DB;
import io.ebean.Database;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.tests.model.basic.ESimple;
@@ -22,6 +23,11 @@ public class TestQueryUsingDatabase {
DB.byName(SOME_OTHER_DB_NAME).insert(RECORD2);
}
@After
public void shutdown() {
DB.byName(SOME_OTHER_DB_NAME).shutdown();
}
@Test
public void usingNonDefaultDatabase() {
final Database nonDefaultDb = DB.byName(SOME_OTHER_DB_NAME);
@@ -3,9 +3,10 @@ package org.tests.changelog;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.ebean.BaseTestCase;
import io.ebean.EbeanServerFactory;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.annotation.ChangeLog;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.event.BeanPersistRequest;
import io.ebean.event.changelog.BeanChange;
import io.ebean.event.changelog.ChangeLogFilter;
@@ -14,7 +15,6 @@ import io.ebean.event.changelog.ChangeLogPrepare;
import io.ebean.event.changelog.ChangeLogRegister;
import io.ebean.event.changelog.ChangeSet;
import io.ebean.event.changelog.ChangeType;
import io.ebeaninternal.api.SpiEbeanServer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -31,16 +31,16 @@ public class TestChangeLog extends BaseTestCase {
TDChangeLogRegister changeLogRegister = new TDChangeLogRegister();
SpiEbeanServer server;
Database server;
@Before
public void setup() {
server = getServer();
server = createServer();
}
@After
public void shutdown() {
server.shutdown(true, false);
server.shutdown();
}
@Test
@@ -65,7 +65,7 @@ public class TestChangeLog extends BaseTestCase {
assertThat(change.getEvent()).isEqualTo(ChangeType.UPDATE);
assertThat(change.getOldData()).contains("\"name\":\"logBean\"");
assertThat(change.getData()) .contains("\"name\":\"ChangedName\"");
assertThat(change.getData()).contains("\"name\":\"ChangedName\"");
server.delete(bean);
@@ -120,31 +120,27 @@ public class TestChangeLog extends BaseTestCase {
}
private Database createServer() {
private SpiEbeanServer getServer() {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2other");
config.loadFromProperties();
config.setDdlGenerate(true);
config.setDdlRun(true);
config.setDdlExtra(false);
config.setDefaultServer(false);
config.setRegister(false);
config.setChangeLogAsync(false);
config.addClass(EBasicChangeLog.class);
config.setChangeLogPrepare(changeLogPrepare);
config.setChangeLogListener(changeLogListener);
config.setChangeLogRegister(changeLogRegister);
return (SpiEbeanServer) EbeanServerFactory.create(config);
return DatabaseFactory.create(config);
}
class TDChangeLogPrepare implements ChangeLogPrepare {
public static class TDChangeLogPrepare implements ChangeLogPrepare {
@Override
public boolean prepare(ChangeSet changes) {
changes.setUserId("appUser1");
@@ -153,14 +149,12 @@ public class TestChangeLog extends BaseTestCase {
}
}
class TDChangeLogListener implements ChangeLogListener {
public static class TDChangeLogListener implements ChangeLogListener {
ObjectMapper objectMapper = new ObjectMapper();
ChangeSet changes;
/**
*/
public TDChangeLogListener() {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
@@ -184,7 +178,7 @@ public class TestChangeLog extends BaseTestCase {
}
class TDChangeLogRegister implements ChangeLogRegister {
public static class TDChangeLogRegister implements ChangeLogRegister {
@Override
public ChangeLogFilter getChangeFilter(Class<?> beanType) {
@@ -198,11 +192,10 @@ public class TestChangeLog extends BaseTestCase {
}
}
/**
* Change log filter that includes all the inserts, updates and deletes.
*/
class TDFilter implements ChangeLogFilter {
public static class TDFilter implements ChangeLogFilter {
/**
* Returns true including all the inserts.
@@ -1,27 +0,0 @@
package org.tests.ddl;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.config.ServerConfig;
import org.tests.model.basic.EBasic;
public class MainDdlWithSchema {
public static void main(String[] args) {
ServerConfig cfg = new ServerConfig();
cfg.setName("h2");
cfg.loadFromProperties();
cfg.addClass(EBasic.class);
// .... other settings ...
//UnderscoreNamingConvention naming = new UnderscoreNamingConvention();
//naming.setSchema("test");
//cfg.setNamingConvention(naming);
cfg.setDdlGenerate(true);
cfg.setDdlRun(true);
EbeanServer ebean = EbeanServerFactory.create(cfg);
//ebean.createSqlUpdate("create schema foo").execute();
System.out.println(ebean);
}
}
@@ -30,7 +30,7 @@ public class TestCacheViaComplexNaturalKey extends BaseTestCase {
return server().getServerCacheManager();
}
private static synchronized void insertSome() {
private static void insertSome() {
if (!loadOnce) {
Ebean.find(OCachedNatKeyBean.class).delete();
for (String store : Arrays.asList("abc", "def")) {
@@ -28,7 +28,7 @@ public class TestCacheViaComplexNaturalKey3 extends BaseTestCase {
return server().getServerCacheManager();
}
private static synchronized void insertSome() {
private static void insertSome() {
if (!loadOnce) {
Ebean.find(OCachedNatKeyBean3.class).delete();
@@ -1,16 +1,16 @@
package org.tests.persistencecontext;
import io.ebean.BaseTestCase;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.PersistenceContextScope;
import io.ebean.Query;
import io.ebean.config.ContainerConfig;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import org.tests.model.basic.EBasicVer;
import org.junit.Test;
import org.tests.model.basic.EBasicVer;
import java.util.Properties;
@@ -20,20 +20,20 @@ public class TestPersistenceContextServerConfig extends BaseTestCase {
@Test
public void test_config() {
SpiEbeanServer ebeanServer = (SpiEbeanServer) create();
try {
Query<EBasicVer> query = ebeanServer.find(EBasicVer.class);
PersistenceContextScope scope = ebeanServer.getPersistenceContextScope((SpiQuery<?>) query);
Query<EBasicVer> query = ebeanServer.find(EBasicVer.class);
PersistenceContextScope scope = ebeanServer.getPersistenceContextScope((SpiQuery<?>) query);
assertEquals(PersistenceContextScope.QUERY, scope);
assertEquals(PersistenceContextScope.QUERY, scope);
} finally {
ebeanServer.shutdown();
}
}
static EbeanServer create() {
static Database create() {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("withPCQuery");
config.setDdlExtra(false);
@@ -49,15 +49,7 @@ public class TestPersistenceContextServerConfig extends BaseTestCase {
config.setDefaultServer(false);
config.setRegister(false);
// DataSourceConfig dataSourceConfig = new DataSourceConfig();
// dataSourceConfig.setUsername("sa");
// dataSourceConfig.setPassword("");
// dataSourceConfig.setUrl("jdbc:h2:mem:withPCQuery;");
// dataSourceConfig.setDriver("org.h2.Driver");
// config.setDataSourceConfig(dataSourceConfig);
config.addClass(EBasicVer.class);
return EbeanServerFactory.create(config);
return DatabaseFactory.create(config);
}
}
@@ -235,7 +235,7 @@ public class TestQueryFindIterate extends BaseTestCase {
SpiServer pluginApi = server().getPluginApi();
DataSourcePool dsPool = (DataSourcePool) pluginApi.getServerConfig().getReadOnlyDataSource();
if (dsPool == null) {
dsPool = (DataSourcePool) server().getPluginApi().getDataSource();
dsPool = (DataSourcePool) server().getDataSource();
}
int startConns = dsPool.getStatus(false).getBusy();
@@ -5,9 +5,9 @@ import io.ebean.Ebean;
import io.ebean.Query;
import io.ebean.annotation.Platform;
import io.ebean.plugin.SpiServer;
import org.junit.Test;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
@@ -38,7 +38,7 @@ public class TestNativeILikeExpression extends BaseTestCase {
SpiServer pluginApi = server().getPluginApi();
boolean expressionNativeIlike = pluginApi.getServerConfig().isExpressionNativeIlike();
Platform platform = pluginApi.getDatabasePlatform().getPlatform();
Platform platform = pluginApi.getPlatform().base();
return expressionNativeIlike && platform == Platform.POSTGRES;
}
@@ -1,22 +1,22 @@
package org.tests.readaudit;
import io.ebean.BaseTestCase;
import io.ebean.EbeanServerFactory;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.FutureList;
import io.ebean.cache.ServerCache;
import io.ebean.cache.ServerCacheStatistics;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
import io.ebean.event.readaudit.ReadAuditQueryPlan;
import io.ebean.event.readaudit.ReadEvent;
import io.ebeaninternal.api.SpiEbeanServer;
import org.tests.model.basic.Country;
import org.tests.model.basic.EBasicChangeLog;
import org.ebeantest.LoggedSqlCollector;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.tests.model.basic.Country;
import org.tests.model.basic.EBasicChangeLog;
import java.util.ArrayList;
import java.util.HashSet;
@@ -30,18 +30,18 @@ import static org.assertj.core.api.Assertions.assertThat;
public class TestReadAudit extends BaseTestCase {
TDReadAuditPrepare readAuditPrepare = new TDReadAuditPrepare(true);
TDReadAuditPrepare readAuditPrepare = new TDReadAuditPrepare();
TDReadAuditLogger readAuditLogger = new TDReadAuditLogger(true);
TDReadAuditLogger readAuditLogger = new TDReadAuditLogger();
SpiEbeanServer server;
Database server;
Long id1;
Long id2;
@Before
public void setup() {
server = getServer();
server = createServer();
EBasicChangeLog bean = new EBasicChangeLog();
bean.setName("readAudito1");
@@ -63,7 +63,7 @@ public class TestReadAudit extends BaseTestCase {
@After
public void shutdown() {
server.shutdown(true, false);
server.shutdown();
}
@Test
@@ -304,9 +304,9 @@ public class TestReadAudit extends BaseTestCase {
assertThat(readAuditLogger.many).hasSize(2);
}
private SpiEbeanServer getServer() {
private Database createServer() {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2other");
config.loadFromProperties();
@@ -323,7 +323,7 @@ public class TestReadAudit extends BaseTestCase {
config.setReadAuditLogger(readAuditLogger);
config.setReadAuditPrepare(readAuditPrepare);
return (SpiEbeanServer) EbeanServerFactory.create(config);
return DatabaseFactory.create(config);
}
private void resetCounters() {
@@ -331,13 +331,10 @@ public class TestReadAudit extends BaseTestCase {
readAuditPrepare.resetCounters();
}
class TDReadAuditPrepare implements ReadAuditPrepare {
static class TDReadAuditPrepare implements ReadAuditPrepare {
int count;
TDReadAuditPrepare(boolean dummy) {
}
void resetCounters() {
count = 0;
}
@@ -351,15 +348,12 @@ public class TestReadAudit extends BaseTestCase {
}
}
class TDReadAuditLogger implements ReadAuditLogger {
static class TDReadAuditLogger implements ReadAuditLogger {
Set<ReadAuditQueryPlan> plans = new HashSet<>();
List<ReadEvent> beans = new ArrayList<>();
List<ReadEvent> many = new ArrayList<>();
TDReadAuditLogger(boolean dummy) {
}
void resetCounters() {
plans.clear();
beans.clear();
@@ -72,7 +72,7 @@ datasource.db.databaseDriver=org.h2.Driver
datasource.h2.username=sa
datasource.h2.password=
datasource.h2.url=jdbc:h2:mem:tests
datasource.h2.url=jdbc:h2:mem:testsMem;DB_CLOSE_ON_EXIT=FALSE
#datasource.h2.driver=org.h2.Driver
datasource.h2.minConnections=1
datasource.h2.maxConnections=25
@@ -86,7 +86,7 @@ datasource.h2.poolListener=org.tests.basic.MyTestDataSourcePoolListener
datasource.h2multitenant.username=sa
datasource.h2multitenant.password=
datasource.h2multitenant.url=jdbc:h2:mem:h2multitenant
datasource.h2multitenant.url=jdbc:h2:mem:h2multitenant;DB_CLOSE_ON_EXIT=FALSE
datasource.h2autocommit.autoCommit=true
datasource.h2autocommit.username=sa
@@ -100,11 +100,11 @@ datasource.h2autocommit2.url=jdbc:h2:mem:autocommit2tests
datasource.h2other.username=sa
datasource.h2other.password=
datasource.h2other.url=jdbc:h2:mem:h2other
datasource.h2other.url=jdbc:h2:mem:h2other;DB_CLOSE_ON_EXIT=FALSE
datasource.h2otherfind.username=sa
datasource.h2otherfind.password=
datasource.h2otherfind.url=jdbc:h2:mem:h2otherfind
datasource.h2otherfind.url=jdbc:h2:mem:h2otherfind;DB_CLOSE_ON_EXIT=FALSE
datasource.h2ebasicver.username=sa
datasource.h2ebasicver.password=
+6 -5
View File
@@ -1,21 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.5.0</version>
<version>12.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<name>ebean ddl generation</name>
<description>DDL and DB Migration generation</description>
<artifactId>ebean-ddlgen</artifactId>
<!-- <version>12.4.1</version>-->
<dependencies>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
</dependency>
<!-- needed for java 11+ -->
@@ -48,7 +49,7 @@
<plugin>
<groupId>io.ebean</groupId>
<artifactId>ebean-maven-plugin</artifactId>
<version>12.4.2</version>
<version>12.5.0</version>
<executions>
<execution>
<id>test</id>
@@ -142,7 +142,7 @@ public class DdlGenerator implements SpiDdlGenerator {
private Connection obtainConnection() {
try {
return server.getPluginApi().getDataSource().getConnection();
return server.getDataSource().getConnection();
} catch (SQLException e) {
throw new PersistenceException("Failed to obtain connection to run DDL", e);
}
@@ -562,7 +562,7 @@ public class PlatformDdl {
/**
* Return true if unique constraints for nullable columns can be inlined as normal.
* Returns false for MsSqlServer & DB2 due to it's not possible to to put a constraint
* Returns false for MsSqlServer and DB2 due to it's not possible to to put a constraint
* on a nullable column
*/
public boolean isInlineUniqueWhenNullable() {
@@ -10,7 +10,7 @@ import io.ebeaninternal.dbmigration.model.MTable;
import java.io.IOException;
/**
* @author Vilmos Nagy <vilmos.nagy@outlook.com>
* @author Vilmos Nagy
*/
public class SqlServerHistoryDdl implements PlatformHistoryDdl {
@@ -1,8 +1,8 @@
package io.ebeaninternal.dbmigration;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.config.ServerConfig;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.config.DatabaseConfig;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,7 +42,7 @@ public class DbMigrationDropHistoryTest {
migration.setPathToResources("src/test/resources");
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("migrationtest-history");
config.loadFromProperties();
config.setRegister(false);
@@ -50,7 +50,7 @@ public class DbMigrationDropHistoryTest {
config.setPackages(Arrays.asList("misc.migration.history.v1_0"));
EbeanServer server = EbeanServerFactory.create(config);
Database server = DatabaseFactory.create(config);
migration.setServer(server);
// First, we clean up the output-directory
@@ -65,7 +65,8 @@ public class DbMigrationDropHistoryTest {
// and now for v1_1
config.setPackages(Arrays.asList("misc.migration.history.v1_1"));
server = EbeanServerFactory.create(config);
server.shutdown();
server = DatabaseFactory.create(config);
migration.setServer(server);
assertThat(migration.generateMigration()).isEqualTo("1.1");
assertThat(migration.generateMigration()).isNull(); // subsequent call
@@ -82,6 +83,7 @@ public class DbMigrationDropHistoryTest {
.hasMessageContaining("No 'pendingDrops'"); // subsequent call
System.clearProperty("ddl.migration.pendingDropsFor");
server.shutdown();
logger.info("end");
}
@@ -1,9 +1,9 @@
package io.ebeaninternal.dbmigration;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.annotation.Platform;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -57,7 +57,7 @@ public class DbMigrationGenerateTest {
migration.addPlatform(Platform.SQLSERVER17, "sqlserver17");
migration.addPlatform(Platform.HANA, "hana");
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("migrationtest");
config.loadFromProperties();
config.setRegister(false);
@@ -66,7 +66,7 @@ public class DbMigrationGenerateTest {
config.setPackages(Arrays.asList("misc.migration.v1_0"));
EbeanServer server = EbeanServerFactory.create(config);
Database server = DatabaseFactory.create(config);
migration.setServer(server);
// First, we clean up the output-directory
@@ -81,7 +81,8 @@ public class DbMigrationGenerateTest {
// and now for v1_1
config.setPackages(Arrays.asList("misc.migration.v1_1"));
server = EbeanServerFactory.create(config);
server.shutdown();
server = DatabaseFactory.create(config);
migration.setServer(server);
assertThat(migration.generateMigration()).isEqualTo("1.1");
assertThat(migration.generateMigration()).isNull(); // subsequent call
@@ -100,7 +101,8 @@ public class DbMigrationGenerateTest {
// and now for v1_2 with
config.setPackages(Arrays.asList("misc.migration.v1_2"));
server = EbeanServerFactory.create(config);
server.shutdown();
server = DatabaseFactory.create(config);
migration.setServer(server);
assertThat(migration.generateMigration()).isEqualTo("1.3");
assertThat(migration.generateMigration()).isNull(); // subsequent call
@@ -108,13 +110,14 @@ public class DbMigrationGenerateTest {
System.setProperty("ddl.migration.pendingDropsFor", "1.3");
assertThat(migration.generateMigration()).isEqualTo("1.4__dropsFor_1.3");
assertThatThrownBy(()->migration.generateMigration())
assertThatThrownBy(migration::generateMigration)
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("No 'pendingDrops'"); // subsequent call
System.clearProperty("ddl.migration.pendingDropsFor");
assertThat(migration.generateMigration()).isNull(); // subsequent call
server.shutdown();
logger.info("end");
}
@@ -16,7 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class DbMigrationTest extends BaseTestCase {
private void runScript(boolean expectErrors, String scriptName) throws IOException {
String ddl = Helper.asText(this, "/dbmigration/migrationtest/" + server().getPluginApi().getDatabasePlatform().getName()+"/" + scriptName);
String ddl = Helper.asText(this, "/dbmigration/migrationtest/" + server().getPlatform().name().toLowerCase() + "/" + scriptName);
runScript(expectErrors, ddl, scriptName);
}
@@ -73,27 +73,28 @@ public class ModelBuildBeanVisitorTest extends BaseTestCase {
config.setDatabasePlatform(new SqlServer17Platform());
final SpiEbeanServer database = (SpiEbeanServer)DatabaseFactory.create(config);
try {
ModelBuildContext ctx = new ModelBuildContext(model, config.getDatabasePlatform(), config.getConstraintNaming(), true);
ModelBuildBeanVisitor addTable = new ModelBuildBeanVisitor(ctx);
ModelBuildContext ctx = new ModelBuildContext(model, config.getDatabasePlatform(), config.getConstraintNaming(), true);
new VisitAllUsing(addTable, database).visitAllBeans();
ModelBuildBeanVisitor addTable = new ModelBuildBeanVisitor(ctx);
MTable parent = model.getTable("[CKeyParent]");
assertThat(parent.getPkName()).isEqualTo("[pk_CKeyParent]");
new VisitAllUsing(addTable, database).visitAllBeans();
MTable detail = model.getTable("[CKeyDetail]");
assertThat(detail.getPkName()).isEqualTo("[pk_CKeyDetail]");
MTable parent = model.getTable("[CKeyParent]");
assertThat(parent.getPkName()).isEqualTo("[pk_CKeyParent]");
final List<MCompoundForeignKey> compoundKeys = detail.getCompoundKeys();
assertThat(compoundKeys).hasSize(1);
final MCompoundForeignKey fkey = compoundKeys.get(0);
assertThat(fkey.getName()).isEqualTo("[fk_CKeyDetail_parent]");
assertThat(fkey.getIndexName()).isEqualTo("[ix_CKeyDetail_parent]");
MTable detail = model.getTable("[CKeyDetail]");
assertThat(detail.getPkName()).isEqualTo("[pk_CKeyDetail]");
final List<MCompoundForeignKey> compoundKeys = detail.getCompoundKeys();
assertThat(compoundKeys).hasSize(1);
final MCompoundForeignKey fkey = compoundKeys.get(0);
assertThat(fkey.getName()).isEqualTo("[fk_CKeyDetail_parent]");
assertThat(fkey.getIndexName()).isEqualTo("[ix_CKeyDetail_parent]");
database.shutdown(true, false);
} finally {
database.shutdown();
}
}
private void assert_compound_pk(ModelContainer model) {
@@ -2,20 +2,20 @@ package io.ebeaninternal.dbmigration.model.build;
import io.ebean.BaseTestCase;
import io.ebean.EbeanServerFactory;
import io.ebean.config.ServerConfig;
import io.ebean.DatabaseFactory;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.dbmigration.ddlgeneration.Helper;
import io.ebeaninternal.dbmigration.migration.Migration;
import io.ebeaninternal.dbmigration.migrationreader.MigrationXmlReader;
import io.ebeaninternal.dbmigration.model.CurrentModel;
import io.ebeaninternal.dbmigration.model.MTable;
import io.ebeaninternal.dbmigration.model.ModelContainer;
import io.ebeaninternal.api.SpiEbeanServer;
import org.junit.Test;
import org.tests.model.basic.CKeyAssoc;
import org.tests.model.basic.CKeyDetail;
import org.tests.model.basic.CKeyParent;
import org.tests.model.basic.CKeyParentId;
import org.junit.Test;
import java.io.IOException;
@@ -23,9 +23,9 @@ import static org.assertj.core.api.Assertions.assertThat;
public class ModelBuild_compoundKeyTest extends BaseTestCase {
private SpiEbeanServer getServer() {
private SpiEbeanServer createServer() {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2");
config.loadFromProperties();
config.setName("h2other");
@@ -40,46 +40,49 @@ public class ModelBuild_compoundKeyTest extends BaseTestCase {
config.addClass(CKeyAssoc.class);
config.addClass(CKeyParentId.class);
return (SpiEbeanServer) EbeanServerFactory.create(config);
return (SpiEbeanServer) DatabaseFactory.create(config);
}
@Test
public void test() throws IOException {
SpiEbeanServer ebeanServer = createServer();
try {
CurrentModel currentModel = new CurrentModel(ebeanServer);
ModelContainer model = currentModel.read();
SpiEbeanServer ebeanServer = getServer();
MTable parent = model.getTable("ckey_parent");
MTable detail = model.getTable("ckey_detail");
CurrentModel currentModel = new CurrentModel(ebeanServer);
ModelContainer model = currentModel.read();
assertThat(parent).isNotNull();
assertThat(detail).isNotNull();
assertThat(parent.primaryKeyColumns()).hasSize(2);
assertThat(detail.getCompoundKeys()).hasSize(1);
MTable parent = model.getTable("ckey_parent");
MTable detail = model.getTable("ckey_detail");
String apply = Helper.asText(this, "/assert/ModelBuild_compoundKeyTest/apply.sql");
assertThat(parent).isNotNull();
assertThat(detail).isNotNull();
assertThat(parent.primaryKeyColumns()).hasSize(2);
assertThat(detail.getCompoundKeys()).hasSize(1);
String apply = Helper.asText(this, "/assert/ModelBuild_compoundKeyTest/apply.sql");
String createDdl = currentModel.getCreateDdl();
assertThat(createDdl).startsWith("-- Generated by ebean").endsWith(apply);
String createDdl = currentModel.getCreateDdl();
assertThat(createDdl).startsWith("-- Generated by ebean").endsWith(apply);
} finally {
ebeanServer.shutdown();
}
}
@Test
public void testFromMigration() throws IOException {
Migration migration = MigrationXmlReader.read("/container/test-compoundkey.xml");
SpiEbeanServer ebeanServer = createServer();
try {
CurrentModel currentModel = new CurrentModel(ebeanServer);
currentModel.setChangeSet(migration.getChangeSet().get(0));
SpiEbeanServer ebeanServer = getServer();
CurrentModel currentModel = new CurrentModel(ebeanServer);
currentModel.setChangeSet(migration.getChangeSet().get(0));
String createDdl = currentModel.getCreateDdl();
String apply = Helper.asText(this, "/assert/ModelBuild_compoundKeyTest/apply.sql");
String createDdl = currentModel.getCreateDdl();
String apply = Helper.asText(this, "/assert/ModelBuild_compoundKeyTest/apply.sql");
assertThat(createDdl).startsWith("-- Generated by ebean").endsWith(apply);
assertThat(createDdl).startsWith("-- Generated by ebean").endsWith(apply);
} finally {
ebeanServer.shutdown();
}
}
}
@@ -2,15 +2,15 @@ package io.ebeaninternal.dbmigration.model.build;
import io.ebean.BaseTestCase;
import io.ebean.EbeanServerFactory;
import io.ebean.config.ServerConfig;
import io.ebean.DatabaseFactory;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlOptions;
import io.ebeaninternal.dbmigration.ddlgeneration.Helper;
import io.ebeaninternal.dbmigration.model.CurrentModel;
import io.ebeaninternal.api.SpiEbeanServer;
import org.junit.Test;
import org.tests.model.basic.Person;
import org.tests.model.basic.Phone;
import org.junit.Test;
import java.io.IOException;
@@ -18,9 +18,9 @@ import static org.assertj.core.api.Assertions.assertThat;
public class ModelBuild_explicitSequencesTest extends BaseTestCase {
private SpiEbeanServer getServer(boolean postgres) {
private SpiEbeanServer createServer(boolean postgres) {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName("h2");
config.loadFromProperties();
config.setName("h2other");
@@ -34,35 +34,40 @@ public class ModelBuild_explicitSequencesTest extends BaseTestCase {
config.addClass(Person.class);
config.addClass(Phone.class);
return (SpiEbeanServer) EbeanServerFactory.create(config);
return (SpiEbeanServer) DatabaseFactory.create(config);
}
@Test
public void test() throws IOException {
SpiEbeanServer ebeanServer = createServer(false);
try {
CurrentModel currentModel = new CurrentModel(ebeanServer);
SpiEbeanServer ebeanServer = getServer(false);
CurrentModel currentModel = new CurrentModel(ebeanServer);
String apply = currentModel.getCreateDdl();
assertThat(apply)
.startsWith("-- Generated by ebean")
.endsWith(Helper.asText(this, "/assert/ModelBuild_explicitSequencesTest/apply.sql"));
String apply = currentModel.getCreateDdl();
assertThat(apply)
.startsWith("-- Generated by ebean")
.endsWith(Helper.asText(this, "/assert/ModelBuild_explicitSequencesTest/apply.sql"));
} finally {
ebeanServer.shutdown();
}
}
@Test
public void test_asPostgres() throws IOException {
SpiEbeanServer ebeanServer = createServer(true);
try {
CurrentModel currentModel = new CurrentModel(ebeanServer);
final DdlOptions ddlOptions = currentModel.getDdlOptions();
ddlOptions.setForeignKeySkipCheck(true);
SpiEbeanServer ebeanServer = getServer(true);
CurrentModel currentModel = new CurrentModel(ebeanServer);
final DdlOptions ddlOptions = currentModel.getDdlOptions();
ddlOptions.setForeignKeySkipCheck(true);
String apply = currentModel.getCreateDdl();
assertThat(apply)
.startsWith("-- Generated by ebean")
.endsWith(Helper.asText(this, "/assert/ModelBuild_explicitSequencesTest/pg-apply.sql"));
String apply = currentModel.getCreateDdl();
assertThat(apply)
.startsWith("-- Generated by ebean")
.endsWith(Helper.asText(this, "/assert/ModelBuild_explicitSequencesTest/pg-apply.sql"));
} finally {
ebeanServer.shutdown();
}
}
}
+4 -2
View File
@@ -1,12 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.5.0</version>
<version>12.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<name>ebean external mapping api</name>
<description>API for mapping external named queries</description>
<artifactId>ebean-externalmapping-api</artifactId>
<build>
+33 -7
View File
@@ -1,20 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>12.5.0</version>
<version>12.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<!-- <parent>-->
<!-- <groupId>org.avaje</groupId>-->
<!-- <artifactId>java8-oss</artifactId>-->
<!-- <version>2.2</version>-->
<!-- </parent>-->
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-parent-12.5.2</tag>
</scm>
<name>ebean external mapping xml</name>
<description>XML implementation for mapping external named queries</description>
<artifactId>ebean-externalmapping-xml</artifactId>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-externalmapping-api</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
</dependency>
<dependency>
@@ -33,14 +52,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>${project.version}</version>
<version>12.5.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddlgen</artifactId>
<version>12.4.1</version>
<version>12.5.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.avaje.composite</groupId>
<artifactId>junit</artifactId>
<version>1.1</version>
<scope>test</scope>
</dependency>
@@ -51,12 +77,12 @@
<plugin>
<groupId>io.repaint.maven</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>2.17</version>
<version>2.18</version>
<extensions>true</extensions>
<configuration>
<tiles>
<!-- other tiles ... -->
<tile>io.ebean.tile:enhancement:12.4.2</tile>
<tile>io.ebean.tile:enhancement:12.5.0</tile>
</tiles>
</configuration>
</plugin>
+17
View File
@@ -0,0 +1,17 @@
# editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
spaces_around_operators = true
max_line_length = 130
[pom.xml]
# Because of <project... line
max_line_length = 999
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

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