Compare commits

..
Author SHA1 Message Date
rob bygrave b721017dd5 [maven-release-plugin] prepare release ebean-12.4.2 2020-10-07 20:42:59 +13:00
rob bygrave de5346437f Bump maven plugin 2020-10-07 20:39:53 +13:00
rob bygrave 1669649706 #2064 - Generated sql is missing a space near to the "dtype and softdelete" join-conditions when "fetch join" is used 2020-10-07 17:12:51 +13:00
rob bygrave 3f816c49c9 #2063 - Updating bean - L2 Bean cache update + l2 cache update on "Many Ids" when they have not change - can lead to race 2020-10-07 15:26:31 +13:00
rob bygrave e31ae49bc5 #2063 - Failing test for - Updating bean - L2 Bean cache update + l2 cache update on "Many Ids" when they have not change - can lead to race 2020-10-07 15:12:13 +13:00
rob bygrave bdf8381518 Update test only - TestAttributeConverter 2020-10-07 14:16:55 +13:00
rob bygrave 7eb185ce9b Refactor remove message.properties resource in favour of simple error messages and logs 2020-09-24 23:40:05 +12:00
rob bygrave f175b198e6 Merge branch 'FOCONIS-test_beancache_wrong_result' 2020-09-24 22:15:09 +12:00
rob bygrave de734665cd #2061 - Fix for L2 bean cache loaded using lazy loading on mutated partially loaded bean
The fix is when the property is dirty (mutated) put the original value into the cache entry.
2020-09-24 22:14:48 +12:00
Jonas Pöhler (JPo) c5eb6fa034 ADD: failing testcase for wrong bean caching
Signed-off-by: Jonas Pöhler (JPo) <jonas.poehler@foconis.de>
2020-09-23 15:19:59 +02:00
rob bygrave 5706c73272 [maven-release-plugin] prepare for next development iteration 2020-09-17 23:59:24 +12:00
rob bygrave c5a899c0e8 [maven-release-plugin] prepare release ebean-12.4.1 2020-09-17 23:59:12 +12:00
rob bygrave 50eb7d78fb Bump to 12.4.1-SNAPSHOT 2020-09-17 23:46:46 +12:00
rob bygrave 13e805b31c No effective change - organise imports on generated EQLLexer and EQLParser 2020-09-17 23:03:56 +12:00
rob bygrave 3531db0e53 #2060 - Bump ANTLR to 4.8-1 (from 4.7.2) and add support for "leOrNull" and "geOrNull" expressions from #2059 2020-09-17 23:01:09 +12:00
rob bygrave 87243a871d No effective change - tidy OrmQueryRequest 2020-09-17 22:46:22 +12:00
rob bygrave f2159fed71 #2058 - .findVersionsBetween() for PG and MySql... should use inclusive/exclusive and it is instead is exclusive/exclusive 2020-09-17 22:38:42 +12:00
rob bygrave 740fd63f35 #2059 - ENH: Add convenience expressions leOrNull() and geOrNull() ... [ property >= value or property is null ] 2020-09-17 22:23:54 +12:00
rob bygrave 2ad99794ea No effective change - tidy whitespace 2020-09-14 21:05:38 +12:00
rob bygrave 775f184450 No effective change - tidy whitespace from SaveManyBeans and BeanPropertyAssocMany 2020-09-14 20:57:21 +12:00
rob bygrave 4492a87a3f No effective change - tidy DefaultTypeFactory 2020-09-14 20:39:22 +12:00
rob bygrave 18d5d01d48 #2049 - Tidy after ServerConfig -> DatabaseConfig 2020-09-14 20:35:20 +12:00
Rob BygraveandGitHub 90b1b88be6 Update CsvCallback API to use Database instead of EbeanServer (#2010)
* Update CsvCallback API to use Database instead of EbeanServer
2020-09-14 18:33:12 +12:00
Rob BygraveandGitHub 6839f869f5 #2049 - Migrate to DatabaseConfig from ServerConfig (#2057) 2020-09-14 18:30:51 +12:00
rob bygrave 488762957a [maven-release-plugin] prepare for next development iteration 2020-09-08 13:28:26 +12:00
rob bygrave ec016cab17 [maven-release-plugin] prepare release ebean-12.3.9 2020-09-08 13:28:15 +12:00
rob bygrave 7c28f01923 Bump parent pom 2020-09-08 13:26:37 +12:00
Rob BygraveandGitHub 54da22eee6 Merge pull request #2056 from ebean-orm/feature/DbContext
#2055 - Refactor internals - Extract DbContext from Ebean and hold Database rather than EbeanServer
2020-09-08 09:33:10 +12:00
rob bygrave 6772b6e87e #2055 - Refactor internals - Extract DbContext from Ebean and hold Database rather than EbeanServer 2020-09-08 09:29:06 +12:00
rob bygrave 9856ebd540 #2055 - Refactor internals - Extract DbContext from Ebean and hold Database rather than EbeanServer 2020-09-08 09:25:32 +12:00
rob bygrave f96ac6e6fe No effective change - tidy Ebean, EbeanVersion 2020-09-07 21:55:21 +12:00
rob bygrave 4c5618b04b #2054 - Invalid SQL with History findVersions() on bean with @EmbeddedId - ... ORDER BY T0.NULL[*] ... 2020-09-07 18:25:25 +12:00
rob bygrave a77de9e5e6 No effective change - trim whitespace for IdBinderEmbedded 2020-09-07 18:00:12 +12:00
rob bygrave da29330a2a #2053 - Refactor tidy StringHelper.replace replacing with just String.replace where possible 2020-09-04 18:04:10 +12:00
rob bygrave d0f9d4a9a6 #2053 - Refactor tidy StringHelper.replaceString 2020-09-04 17:42:09 +12:00
rob bygrave 61ee67ee41 #2053 - Refactor tidy StringHelper.replaceString 2020-09-04 17:36:10 +12:00
rob bygrave 3117acd2d7 #2053 - Refactor tidy StringHelper.delimitedToMap 2020-09-04 13:37:25 +12:00
rob bygrave 4cee41d8d6 #2053 - Refactor tidy StringHelper - replace replaceStringMulti() with removeNewLines() 2020-09-04 13:21:13 +12:00
rob bygrave f4a58938bd #2053 - Refactor tidy StringHelper - just tidy 2020-09-04 13:09:55 +12:00
rob bygrave 4ce84f694f #2053 - Refactor tidy internals - Clean up StringHelper 2020-09-04 13:04:14 +12:00
rob bygrave 8eb248b966 #2052 - Refactor tidy internals - Use String.replace() rather than literal pattern replaceAll() 2020-09-04 12:53:43 +12:00
rob bygrave c294d8e568 #2051 - Bump config dependency from io.avaje:config to io.avaje:avaje-config 2020-09-03 17:18:14 +12:00
rob bygrave e923316ce9 Change to use maven <optional>true</optional> rather than scope provided 2020-09-03 17:13:23 +12:00
rob bygrave f611068a03 #2050 - Refactor internals - remove dependency on java.beans 2020-09-03 14:45:27 +12:00
rob bygrave dd880ac09b #2044 - Using @AttributeOverrides when override nullable 2020-08-31 14:38:23 +12:00
rob bygrave dbe24a4041 [maven-release-plugin] prepare for next development iteration 2020-08-26 11:37:29 +12:00
rob bygrave 1f32dc2dc5 [maven-release-plugin] prepare release ebean-12.3.8 2020-08-26 11:37:17 +12:00
rob bygrave b2ce9db8a8 #2048 - IllegalStateException: No query cache enabled on __. Need explicit @Cache(enableQueryCache=true) ... when ebean.disableL2Cache=true l2 2020-08-26 11:33:23 +12:00
rob bygrave a626690918 #2044 - Using @AttributeOverrides also override length, scale and columnDefinition 2020-08-25 09:48:01 +12:00
rob bygrave 0d511d51a6 #2044 - Using @AttributeOverrides breaking generated SQL (when override nullable and no column name) 2020-08-25 09:22:15 +12:00
rob bygrave 854f467504 No effective change - update ddl review h2 2020-08-25 09:08:11 +12:00
rob bygrave d3cc393edc No effective change - update ddl review postgres 2020-08-25 09:04:21 +12:00
Rob BygraveandGitHub 002014f930 For #2038 - updated from 12.3.6 to 12.3.7 - NPE BeanDescriptor.findPropertyFromPath(BeanDescriptor.java:1965) (#2047)
* #2038 - lazy loading ToMany with path

* #2038 - Failing test for NPE BeanDescriptor.findPropertyFromPath(BeanDescriptor.java:1965)

* #2038 Refactor internals DbReadContext use BeanPropertyAssocMany
2020-08-24 18:40:36 +12:00
rob bygrave c8d352b0a8 Add a better error message for #2038 NPE at BeanDescriptor.java:1965 2020-08-05 16:44:45 +12:00
rob bygrave 3796f2b267 No effective change - organise imports on tests 2020-08-05 16:39:10 +12:00
peterko2017andGitHub 4ef5abceca Add STI Discrimination on Reference Associations (#2041)
* Update SqlTreeNodeBean#appendFromBaseTable to add
discriminator values to the join
* Update tests to reflect new generated SQL
2020-08-05 16:33:34 +12:00
rob bygrave 4eda4201de Javadoc only change for RawSql 2020-07-30 16:22:09 +12:00
rob bygrave 933aa30149 Javadoc only change - replace at sign and fix javadoc 2020-07-27 16:41:30 +12:00
rob bygrave 0c80b3078a #2037 - Refactor simplify TransactionCallback to lambda
- Move to use generic try catch exception
- Convert to lambda method calls
2020-07-24 13:19:56 +12:00
rob bygrave 7317847aa7 #2037 - Allow PostCommit transaction callback to recursively add another PostCommit callback 2020-07-24 13:16:18 +12:00
rob bygrave 444644f759 #2037 - Allow PostCommit transaction callback to recursively add another PostCommit callback 2020-07-24 13:16:00 +12:00
rob bygrave f704da641d No effective change - Modify test only adding extra asserts for #2036 2020-07-24 11:54:15 +12:00
rob bygrave a1d2f4c1af [maven-release-plugin] prepare for next development iteration 2020-07-14 12:52:50 +12:00
232 changed files with 7486 additions and 5619 deletions
+14 -14
View File
@@ -4,12 +4,12 @@
<parent>
<groupId>org.avaje</groupId>
<artifactId>java8-oss</artifactId>
<version>2.1</version>
<version>2.2</version>
</parent>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>12.3.7</version>
<version>12.4.2</version>
<packaging>jar</packaging>
<name>ebean</name>
@@ -22,7 +22,7 @@
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-12.3.7</tag>
<tag>ebean-12.4.2</tag>
</scm>
<profiles>
@@ -63,8 +63,8 @@
<dependency>
<groupId>io.avaje</groupId>
<artifactId>config</artifactId>
<version>1.2</version>
<artifactId>avaje-config</artifactId>
<version>1.0</version>
</dependency>
<!--
@@ -111,7 +111,7 @@
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.7.2</version>
<version>4.8-1</version>
</dependency>
<!-- Jackson core used internally by Ebean -->
@@ -126,14 +126,14 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-databind.version}</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<!-- provided scope to read validation annotations Size etc -->
@@ -141,21 +141,21 @@
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.7</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<!-- Provided scope to compile with java 11 -->
@@ -170,7 +170,7 @@
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<!-- Provided scope for Postgres JSON/JSONB support -->
@@ -178,7 +178,7 @@
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.10</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<!-- Test scope -->
@@ -299,7 +299,7 @@
<plugin>
<groupId>io.ebean</groupId>
<artifactId>ebean-maven-plugin</artifactId>
<version>12.3.7</version>
<version>12.4.1</version>
<executions>
<execution>
<id>test</id>
+1 -1
View File
@@ -14,7 +14,7 @@ import java.util.Optional;
*
* public class CustomerFinder extends BeanFinder<Long,Customer> {
*
* @Inject
* Inject
* public CustomerFinder(Database database) {
* super(Customer.class, database);
* }
+2 -2
View File
@@ -9,10 +9,10 @@ import java.util.Collection;
* <p>
* <pre>{@code
*
* @Repository
* Repository
* public class CustomerRepository extends BeanRepository<Long,Customer> {
*
* @Inject
* Inject
* public CustomerRepository(Database server) {
* super(Customer.class, server);
* }
+5 -20
View File
@@ -60,7 +60,9 @@ import java.util.concurrent.Callable;
*
* }</pre>
*/
public class DB {
public final class DB {
private static final DbContext context = DbContext.getInstance();
/**
* Hide constructor.
@@ -72,7 +74,7 @@ public class DB {
* Return the default database.
*/
public static Database getDefault() {
return Ebean.getDefaultServer();
return context.getDefault();
}
/**
@@ -81,26 +83,9 @@ public class DB {
* @param name The name of the database
*/
public static Database byName(String name) {
return Ebean.getServer(name);
return context.get(name);
}
// /**
// * Register the server with this Ebean singleton. Specify if the registered
// * server is the primary/default database.
// */
// public static void register(EbeanServer server, boolean defaultServer) {
// serverMgr.register(server, defaultServer);
// }
//
// /**
// * Backdoor for registering a mock implementation of EbeanServer as the default database.
// */
// protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
// EbeanServer originalPrimaryServer = serverMgr.defaultServer;
// serverMgr.registerWithName(name, server, defaultServer);
// return originalPrimaryServer;
// }
/**
* Return the ScriptRunner for the default database.
* <p>
+1 -1
View File
@@ -881,7 +881,7 @@ public interface Database {
* <pre>{@code
* public class Order { ...
*
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
* OneToMany(cascade=CascadeType.ALL, mappedBy="order")
* List<OrderDetail> details;
* ...
* }
+75 -9
View File
@@ -2,6 +2,13 @@ package io.ebean;
import io.ebean.config.ContainerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.service.SpiContainer;
import io.ebean.service.SpiContainerFactory;
import javax.persistence.PersistenceException;
import java.util.Iterator;
import java.util.Properties;
import java.util.ServiceLoader;
/**
* Creates Database instances.
@@ -23,35 +30,57 @@ import io.ebean.config.DatabaseConfig;
*/
public class DatabaseFactory {
private static SpiContainer container;
static {
EbeanVersion.getVersion();
}
/**
* Initialise the container with clustering configuration.
* <p>
* Call this prior to creating any Database instances or alternatively set the
* ContainerConfig on the ServerConfig when creating the first Database instance.
* ContainerConfig on the DatabaseConfig when creating the first Database instance.
*/
public static synchronized void initialiseContainer(ContainerConfig containerConfig) {
EbeanServerFactory.initialiseContainer(containerConfig);
getContainer(containerConfig);
}
/**
* Create using ebean.properties to configure the database.
* Create using properties to configure the database.
*/
public static synchronized Database create(String name) {
return EbeanServerFactory.create(name);
// construct based on loading properties files
return getContainer(null).createServer(name);
}
/**
* Create using the ServerConfig object to configure the database.
* Create using the DatabaseConfig object to configure the database.
*/
public static synchronized Database create(DatabaseConfig config) {
return EbeanServerFactory.create(config);
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;
}
/**
* Create using the ServerConfig additionally specifying a classLoader to use as the context class loader.
* Create using the DatabaseConfig additionally specifying a classLoader to use as the context class loader.
*/
public static synchronized Database createWithContextClassLoader(DatabaseConfig config, ClassLoader classLoader) {
return EbeanServerFactory.createWithContextClassLoader(config, classLoader);
ClassLoader currentContextLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
try {
return DatabaseFactory.create(config);
} finally {
// set the currentContextLoader back
Thread.currentThread().setContextClassLoader(currentContextLoader);
}
}
/**
@@ -61,7 +90,44 @@ public class DatabaseFactory {
* </p>
*/
public static synchronized void shutdown() {
EbeanServerFactory.shutdown();
container.shutdown();
}
private static Database createInternal(DatabaseConfig config) {
return getContainer(config.getContainerConfig()).createServer(config);
}
/**
* Get the EbeanContainer initialising it if necessary.
*
* @param containerConfig the configuration controlling clustering communication
*/
private static SpiContainer getContainer(ContainerConfig containerConfig) {
// thread safe in that all calling methods are synchronized
if (container != null) {
return container;
}
if (containerConfig == null) {
// effectively load configuration from ebean.properties
Properties properties = DbPrimary.getProperties();
containerConfig = new ContainerConfig();
containerConfig.loadFromProperties(properties);
}
container = createContainer(containerConfig);
return container;
}
/**
* 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);
}
throw new IllegalStateException("Service loader didn't find a SpiContainerFactory?");
}
}
+140
View File
@@ -0,0 +1,140 @@
package io.ebean;
import io.ebean.config.BeanNotEnhancedException;
import io.ebean.datasource.DataSourceConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.PersistenceException;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
/**
* Holds Database instances.
*/
final class DbContext {
private static final Logger logger = LoggerFactory.getLogger(DbContext.class);
static {
EbeanVersion.getVersion();
}
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();
/**
* The 'default' Database.
*/
private Database defaultDatabase;
private DbContext() {
try {
if (!DbPrimary.isSkip()) {
// look to see if there is a default server defined
String defaultName = DbPrimary.getDefaultServerName();
logger.debug("defaultName:{}", defaultName);
if (defaultName != null && !defaultName.trim().isEmpty()) {
defaultDatabase = getWithCreate(defaultName.trim());
}
}
} catch (BeanNotEnhancedException e) {
throw e;
} catch (DataSourceConfigurationException e) {
String msg = "Configuration error creating DataSource for the default Database." +
" This typically means a missing application-test.yaml or missing ebean-test dependency." +
" See https://ebean.io/docs/trouble-shooting#datasource";
throw new DataSourceConfigurationException(msg, e);
} catch (Throwable e) {
logger.error("Error trying to create the default Database", e);
throw new RuntimeException(e);
}
}
/**
* Return the shared singleton instance.
*/
static DbContext getInstance() {
return INSTANCE;
}
/**
* Return the default database.
*/
Database getDefault() {
if (defaultDatabase == null) {
String msg = "The default Database has not been defined?";
msg += " This is normally set via the ebean.datasource.default property.";
msg += " Otherwise it should be registered programmatically via registerServer()";
throw new PersistenceException(msg);
}
return defaultDatabase;
}
/**
* Return the database by name.
*/
Database get(String name) {
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.
*/
private Database getWithCreate(String name) {
synchronized (monitor) {
Database server = syncMap.get(name);
if (server == null) {
// register when creating server this way
server = EbeanServerFactory.create(name);
register(server, false);
}
return server;
}
}
/**
* Register a server so we can get it by its name.
*/
void register(Database server, boolean isDefault) {
registerWithName(server.getName(), server, isDefault);
}
private void registerWithName(String name, Database server, boolean isDefault) {
synchronized (monitor) {
concMap.put(name, server);
syncMap.put(name, server);
if (isDefault) {
defaultDatabase = server;
}
}
}
Database mock(String name, Database server, boolean defaultServer) {
Database originalPrimaryServer = this.defaultDatabase;
registerWithName(name, server, defaultServer);
return originalPrimaryServer;
}
}
@@ -9,7 +9,7 @@ import java.util.Properties;
* <p/>
* Intended for internal use as part of bootup, construction, registration of the default database.
*/
class PrimaryServer {
class DbPrimary {
private static String defaultServerName;
@@ -19,7 +19,7 @@ class PrimaryServer {
* Set whether to skip automatically creating the primary database.
*/
static synchronized void setSkip(boolean skip) {
PrimaryServer.skip = skip;
DbPrimary.skip = skip;
}
/**
+1 -1
View File
@@ -149,7 +149,7 @@ public interface DocumentStore {
* .setUseDocStore(true)
* .where()... // perhaps add predicates
* .findEachWhile(new Predicate<Order>() {
* @Override
* Override
* public void accept(Order bean) {
* // process the bean
*
+84 -219
View File
@@ -2,26 +2,19 @@ package io.ebean;
import io.ebean.annotation.TxIsolation;
import io.ebean.cache.ServerCacheManager;
import io.ebean.config.BeanNotEnhancedException;
import io.ebean.config.ServerConfig;
import io.ebean.datasource.DataSourceConfigurationException;
import io.ebean.plugin.Property;
import io.ebean.text.csv.CsvReader;
import io.ebean.text.json.JsonContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
/**
* Deprecated - please migrate to use <code>io.ebean.DB</code>.
@@ -34,123 +27,8 @@ import java.util.concurrent.ConcurrentHashMap;
*/
@Deprecated
public final class Ebean {
private static final Logger logger = LoggerFactory.getLogger(Ebean.class);
static {
EbeanVersion.getVersion(); // initialises the version class and logs the version.
}
/**
* Manages creation and cache of Databases.
*/
private static final Ebean.ServerManager serverMgr = new Ebean.ServerManager();
/**
* Helper class for managing fast and safe access and creation of Databases.
*/
private static final class ServerManager {
/**
* Cache for fast concurrent read access.
*/
private final ConcurrentHashMap<String, EbeanServer> concMap = new ConcurrentHashMap<>();
/**
* Cache for synchronized read, creation and put. Protected by the monitor object.
*/
private final HashMap<String, EbeanServer> syncMap = new HashMap<>();
private final Object monitor = new Object();
/**
* The 'default' Database.
*/
private EbeanServer defaultServer;
private ServerManager() {
try {
if (!PrimaryServer.isSkip()) {
// look to see if there is a default server defined
String defaultName = PrimaryServer.getDefaultServerName();
logger.debug("defaultName:{}", defaultName);
if (defaultName != null && !defaultName.trim().isEmpty()) {
defaultServer = getWithCreate(defaultName.trim());
}
}
} catch (BeanNotEnhancedException e) {
throw e;
} catch (DataSourceConfigurationException e) {
String msg = "Configuration error creating DataSource for the default Database." +
" This typically means a missing application-test.yaml or missing ebean-test dependency." +
" See https://ebean.io/docs/trouble-shooting#datasource";
throw new DataSourceConfigurationException(msg, e);
} catch (Throwable e) {
logger.error("Error trying to create the default Database", e);
throw new RuntimeException(e);
}
}
private EbeanServer getDefaultServer() {
if (defaultServer == null) {
String msg = "The default Database has not been defined?";
msg += " This is normally set via the ebean.datasource.default property.";
msg += " Otherwise it should be registered programmatically via registerServer()";
throw new PersistenceException(msg);
}
return defaultServer;
}
private EbeanServer get(String name) {
if (name == null || name.isEmpty()) {
return defaultServer;
}
// non-synchronized read
EbeanServer server = concMap.get(name);
if (server != null) {
return server;
}
// synchronized read, create and put
return getWithCreate(name);
}
/**
* Synchronized read, create and put of Databases.
*/
private EbeanServer getWithCreate(String name) {
synchronized (monitor) {
EbeanServer server = syncMap.get(name);
if (server == null) {
// register when creating server this way
server = EbeanServerFactory.create(name);
register(server, false);
}
return server;
}
}
/**
* Register a server so we can get it by its name.
*/
private void register(EbeanServer server, boolean isDefaultServer) {
registerWithName(server.getName(), server, isDefaultServer);
}
private void registerWithName(String name, EbeanServer server, boolean isDefaultServer) {
synchronized (monitor) {
concMap.put(name, server);
syncMap.put(name, server);
if (isDefaultServer) {
defaultServer = server;
}
}
}
}
private static final DbContext context = DbContext.getInstance();
private Ebean() {
}
@@ -174,7 +52,7 @@ public final class Ebean {
* @param name the name of the server, can use null for the 'default server'
*/
public static EbeanServer getServer(String name) {
return serverMgr.get(name);
return (EbeanServer)context.get(name);
}
/**
@@ -184,7 +62,27 @@ public final class Ebean {
* </p>
*/
public static EbeanServer getDefaultServer() {
return serverMgr.getDefaultServer();
return (EbeanServer)context.getDefault();
}
/**
* Register the server with this Ebean singleton. Specify if the registered
* server is the primary/default database.
*/
@Deprecated
public static void register(EbeanServer server, boolean defaultServer) {
context.register(server, defaultServer);
}
/**
* Backdoor for registering a mock implementation of EbeanServer as the default database.
*/
protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
return (EbeanServer)context.mock(name, server, defaultServer);
}
private static Database getDefault() {
return context.getDefault();
}
/**
@@ -205,24 +103,7 @@ public final class Ebean {
* </p>
*/
public static ExpressionFactory getExpressionFactory() {
return serverMgr.getDefaultServer().getExpressionFactory();
}
/**
* Register the server with this Ebean singleton. Specify if the registered
* server is the primary/default database.
*/
public static void register(EbeanServer server, boolean defaultServer) {
serverMgr.register(server, defaultServer);
}
/**
* Backdoor for registering a mock implementation of EbeanServer as the default database.
*/
protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
EbeanServer originalPrimaryServer = serverMgr.defaultServer;
serverMgr.registerWithName(name, server, defaultServer);
return originalPrimaryServer;
return getDefault().getExpressionFactory();
}
/**
@@ -238,7 +119,7 @@ public final class Ebean {
* </p>
*/
public static Object nextId(Class<?> beanType) {
return serverMgr.getDefaultServer().nextId(beanType);
return getDefault().nextId(beanType);
}
/**
@@ -284,7 +165,7 @@ public final class Ebean {
* </p>
*/
public static Transaction beginTransaction() {
return serverMgr.getDefaultServer().beginTransaction();
return getDefault().beginTransaction();
}
/**
@@ -293,7 +174,7 @@ public final class Ebean {
* @param isolation the Transaction isolation level
*/
public static Transaction beginTransaction(TxIsolation isolation) {
return serverMgr.getDefaultServer().beginTransaction(isolation);
return getDefault().beginTransaction(isolation);
}
/**
@@ -346,7 +227,7 @@ public final class Ebean {
* }</pre>
*/
public static Transaction beginTransaction(TxScope scope) {
return serverMgr.getDefaultServer().beginTransaction(scope);
return getDefault().beginTransaction(scope);
}
/**
@@ -354,7 +235,7 @@ public final class Ebean {
* in scope.
*/
public static Transaction currentTransaction() {
return serverMgr.getDefaultServer().currentTransaction();
return getDefault().currentTransaction();
}
/**
@@ -384,21 +265,21 @@ public final class Ebean {
* @throws PersistenceException if there is no currently active transaction
*/
public static void register(TransactionCallback transactionCallback) throws PersistenceException {
serverMgr.getDefaultServer().register(transactionCallback);
getDefault().register(transactionCallback);
}
/**
* Commit the current transaction.
*/
public static void commitTransaction() {
serverMgr.getDefaultServer().commitTransaction();
getDefault().commitTransaction();
}
/**
* Rollback the current transaction.
*/
public static void rollbackTransaction() {
serverMgr.getDefaultServer().rollbackTransaction();
getDefault().rollbackTransaction();
}
/**
@@ -426,14 +307,14 @@ public final class Ebean {
* }</pre>
*/
public static void endTransaction() {
serverMgr.getDefaultServer().endTransaction();
getDefault().endTransaction();
}
/**
* Mark the current transaction as rollback only.
*/
public static void setRollbackOnly() {
serverMgr.getDefaultServer().currentTransaction().setRollbackOnly();
getDefault().currentTransaction().setRollbackOnly();
}
/**
@@ -444,7 +325,7 @@ public final class Ebean {
* </p>
*/
public static Map<String, ValuePair> diff(Object a, Object b) {
return serverMgr.getDefaultServer().diff(a, b);
return getDefault().diff(a, b);
}
/**
@@ -465,7 +346,7 @@ public final class Ebean {
* <pre>{@code
* public class Order { ...
*
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
* OneToMany(cascade=CascadeType.ALL, mappedBy="order")
* List<OrderDetail> details;
* ...
* }
@@ -478,7 +359,7 @@ public final class Ebean {
* </p>
*/
public static void save(Object bean) throws OptimisticLockException {
serverMgr.getDefaultServer().save(bean);
getDefault().save(bean);
}
/**
@@ -486,14 +367,14 @@ public final class Ebean {
* want to explicitly insert it.
*/
public static void insert(Object bean) {
serverMgr.getDefaultServer().insert(bean);
getDefault().insert(bean);
}
/**
* Insert a collection of beans.
*/
public static void insertAll(Collection<?> beans) {
serverMgr.getDefaultServer().insertAll(beans);
getDefault().insertAll(beans);
}
/**
@@ -516,7 +397,7 @@ public final class Ebean {
* }</pre>
*/
public static void markAsDirty(Object bean) throws OptimisticLockException {
serverMgr.getDefaultServer().markAsDirty(bean);
getDefault().markAsDirty(bean);
}
/**
@@ -531,16 +412,6 @@ public final class Ebean {
* <b>Optimistic Locking: </b> Note that if the version property is not set when update() is
* called then no optimistic locking is performed (internally ConcurrencyMode.NONE is used).
* </p>
* <p>
* <b>{@link ServerConfig#setUpdatesDeleteMissingChildren(boolean)}: </b> When cascade saving to a
* OneToMany or ManyToMany the updatesDeleteMissingChildren setting controls if any other children
* that are in the database but are not in the collection are deleted.
* </p>
* <p>
* <b>{@link ServerConfig#setUpdateChangesOnly(boolean)}: </b> The updateChangesOnly setting
* controls if only the changed properties are included in the update or if all the loaded
* properties are included instead.
* </p>
* <pre>{@code
*
* // A 'stateless update' example
@@ -553,14 +424,14 @@ public final class Ebean {
* }</pre>
*/
public static void update(Object bean) throws OptimisticLockException {
serverMgr.getDefaultServer().update(bean);
getDefault().update(bean);
}
/**
* Update the beans in the collection.
*/
public static void updateAll(Collection<?> beans) throws OptimisticLockException {
serverMgr.getDefaultServer().updateAll(beans);
getDefault().updateAll(beans);
}
/**
@@ -569,7 +440,7 @@ public final class Ebean {
* @param bean The bean to merge
*/
public static void merge(Object bean) {
serverMgr.getDefaultServer().merge(bean);
getDefault().merge(bean);
}
/**
@@ -579,14 +450,14 @@ public final class Ebean {
* @param options The options to control the merge
*/
public static void merge(Object bean, MergeOptions options) {
serverMgr.getDefaultServer().merge(bean, options);
getDefault().merge(bean, options);
}
/**
* Save all the beans from a Collection.
*/
public static int saveAll(Collection<?> beans) throws OptimisticLockException {
return serverMgr.getDefaultServer().saveAll(beans);
return getDefault().saveAll(beans);
}
/**
@@ -637,7 +508,7 @@ public final class Ebean {
*/
@Nonnull
public static Set<Property> checkUniqueness(Object bean) {
return serverMgr.getDefaultServer().checkUniqueness(bean);
return getDefault().checkUniqueness(bean);
}
/**
@@ -645,7 +516,7 @@ public final class Ebean {
*/
@Nonnull
public static Set<Property> checkUniqueness(Object bean, Transaction transaction) {
return serverMgr.getDefaultServer().checkUniqueness(bean, transaction);
return getDefault().checkUniqueness(bean, transaction);
}
/**
@@ -668,56 +539,56 @@ public final class Ebean {
* </p>
*/
public static boolean delete(Object bean) throws OptimisticLockException {
return serverMgr.getDefaultServer().delete(bean);
return getDefault().delete(bean);
}
/**
* Delete the bean in permanent fashion (will not use soft delete).
*/
public static boolean deletePermanent(Object bean) throws OptimisticLockException {
return serverMgr.getDefaultServer().deletePermanent(bean);
return getDefault().deletePermanent(bean);
}
/**
* Delete the bean given its type and id.
*/
public static int delete(Class<?> beanType, Object id) {
return serverMgr.getDefaultServer().delete(beanType, id);
return getDefault().delete(beanType, id);
}
/**
* Delete permanent the bean given its type and id.
*/
public static int deletePermanent(Class<?> beanType, Object id) {
return serverMgr.getDefaultServer().deletePermanent(beanType, id);
return getDefault().deletePermanent(beanType, id);
}
/**
* Delete several beans given their type and id values.
*/
public static int deleteAll(Class<?> beanType, Collection<?> ids) {
return serverMgr.getDefaultServer().deleteAll(beanType, ids);
return getDefault().deleteAll(beanType, ids);
}
/**
* Delete permanent several beans given their type and id values.
*/
public static int deleteAllPermanent(Class<?> beanType, Collection<?> ids) {
return serverMgr.getDefaultServer().deleteAllPermanent(beanType, ids);
return getDefault().deleteAllPermanent(beanType, ids);
}
/**
* Delete all the beans in the Collection.
*/
public static int deleteAll(Collection<?> beans) throws OptimisticLockException {
return serverMgr.getDefaultServer().deleteAll(beans);
return getDefault().deleteAll(beans);
}
/**
* Delete permanent all the beans in the Collection (will not use soft delete).
*/
public static int deleteAllPermanent(Collection<?> beans) throws OptimisticLockException {
return serverMgr.getDefaultServer().deleteAllPermanent(beans);
return getDefault().deleteAllPermanent(beans);
}
/**
@@ -728,7 +599,7 @@ public final class Ebean {
* </p>
*/
public static void refresh(Object bean) {
serverMgr.getDefaultServer().refresh(bean);
getDefault().refresh(bean);
}
/**
@@ -746,7 +617,7 @@ public final class Ebean {
* @param manyPropertyName the property name of the List Set or Map to refresh.
*/
public static void refreshMany(Object bean, String manyPropertyName) {
serverMgr.getDefaultServer().refreshMany(bean, manyPropertyName);
getDefault().refreshMany(bean, manyPropertyName);
}
/**
@@ -771,7 +642,7 @@ public final class Ebean {
* @param id the id value
*/
public static <T> T getReference(Class<T> beanType, Object id) {
return serverMgr.getDefaultServer().getReference(beanType, id);
return getDefault().getReference(beanType, id);
}
/**
@@ -814,7 +685,7 @@ public final class Ebean {
* @param sortByClause the properties to sort the list by
*/
public static <T> void sort(List<T> list, String sortByClause) {
serverMgr.getDefaultServer().sort(list, sortByClause);
getDefault().sort(list, sortByClause);
}
/**
@@ -864,7 +735,7 @@ public final class Ebean {
*/
@Nullable
public static <T> T find(Class<T> beanType, Object id) {
return serverMgr.getDefaultServer().find(beanType, id);
return getDefault().find(beanType, id);
}
/**
@@ -879,7 +750,7 @@ public final class Ebean {
*/
@Deprecated
public static SqlQuery createSqlQuery(String sql) {
return serverMgr.getDefaultServer().sqlQuery(sql);
return getDefault().sqlQuery(sql);
}
/**
@@ -894,7 +765,7 @@ public final class Ebean {
*/
@Deprecated
public static SqlUpdate createSqlUpdate(String sql) {
return serverMgr.getDefaultServer().sqlUpdate(sql);
return getDefault().sqlUpdate(sql);
}
/**
@@ -903,7 +774,7 @@ public final class Ebean {
* @see CallableSql
*/
public static CallableSql createCallableSql(String sql) {
return serverMgr.getDefaultServer().createCallableSql(sql);
return getDefault().createCallableSql(sql);
}
/**
@@ -935,16 +806,14 @@ public final class Ebean {
* }</pre>
*/
public static <T> Update<T> createUpdate(Class<T> beanType, String ormUpdate) {
return serverMgr.getDefaultServer().createUpdate(beanType, ormUpdate);
return getDefault().createUpdate(beanType, ormUpdate);
}
/**
* Create a CsvReader for a given beanType.
*/
public static <T> CsvReader<T> createCsvReader(Class<T> beanType) {
return serverMgr.getDefaultServer().createCsvReader(beanType);
return getDefault().createCsvReader(beanType);
}
/**
@@ -959,7 +828,7 @@ public final class Ebean {
* @return The query
*/
public static <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
return serverMgr.getDefaultServer().createNamedQuery(beanType, namedQuery);
return getDefault().createNamedQuery(beanType, namedQuery);
}
/**
@@ -982,8 +851,7 @@ public final class Ebean {
* @return A ORM Query object for this beanType
*/
public static <T> Query<T> createQuery(Class<T> beanType) {
return serverMgr.getDefaultServer().createQuery(beanType);
return getDefault().createQuery(beanType);
}
/**
@@ -1020,8 +888,7 @@ public final class Ebean {
* @return The query with expressions defined as per the parsed query statement
*/
public static <T> Query<T> createQuery(Class<T> beanType, String eql) {
return serverMgr.getDefaultServer().createQuery(beanType, eql);
return getDefault().createQuery(beanType, eql);
}
/**
@@ -1036,8 +903,7 @@ public final class Ebean {
* @return A ORM Query object for this beanType
*/
public static <T> Query<T> find(Class<T> beanType) {
return serverMgr.getDefaultServer().find(beanType);
return getDefault().find(beanType);
}
/**
@@ -1060,7 +926,7 @@ public final class Ebean {
* @return The query to set parameters and execute
*/
public static <T> Query<T> findNative(Class<T> beanType, String nativeSql) {
return serverMgr.getDefaultServer().findNative(beanType, nativeSql);
return getDefault().findNative(beanType, nativeSql);
}
/**
@@ -1075,7 +941,7 @@ public final class Ebean {
* @param <T> The type of the DTO bean.
*/
public static <T> DtoQuery<T> findDto(Class<T> dtoType, String sql) {
return serverMgr.getDefaultServer().findDto(dtoType, sql);
return getDefault().findDto(dtoType, sql);
}
/**
@@ -1097,7 +963,7 @@ public final class Ebean {
* @return The update query to use
*/
public static <T> UpdateQuery<T> update(Class<T> beanType) {
return serverMgr.getDefaultServer().update(beanType);
return getDefault().update(beanType);
}
/**
@@ -1111,7 +977,7 @@ public final class Ebean {
* </p>
*/
public static <T> Filter<T> filter(Class<T> beanType) {
return serverMgr.getDefaultServer().filter(beanType);
return getDefault().filter(beanType);
}
/**
@@ -1154,7 +1020,7 @@ public final class Ebean {
* @see Ebean#execute(CallableSql)
*/
public static int execute(SqlUpdate sqlUpdate) {
return serverMgr.getDefaultServer().execute(sqlUpdate);
return getDefault().execute(sqlUpdate);
}
/**
@@ -1182,7 +1048,7 @@ public final class Ebean {
* @see Ebean#execute(SqlUpdate)
*/
public static int execute(CallableSql callableSql) {
return serverMgr.getDefaultServer().execute(callableSql);
return getDefault().execute(callableSql);
}
/**
@@ -1206,7 +1072,7 @@ public final class Ebean {
* }</pre>
*/
public static void execute(TxScope scope, Runnable r) {
serverMgr.getDefaultServer().execute(scope, r);
getDefault().execute(scope, r);
}
/**
@@ -1233,7 +1099,7 @@ public final class Ebean {
* }</pre>
*/
public static void execute(Runnable r) {
serverMgr.getDefaultServer().execute(r);
getDefault().execute(r);
}
/**
@@ -1258,7 +1124,7 @@ public final class Ebean {
* }</pre>
*/
public static <T> T executeCall(TxScope scope, Callable<T> c) {
return serverMgr.getDefaultServer().executeCall(scope, c);
return getDefault().executeCall(scope, c);
}
/**
@@ -1291,7 +1157,7 @@ public final class Ebean {
* }</pre>
*/
public static <T> T executeCall(Callable<T> c) {
return serverMgr.getDefaultServer().executeCall(c);
return getDefault().executeCall(c);
}
/**
@@ -1325,8 +1191,7 @@ public final class Ebean {
* @param deletes true if rows on the table where deleted
*/
public static void externalModification(String tableName, boolean inserts, boolean updates, boolean deletes) {
serverMgr.getDefaultServer().externalModification(tableName, inserts, updates, deletes);
getDefault().externalModification(tableName, inserts, updates, deletes);
}
/**
@@ -1336,14 +1201,14 @@ public final class Ebean {
* </p>
*/
public static BeanState getBeanState(Object bean) {
return serverMgr.getDefaultServer().getBeanState(bean);
return getDefault().getBeanState(bean);
}
/**
* Return the manager of the server cache ("L2" cache).
*/
public static ServerCacheManager getServerCacheManager() {
return serverMgr.getDefaultServer().getServerCacheManager();
return getDefault().getServerCacheManager();
}
/**
@@ -1351,14 +1216,14 @@ public final class Ebean {
* queries.
*/
public static BackgroundExecutor getBackgroundExecutor() {
return serverMgr.getDefaultServer().getBackgroundExecutor();
return getDefault().getBackgroundExecutor();
}
/**
* Return the JsonContext for reading/writing JSON.
*/
public static JsonContext json() {
return serverMgr.getDefaultServer().json();
return getDefault().json();
}
}
+5 -76
View File
@@ -33,13 +33,6 @@ import java.util.ServiceLoader;
@Deprecated
public class EbeanServerFactory {
private static SpiContainer container;
static {
EbeanVersion.getVersion(); // initalizes the version class and logs the version.
}
/**
* Initialise the container with clustering configuration.
* <p>
@@ -47,53 +40,28 @@ public class EbeanServerFactory {
* ContainerConfig on the ServerConfig when creating the first EbeanServer instance.
*/
public static synchronized void initialiseContainer(ContainerConfig containerConfig) {
getContainer(containerConfig);
DatabaseFactory.initialiseContainer(containerConfig);
}
/**
* Create using ebean.properties to configure the database.
*/
public static synchronized EbeanServer create(String name) {
// construct based on loading properties files
// and if invoked by Ebean then it handles registration
SpiContainer serverFactory = getContainer(null);
return serverFactory.createServer(name);
return (EbeanServer)DatabaseFactory.create(name);
}
/**
* Create using the ServerConfig object to configure the database.
*/
public static synchronized EbeanServer create(ServerConfig config) {
if (config.getName() == null) {
throw new PersistenceException("The name is null (it is required)");
}
EbeanServer server = createInternal(config);
if (config.isRegister()) {
PrimaryServer.setSkip(true);
Ebean.register(server, config.isDefaultServer());
}
return server;
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) {
ClassLoader currentContextLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
try {
return EbeanServerFactory.create(config);
} finally {
// set the currentContextLoader back
Thread.currentThread().setContextClassLoader(currentContextLoader);
}
return (EbeanServer)DatabaseFactory.createWithContextClassLoader(config, classLoader);
}
/**
@@ -103,46 +71,7 @@ public class EbeanServerFactory {
* </p>
*/
public static synchronized void shutdown() {
container.shutdown();
DatabaseFactory.shutdown();
}
private static EbeanServer createInternal(ServerConfig config) {
return getContainer(config.getContainerConfig()).createServer(config);
}
/**
* Get the EbeanContainer initialising it if necessary.
*
* @param containerConfig the configuration controlling clustering communication
*/
private static SpiContainer getContainer(ContainerConfig containerConfig) {
// thread safe in that all calling methods are synchronized
if (container != null) {
return container;
}
if (containerConfig == null) {
// effectively load configuration from ebean.properties
Properties properties = PrimaryServer.getProperties();
containerConfig = new ContainerConfig();
containerConfig.loadFromProperties(properties);
}
container = createContainer(containerConfig);
return container;
}
/**
* 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);
}
throw new IllegalStateException("Service loader didn't find a SpiContainerFactory?");
}
}
+8 -4
View File
@@ -6,18 +6,18 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* Class to determine the ebean version. (
* @author Roland Praml, FOCONIS AG
* Class to determine the ebean version.
*
* @author Roland Praml, FOCONIS AG
*/
public class EbeanVersion {
private EbeanVersion() {
}
private static final Logger logger = LoggerFactory.getLogger(EbeanVersion.class);
private static String version = "unknown";
static {
try {
Properties prop = new Properties();
@@ -34,6 +34,10 @@ public class EbeanVersion {
}
}
private EbeanVersion() {
// hide
}
/**
* Returns the ebean version (read from /META-INF/maven/io.ebean/ebean/pom.properties)
*/
+1 -1
View File
@@ -53,7 +53,7 @@ public class Expr {
}
/**
* In Range - property >= value1 and property < value2.
* In Range - {@code property >= value1 and property < value2}.
* <p>
* Unlike Between inRange is "half open" and usually more useful for use with dates or timestamps.
* </p>
+17 -1
View File
@@ -155,7 +155,7 @@ public interface ExpressionFactory {
Expression ineObject(String propertyName, Object value);
/**
* In Range - property >= value1 and property < value2.
* In Range - {@code property >= value1 and property < value2}.
* <p>
* Unlike Between inRange is "half open" and usually more useful for use with dates or timestamps.
* </p>
@@ -199,6 +199,14 @@ public interface ExpressionFactory {
*/
Expression gtOrNull(String propertyName, Object value);
/**
* Greater than or Equal to OR Null <code> >= or null </code>
* <p>
* A convenient expression combining GE and Is Null. Most often useful for range
* expressions where the top range value is nullable.
*/
Expression geOrNull(String propertyName, Object value);
/**
* Greater Than - property greater than the given value.
*/
@@ -218,6 +226,14 @@ public interface ExpressionFactory {
*/
Expression ltOrNull(String propertyName, Object value);
/**
* Less Than or Equal to OR Null <code> <= or null </code>
* <p>
* A convenient expression combining LE and Is Null. Most often useful for range
* expressions where the bottom range value is nullable.
*/
Expression leOrNull(String propertyName, Object value);
/**
* Less Than - property less than the given value.
*/
+12 -4
View File
@@ -859,7 +859,7 @@ public interface ExpressionList<T> {
ExpressionList<T> inRangeWith(String lowProperty, String highProperty, Object value);
/**
* In Range - property >= value1 and property < value2.
* In Range - {@code property >= value1 and property < value2}.
* <p>
* Unlike Between inRange is "half open" and usually more useful for use with dates or timestamps.
* </p>
@@ -886,6 +886,11 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> gtOrNull(String propertyName, Object value);
/**
* Greater Than or Equal to OR Null - <code> >= or null </code>.
*/
ExpressionList<T> geOrNull(String propertyName, Object value);
/**
* Greater Than or Equal to - property greater than or equal to the given
* value.
@@ -902,6 +907,11 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> ltOrNull(String propertyName, Object value);
/**
* Less Than or Equal to OR Null - <code> <= or null </code>.
*/
ExpressionList<T> leOrNull(String propertyName, Object value);
/**
* Less Than or Equal to - property less than or equal to the given value.
*/
@@ -1254,12 +1264,10 @@ public interface ExpressionList<T> {
* The raw expression should contain a single ? or ?1
* at the location of the parameter. We use ?1 when binding a
* collection for an IN expression.
* </p>
* <p>>
* <p>
* When properties in the clause are fully qualified as table-column names
* then they are not translated. logical property name names (not fully
* qualified) will still be translated to their physical name.
* </p>
* <p>
* <h4>Examples:</h4>
* <pre>{@code
+4 -2
View File
@@ -37,12 +37,13 @@ import java.util.List;
* }
* }
*
* @Entity
* Entity
* public class Customer extends BaseModel {
*
* public static final CustomerFinder find = new CustomerFinder();
* ...
*
* }
* }</pre>
* <p>
* When the Finder is registered as a field on Customer it can then be used like:
@@ -79,12 +80,13 @@ public class Finder<I, T> {
* // ... add extra customer specific finder methods
* }
*
* @Entity
* Entity
* public class Customer extends BaseModel {
*
* public static final CustomerFinder find = new CustomerFinder();
* ...
*
* }
* }</pre>
*/
public Finder(Class<T> type) {
+9 -9
View File
@@ -32,19 +32,19 @@ import io.ebean.bean.EntityBean;
* // Typically there is a common base model that has some
* // common properties like the ones below
*
* @MappedSuperclass
* public class BaseModel extends Model {
* MappedSuperclass
* public class BaseModel extends Model {
*
* @Id Long id;
* Id Long id;
*
* @Version Long version;
* Version Long version;
*
* @WhenCreated Timestamp whenCreated;
* WhenCreated Timestamp whenCreated;
*
* @WhenUpdated Timestamp whenUpdated;
*
* ...
* WhenUpdated Timestamp whenUpdated;
*
* ...
* }
* }</pre>
* <p>
* <h3>Extend the Model</h3>
@@ -52,7 +52,7 @@ import io.ebean.bean.EntityBean;
*
* // Extend the mappedSuperclass
*
* @Entity @Table(name="o_account")
* Entity Table(name="o_account")
* public class Customer extends BaseModel {
*
* String name;
+1 -3
View File
@@ -1,7 +1,5 @@
package io.ebean;
import io.ebean.util.StringHelper;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@@ -341,7 +339,7 @@ public final class OrderBy<T> implements Serializable {
if (collation != null) {
if (collation.contains("${}")) {
// this is a complex collation, e.g. DB2 - we must replace the property
sb.append(StringHelper.replaceString(collation, "${}", property));
sb.append(collation.replace("${}", property));
} else {
sb.append(property);
sb.append(" collate ").append(collation);
+2 -2
View File
@@ -94,8 +94,8 @@ public interface PagedList<T> {
* Return the Future row count. You might get this if you wish to cancel the total row count query
* or specify a timeout for the row count query.
* <p>
* The loadRowCount() & getTotalRowCount() methods internally make use of this getFutureRowCount() method.
* Generally I expect people to prefer loadRowCount() & getTotalRowCount() over getFutureRowCount().
* The loadRowCount() and getTotalRowCount() methods internally make use of this getFutureRowCount() method.
* Generally I expect people to prefer loadRowCount() and getTotalRowCount() over getFutureRowCount().
* </p>
* <pre>{@code
*
+1 -1
View File
@@ -18,7 +18,7 @@ import java.util.List;
*
* // where a bean is annotated with a complex
* // natural key made of several properties
* @Cache(naturalKey = {"store","code","sku"})
* Cache(naturalKey = {"store","code","sku"})
*
*
* Pairs pairs = new Pairs("sku", "code");
@@ -6,7 +6,7 @@ package io.ebean;
* Ebean has traditionally used Transaction scope for the PersistenceContext. This is used to change the scope to
* use (by default) and explicitly set the scope to use for an individual query.
*
* @see io.ebean.config.ServerConfig#setPersistenceContextScope(PersistenceContextScope)
* @see io.ebean.config.DatabaseConfig#setPersistenceContextScope(PersistenceContextScope)
* @see Query#setPersistenceContextScope(PersistenceContextScope)
*/
public enum PersistenceContextScope {
+1 -1
View File
@@ -283,7 +283,7 @@ public interface Query<T> {
/**
* Specify the PersistenceContextScope to use for this query.
* <p/>
* When this is not set the 'default' configured on {@link io.ebean.config.ServerConfig#setPersistenceContextScope(PersistenceContextScope)}
* When this is not set the 'default' configured on {@link io.ebean.config.DatabaseConfig#setPersistenceContextScope(PersistenceContextScope)}
* is used - this value defaults to {@link PersistenceContextScope#TRANSACTION}.
* <p/>
* Note that the same persistence Context is used for subsequent lazy loading and query join queries.
+29 -42
View File
@@ -6,17 +6,13 @@ package io.ebean;
* <p>
* If you don't want to build object graphs you can use {@link SqlQuery} instead
* which returns {@link SqlRow} objects rather than entity beans.
* </p>
* <p>
* <b>Unparsed RawSql:</b>
* </p>
* <p>
* When RawSql is created via {@link RawSqlBuilder#unparsed(String)} then Ebean can not
* modify the SQL at all. It can't add any extra expressions into the SQL.
* </p>
* <p>
* <b>Parsed RawSql:</b>
* </p>
* <p>
* When RawSql is created via {@link RawSqlBuilder#parse(String)} then Ebean will parse the
* SQL and find places in the SQL where it can add extra where expressions, add
@@ -24,16 +20,13 @@ package io.ebean;
* explicitly tell Ebean where these insertion points are you can place special
* strings into your SQL ({@code ${where}} or {@code ${andWhere}} and {@code ${having}} or
* {@code ${andHaving})}.
* </p>
* <p>
* If the SQL already includes a WHERE clause put in {@code ${andWhere}} in the location
* you want Ebean to add any extra where expressions. If the SQL doesn't have a
* WHERE clause put {@code ${where}} in instead. Similarly you can put in {@code ${having}} or
* {@code ${andHaving}} where you want Ebean put add extra having expressions.
* </p>
* <p>
* <b>Aggregates:</b>
* </p>
* <p>
* Often RawSql will be used with Aggregate functions (sum, avg, max etc). The
* follow example shows an example based on Total Order Amount -
@@ -44,38 +37,37 @@ package io.ebean;
* on RawSql and not based on a real DB Table or DB View. It has some properties
* to hold the values for the aggregate functions (sum etc) and a &#064;OneToOne
* to Order.
* </p>
* <p>
* <h3>Example OrderAggregate</h3>
* <pre>{@code
* ...
* // @Sql indicates to that this bean
* // is based on RawSql rather than a table
* // Sql indicates to that this bean
* // is based on RawSql rather than a table
*
* @Entity
* @Sql
* public class OrderAggregate {
* Entity
* Sql
* public class OrderAggregate {
*
* @OneToOne
* Order order;
* OneToOne
* Order order;
*
* Double totalAmount;
* Double totalAmount;
*
* Double totalItems;
*
* // getters and setters
* ...
* Double totalItems;
*
* // getters and setters
* ...
* }
* }</pre>
* <p>
*
* <h3>Example 1:</h3>
* <p>
*
* <pre>{@code
*
* String sql = " select order_id, o.status, c.id, c.name, sum(d.order_qty*d.unit_price) as totalAmount"
* + " from o_order o"
* + " join o_customer c on c.id = o.kcustomer_id "
* + " join o_order_detail d on d.order_id = o.id " + " group by order_id, o.status ";
* String sql = " select order_id, o.status, c.id, c.name, sum(l.order_qty*l.unit_price) as totalAmount"
* + " from order o"
* + " join customer c on c.id = o.customer_id "
* + " join order_line l on l.order_id = o.id " + " group by order_id, o.status ";
*
* RawSql rawSql = RawSqlBuilder.parse(sql)
* // map the sql result columns to bean properties
@@ -95,18 +87,17 @@ package io.ebean;
*
*
* }</pre>
* <p>
*
* <h3>Example 2:</h3>
* <p>
* The following example uses a FetchConfig().query() so that after the initial
* RawSql query is executed Ebean executes a secondary query to fetch the
* associated order status, orderDate along with the customer name.
* </p>
* <p>
*
* <pre>{@code
*
* String sql = " select order_id, 'ignoreMe', sum(d.order_qty*d.unit_price) as totalAmount "
* + " from o_order_detail d"
* String sql = " select order_id, 'ignoreMe', sum(l.order_qty*l.unit_price) as totalAmount "
* + " from order_line l"
* + " group by order_id ";
*
* RawSql rawSql = RawSqlBuilder.parse(sql)
@@ -125,25 +116,23 @@ package io.ebean;
* .findList();
*
* }</pre>
* <p>
* <h3>Example 3: tableAliasMapping</h3>
* <p>
* Instead of mapping each column you can map each table alias to a path using tableAliasMapping().
* </p>
* <pre>{@code
*
* String rs = "select o.id, o.status, c.id, c.name, "+
* " d.id, d.order_qty, p.id, p.name " +
* "from o_order o join o_customer c on c.id = o.kcustomer_id " +
* "join o_order_detail d on d.order_id = o.id " +
* "join o_product p on p.id = d.product_id " +
* " l.id, l.order_qty, p.id, p.name " +
* "from orders o join o_customer c on c.id = o.customer_id " +
* "join order_line l on l.order_id = o.id " +
* "join product p on p.id = l.product_id " +
* "where o.id <= :maxOrderId and p.id = :productId "+
* "order by o.id, d.id asc";
* "order by o.id, l.id asc";
*
* RawSql rawSql = RawSqlBuilder.parse(rs)
* .tableAliasMapping("c", "customer")
* .tableAliasMapping("d", "details")
* .tableAliasMapping("p", "details.product")
* .tableAliasMapping("l", "lines")
* .tableAliasMapping("p", "lines.product")
* .create();
*
* List<Order> ordersFromRaw = DB.find(Order.class)
@@ -154,9 +143,7 @@ package io.ebean;
*
* }</pre>
* <p>
* <p>
* Note that lazy loading also works with object graphs built with RawSql.
* </p>
*/
public interface RawSql {
+1 -1
View File
@@ -22,7 +22,7 @@ import java.sql.SQLException;
* //
* class CustomerMapper implements RowMapper<CustomerDto> {
*
* @Override
* Override
* public CustomerDto map(ResultSet rset, int rowNum) throws SQLException {
*
* long id = rset.getLong(1);
+5 -5
View File
@@ -3,7 +3,7 @@ package io.ebean;
import io.ebean.annotation.DocStoreMode;
import io.ebean.annotation.PersistBatch;
import io.ebean.config.DocStoreConfig;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import javax.persistence.PersistenceException;
import java.sql.Connection;
@@ -226,7 +226,7 @@ public interface Transaction extends AutoCloseable {
/**
* Set if the L2 cache should be skipped for "find by id" and "find by natural key" queries.
* <p>
* By default {@link ServerConfig#isSkipCacheAfterWrite()} is true and that means that for
* By default {@link DatabaseConfig#isSkipCacheAfterWrite()} is true and that means that for
* "find by id" and "find by natural key" queries which normally hit L2 bean cache automatically
* - will not do so after a persist/write on the transaction.
* </p>
@@ -235,7 +235,7 @@ public interface Transaction extends AutoCloseable {
* will skip the L2 bean cache or not (regardless of whether the transaction is considered "read only").
* </p>
* <p>
* Refer to {@link ServerConfig#setSkipCacheAfterWrite(boolean)} for configuring the default behavior
* Refer to {@link DatabaseConfig#setSkipCacheAfterWrite(boolean)} for configuring the default behavior
* for using the L2 bean cache in transactions spanning multiple query/persist requests.
* </p>
*
@@ -276,7 +276,7 @@ public interface Transaction extends AutoCloseable {
*
* }</pre>
*
* @see ServerConfig#isSkipCacheAfterWrite()
* @see DatabaseConfig#isSkipCacheAfterWrite()
*/
void setSkipCache(boolean skipCache);
@@ -402,7 +402,7 @@ public interface Transaction extends AutoCloseable {
* </p>
*
* @param batchMode the batch mode to use per save(), insert(), update() or delete()
* @see io.ebean.config.ServerConfig#setPersistBatchOnCascade(PersistBatch)
* @see io.ebean.config.DatabaseConfig#setPersistBatchOnCascade(PersistBatch)
*/
void setBatchOnCascade(boolean batchMode);
+21 -20
View File
@@ -12,26 +12,27 @@ package io.ebean;
* The following is an example of named updates on an entity bean.
* </p>
* <pre>{@code
* ...
* @NamedUpdates(value = {
* @NamedUpdate(
* name = "setTitle",
* notifyCache = false,
* update = "update topic set title = :title, postCount = :count where id = :id"),
* @NamedUpdate(
* name = "setPostCount",
* notifyCache = false,
* update = "update f_topic set post_count = :postCount where id = :id"),
* @NamedUpdate(
* name = "incrementPostCount",
* notifyCache = false,
* update = "update Topic set postCount = postCount + 1 where id = :id")
* //update = "update f_topic set post_count = post_count + 1 where id = :id")
* })
* @Entity
* @Table(name = "f_topic")
* public class Topic {
* ...
* ...
* NamedUpdates(value = {
* NamedUpdate(
* name = "setTitle",
* notifyCache = false,
* update = "update topic set title = :title, postCount = :count where id = :id"),
* NamedUpdate(
* name = "setPostCount",
* notifyCache = false,
* update = "update f_topic set post_count = :postCount where id = :id"),
* NamedUpdate(
* name = "incrementPostCount",
* notifyCache = false,
* update = "update Topic set postCount = postCount + 1 where id = :id")
* //update = "update f_topic set post_count = post_count + 1 where id = :id")
* })
* Entity
* Table(name = "f_topic")
* public class Topic {
* ...
* }
* }</pre>
*
* <p>
+2 -2
View File
@@ -1,6 +1,6 @@
package io.ebean.cache;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
/**
* Plugin that provides a ServerCacheNotify implementation.
@@ -13,5 +13,5 @@ public interface ServerCacheNotifyPlugin {
/**
* Create a ServerCacheNotify implementation given the server configuration.
*/
ServerCacheNotify create(ServerConfig serverConfig);
ServerCacheNotify create(DatabaseConfig config);
}
+2 -2
View File
@@ -1,7 +1,7 @@
package io.ebean.cache;
import io.ebean.BackgroundExecutor;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
/**
* The plugin interface that creates a ServerCacheFactory.
@@ -11,5 +11,5 @@ public interface ServerCachePlugin {
/**
* Create the ServerCacheFactory given the server config and background executor service.
*/
ServerCacheFactory create(ServerConfig config, BackgroundExecutor executor);
ServerCacheFactory create(DatabaseConfig config, BackgroundExecutor executor);
}
@@ -3,8 +3,6 @@ package io.ebean.config;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.util.AnnotationUtil;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Inheritance;
import javax.persistence.Table;
@@ -16,10 +14,6 @@ import javax.persistence.Table;
*/
public abstract class AbstractNamingConvention implements NamingConvention {
private static final Pattern TABLE_REPLACE = Pattern.compile("{table}", Pattern.LITERAL);
private static final Pattern COLUMN_REPLACE = Pattern.compile("{column}", Pattern.LITERAL);
/**
* The Constant DEFAULT_SEQ_FORMAT.
*/
@@ -85,13 +79,9 @@ public abstract class AbstractNamingConvention implements NamingConvention {
@Override
public String getSequenceName(String rawTableName, String pkColumn) {
final String tableNameUnquoted = databasePlatform.unQuote(rawTableName);
String s = TABLE_REPLACE.matcher(sequenceFormat).replaceAll(Matcher.quoteReplacement(tableNameUnquoted));
if (pkColumn == null) {
pkColumn = "";
} else {
pkColumn = databasePlatform.unQuote(pkColumn);
}
return COLUMN_REPLACE.matcher(s).replaceAll(Matcher.quoteReplacement(pkColumn));
String seqName = sequenceFormat.replace("{table}", tableNameUnquoted);
pkColumn = (pkColumn == null) ? "" : databasePlatform.unQuote(pkColumn);
return seqName.replace("{column}", pkColumn);
}
/**
@@ -6,13 +6,13 @@ package io.ebean.config;
public interface AutoConfigure {
/**
* Perform configuration for the ServerConfig prior to properties load.
* Perform configuration for the DatabaseConfig prior to properties load.
*/
void preConfigure(ServerConfig serverConfig);
void preConfigure(DatabaseConfig config);
/**
* Provide some configuration the ServerConfig prior to server creation but after properties have been applied.
* Provide some configuration the DatabaseConfig prior to server creation but after properties have been applied.
*/
void postConfigure(ServerConfig serverConfig);
void postConfigure(DatabaseConfig config);
}
@@ -147,7 +147,7 @@ public class ClassLoadConfig {
ClassLoaderContext(ClassLoader preferredLoader) {
this.preferredLoader = preferredLoader;
this.callerLoader = ServerConfig.class.getClassLoader();
this.callerLoader = DatabaseConfig.class.getClassLoader();
this.contextLoader = contextLoader();
}
@@ -6,7 +6,7 @@ import io.ebean.annotation.Platform;
/**
* Custom mappings for DB types that override the default.
*
* @see ServerConfig#addCustomMapping(DbType, String)
* @see DatabaseConfig#addCustomMapping(DbType, String)
*/
public class CustomDbTypeMapping {
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,39 @@
package io.ebean.config;
/**
* Provides a ServiceLoader based mechanism to configure a DatabaseConfig.
* <p>
* Provide an implementation and register it via the standard Java ServiceLoader mechanism
* via a file at <code>META-INF/services/io.ebean.config.DatabaseConfigProvider</code>.
* </p>
* <p>
* If you are using a DI container like Spring or Guice you are unlikely to use this but instead use a
* spring specific configuration. When we are not using a DI container we may use this mechanism to
* explicitly register the entity beans and avoid classpath scanning.
* </p>
* <pre>{@code
*
* public class EbeanConfigProvider implements DatabaseConfigProvider {
*
* Override
* public void apply(DatabaseConfig config) {
*
* // register the entity bean classes explicitly
* config.addClass(Customer.class);
* config.addClass(User.class);
* ...
* }
* }
*
* }</pre>
*/
public interface DatabaseConfigProvider {
/**
* Apply the configuration to the DatabaseConfig.
* <p>
* Typically we explicitly register entity bean classes and thus avoid classpath scanning.
* </p>
*/
void apply(DatabaseConfig config);
}
@@ -13,6 +13,8 @@ import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.Properties;
import static io.ebean.util.StringHelper.replace;
/**
* Configuration for the DB migration processing.
*/
@@ -375,8 +377,8 @@ public class DbMigrationConfig {
*/
public String getDdlHeader() {
if (ddlHeader != null && !ddlHeader.isEmpty()) {
ddlHeader = StringHelper.replaceString(ddlHeader, "${version}", EbeanVersion.getVersion());
ddlHeader = StringHelper.replaceString(ddlHeader, "${timestamp}", ZonedDateTime.now().format( DateTimeFormatter.ISO_INSTANT ));
ddlHeader = replace(ddlHeader, "${version}", EbeanVersion.getVersion());
ddlHeader = replace(ddlHeader, "${timestamp}", ZonedDateTime.now().format( DateTimeFormatter.ISO_INSTANT ));
}
return ddlHeader;
}
@@ -249,10 +249,10 @@ public class PlatformConfig {
* <pre>{@code
*
* // set the default mapping for BigDecimal.class/decimal
* serverConfig.addCustomMapping(DbType.DECIMAL, "decimal(18,6)");
* config.addCustomMapping(DbType.DECIMAL, "decimal(18,6)");
*
* // set the default mapping for String.class/varchar but only for Postgres
* serverConfig.addCustomMapping(DbType.VARCHAR, "text", Platform.POSTGRES);
* config.addCustomMapping(DbType.VARCHAR, "text", Platform.POSTGRES);
*
* }</pre>
*
@@ -270,10 +270,10 @@ public class PlatformConfig {
* <pre>{@code
*
* // set the default mapping for BigDecimal/decimal
* serverConfig.addCustomMapping(DbType.DECIMAL, "decimal(18,6)");
* config.addCustomMapping(DbType.DECIMAL, "decimal(18,6)");
*
* // set the default mapping for String/varchar
* serverConfig.addCustomMapping(DbType.VARCHAR, "text");
* config.addCustomMapping(DbType.VARCHAR, "text");
*
* }</pre>
*
File diff suppressed because it is too large Load Diff
@@ -1,11 +1,12 @@
package io.ebean.config;
/**
* Deprecated - migrate to DatabaseConfigProvider.
* <p>
* Provides a ServiceLoader based mechanism to configure a ServerConfig.
* <p>
* Provide an implementation and register it via the standard Java ServiceLoader mechanism
* via a file at <code>META-INF/services/io.ebean.config.ServerConfigProvider</code>.
* </p>
* <p>
* If you are using a DI container like Spring or Guice you are unlikely to use this but instead use a
* spring specific configuration. When we are not using a DI container we may use this mechanism to
@@ -15,7 +16,7 @@ package io.ebean.config;
*
* public class EbeanConfigProvider implements ServerConfigProvider {
*
* @Override
* Override
* public void apply(ServerConfig config) {
*
* // register the entity bean classes explicitly
@@ -27,6 +28,7 @@ package io.ebean.config;
*
* }</pre>
*/
@Deprecated
public interface ServerConfigProvider {
/**
@@ -242,7 +242,7 @@ public class DatabasePlatform {
}
/**
* Configure UUID Storage etc based on ServerConfig settings.
* Configure UUID Storage etc based on DatabaseConfig settings.
*/
protected void configure(PlatformConfig config, boolean allQuotedIdentifiers) {
this.allQuotedIdentifiers = allQuotedIdentifiers;
@@ -1,8 +1,5 @@
package io.ebean.config.dbplatform;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Defines the identity/sequence behaviour for the database.
*/
@@ -10,8 +7,6 @@ public class DbIdentity {
private static final String TABLE_PLACEHOLDER = "{table}";
private static final Pattern TABLE_REPLACE = Pattern.compile(TABLE_PLACEHOLDER, Pattern.LITERAL);
/**
* Set if this DB supports sequences. Note some DB's support both Sequences
* and Identity.
@@ -55,10 +50,7 @@ public class DbIdentity {
if (selectLastInsertedIdTemplate == null) {
return null;
}
if (!selectLastInsertedIdTemplate.contains(TABLE_PLACEHOLDER)) {
return selectLastInsertedIdTemplate;
}
return TABLE_REPLACE.matcher(selectLastInsertedIdTemplate).replaceAll(Matcher.quoteReplacement(table));
return selectLastInsertedIdTemplate.replace(TABLE_PLACEHOLDER, table);
}
/**
@@ -205,7 +205,7 @@ public class DbPlatformTypeMapping {
}
/**
* Map the UUID appropriately based on native DB support and ServerConfig.DbUuid.
* Map the UUID appropriately based on native DB support and DatabaseConfig.DbUuid.
*/
public void config(boolean nativeUuidType, PlatformConfig.DbUuid dbUuid) {
if (nativeUuidType && dbUuid.useNativeType()) {
@@ -5,7 +5,7 @@ import io.ebean.config.dbplatform.DbStandardHistorySupport;
/**
* History support only valid on SqlServer 2016 or later.
*
* @author Vilmos Nagy <vilmos.nagy@outlook.com>
* @author Vilmos Nagy
*/
public class SqlServerHistorySupport extends DbStandardHistorySupport {
@@ -2,7 +2,7 @@ package io.ebean.dbmigration;
import io.ebean.Database;
import io.ebean.annotation.Platform;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import java.io.IOException;
@@ -86,9 +86,9 @@ public interface DbMigration {
void setServer(Database database);
/**
* Set the serverConfig to use. Typically this is not called explicitly.
* Set the DatabaseConfig to use. Typically this is not called explicitly.
*/
void setServerConfig(ServerConfig config);
void setServerConfig(DatabaseConfig config);
/**
* Set the specific platform to generate DDL for.
@@ -1,6 +1,6 @@
package io.ebean.event;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
/**
* A no operation implementation of BeanPersistController. Objects extending
@@ -8,8 +8,8 @@ import io.ebean.config.ServerConfig;
* <p>
* A BeanPersistAdapter is either found automatically via class path search or
* can be added programmatically via
* {@link ServerConfig#add(BeanPersistController)} or
* {@link ServerConfig#setPersistControllers(java.util.List)}.
* {@link DatabaseConfig#add(BeanPersistController)} or
* {@link DatabaseConfig#setPersistControllers(java.util.List)}.
* </p>
*/
public abstract class BeanPersistAdapter implements BeanPersistController {
@@ -22,6 +22,7 @@ package io.ebean.event;
* <p>
* It is worth noting that BeanPersistListener is different in three main ways
* from BeanPersistController postXXX methods.
* </p>
* <ul>
* <li>BeanPersistListener only sees successfully committed events.
* BeanController pre and post methods occur before the commit or a rollback and
@@ -31,10 +32,9 @@ package io.ebean.event;
* <li>BeanPersistListener can be notified of events from other servers in a
* cluster.</li>
* </ul>
* </p>
* <p>
* A BeanPersistController is either found automatically via class path search
* or can be added programmatically via ServerConfiguration.addEntity().
* or can be added programmatically via DatabaseConfig.add().
* </p>
*/
public interface BeanPersistController {
@@ -1,6 +1,6 @@
package io.ebean.event;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import java.util.Set;
@@ -29,10 +29,10 @@ import java.util.Set;
* </p>
* <p>
* A BeanPersistListener is either found automatically via class path search or
* can be added programmatically via {@link ServerConfig#add(BeanPersistListener)}}.
* can be added programmatically via {@link DatabaseConfig#add(BeanPersistListener)}}.
* </p>
*
* @see ServerConfig#add(BeanPersistListener)
* @see DatabaseConfig#add(BeanPersistListener)
*/
public interface BeanPersistListener {
@@ -1,6 +1,6 @@
package io.ebean.event;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
/**
* Objects extending this modify queries prior their execution.
@@ -10,7 +10,7 @@ import io.ebean.config.ServerConfig;
* </p>
* <p>
* A BeanQueryAdapter is either found automatically via class path search or can
* be added programmatically via {@link ServerConfig#add(BeanQueryAdapter)}.
* be added programmatically via {@link DatabaseConfig#add(BeanQueryAdapter)}.
* </p>
* <p>
* Note that a BeanQueryAdapter should be thread safe (stateless) and if
@@ -1,6 +1,6 @@
package io.ebean.event;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
/**
* Used to configure the server on startup.
@@ -11,8 +11,8 @@ import io.ebean.config.ServerConfig;
public interface ServerConfigStartup {
/**
* On starting configure the ServerConfig.
* On starting configure the DatabaseConfig.
*/
void onStart(ServerConfig serverConfig);
void onStart(DatabaseConfig config);
}
@@ -52,7 +52,7 @@ public interface MetaInfoManager {
/**
* Initiate query plan collection by turning on "bind capture" on matching query plans.
* <p>
* Also refer to ServerConfig collectQueryPlans that needs to be set to true
* Also refer to DatabaseConfig collectQueryPlans that needs to be set to true
* and collectQueryPlanThresholdMicros which is a global defaults that can also
* initiate query plan capture.
*
+3 -3
View File
@@ -3,7 +3,7 @@ package io.ebean.plugin;
import io.ebean.EbeanServer;
import io.ebean.bean.BeanLoader;
import io.ebean.bean.EntityBeanIntercept;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import javax.sql.DataSource;
@@ -15,9 +15,9 @@ import java.util.List;
public interface SpiServer extends EbeanServer, BeanLoader {
/**
* Return the serverConfig.
* Return the DatabaseConfig.
*/
ServerConfig getServerConfig();
DatabaseConfig getServerConfig();
/**
* Return the DatabasePlatform for this database.
@@ -1,7 +1,7 @@
package io.ebean.service;
import io.ebean.EbeanServer;
import io.ebean.config.ServerConfig;
import io.ebean.Database;
import io.ebean.config.DatabaseConfig;
/**
* Creates the Database implementations. This is used internally by the EbeanServerFactory and is not currently
@@ -14,7 +14,7 @@ public interface SpiContainer {
*
* @param configuration The configuration information for this database.
*/
EbeanServer createServer(ServerConfig configuration);
Database createServer(DatabaseConfig configuration);
/**
* Create an EbeanServer just using the name.
@@ -23,7 +23,7 @@ public interface SpiContainer {
* avaje.properties file.
* </p>
*/
EbeanServer createServer(String name);
Database createServer(String name);
/**
* Shutdown any Ebean wide resources such as clustering.
@@ -1,6 +1,6 @@
package io.ebean.text.csv;
import io.ebean.EbeanServer;
import io.ebean.Database;
/**
* Provides callback methods for customisation of CSV processing.
@@ -8,9 +8,6 @@ import io.ebean.EbeanServer;
* You can provide your own CsvCallback implementation to customise the CSV
* processing. It is expected that the DefaultCsvCallback provides a good base
* class that you can extend.
* </p>
*
* @param <T>
*/
public interface CsvCallback<T> {
@@ -21,7 +18,7 @@ public interface CsvCallback<T> {
* size etc.
* </p>
*/
void begin(EbeanServer server);
void begin(Database database);
/**
* Read the header row.
@@ -73,8 +70,8 @@ public interface CsvCallback<T> {
* was created.
* </p>
*
* @param row the row that the error has occured on
* @param e the error that occured
* @param row the row that the error has occurred on
* @param e the error that occurred
*/
void endWithError(int row, Exception e);
@@ -1,6 +1,6 @@
package io.ebean.text.csv;
import io.ebean.EbeanServer;
import io.ebean.Database;
import io.ebean.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,7 +35,7 @@ public class DefaultCsvCallback<T> implements CsvCallback<T> {
/**
* The EbeanServer used to save the beans.
*/
protected EbeanServer server;
protected Database server;
/**
* Used to log a message to indicate progress through large files.
@@ -69,7 +69,6 @@ public class DefaultCsvCallback<T> implements CsvCallback<T> {
* Construct with explicit batch size and logging info frequency.
*/
public DefaultCsvCallback(int persistBatchSize, int logInfoFrequency) {
this.persistBatchSize = persistBatchSize;
this.logInfoFrequency = logInfoFrequency;
}
@@ -78,10 +77,9 @@ public class DefaultCsvCallback<T> implements CsvCallback<T> {
* Create a transaction if required.
*/
@Override
public void begin(EbeanServer server) {
public void begin(Database server) {
this.server = server;
this.startTime = System.currentTimeMillis();
initTransactionIfRequired();
}
@@ -73,14 +73,14 @@ public class JsonReadOptions {
}
/**
* Return the Jackson ObjectMapper to use (if not wanted to use the objectMapper set on the ServerConfig).
* Return the Jackson ObjectMapper to use (if not wanted to use the objectMapper set on the DatabaseConfig).
*/
public Object getObjectMapper() {
return objectMapper;
}
/**
* Set the Jackson ObjectMapper to use (if not wanted to use the objectMapper set on the ServerConfig).
* Set the Jackson ObjectMapper to use (if not wanted to use the objectMapper set on the DatabaseConfig).
*/
public JsonReadOptions setObjectMapper(Object objectMapper) {
this.objectMapper = objectMapper;
@@ -101,7 +101,7 @@ public class JsonWriteOptions {
/**
* Return the jackson object mapper to use.
* <p/>
* If null the ObjectMapper from serverConfig will be used.
* If null the ObjectMapper from DatabaseConfig will be used.
*/
public Object getObjectMapper() {
return objectMapper;
@@ -110,7 +110,7 @@ public class JsonWriteOptions {
/**
* Set the jackson object mapper to use.
* <p/>
* If null the ObjectMapper from serverConfig will be used.
* If null the ObjectMapper from DatabaseConfig will be used.
*/
public void setObjectMapper(Object objectMapper) {
this.objectMapper = objectMapper;
+56 -388
View File
@@ -1,6 +1,5 @@
package io.ebean.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
@@ -10,152 +9,10 @@ import java.util.regex.Pattern;
*/
public class StringHelper {
private static final char SINGLE_QUOTE = '\'';
private static final char DOUBLE_QUOTE = '"';
private static final Pattern SPLIT_NAMES = Pattern.compile("[\\s,;]+");
private static final String[] EMPTY_STRING_ARRAY = new String[0];
/**
* parses a String of the form name1='value1' name2='value2'. Note that you
* can use either single or double quotes for any particular name value pair
* and the end quote must match the begin quote.
*/
public static HashMap<String, String> parseNameQuotedValue(String tag) throws RuntimeException {
if (tag == null || tag.length() < 1) {
return null;
}
// make sure that the quotes are matched...
// int remainer = countOccurances(tag, ""+quote) % 2;
// if (remainer == 1) {
// dp("remainder = "+remainer);
// throw new StringParsingException("Unmatched quote in "+tag);
// }
// make sure that th last character is not an equals...
// (check now so I don't need to check this every time..)
if (tag.charAt(tag.length() - 1) == '=') {
throw new RuntimeException("missing quoted value at the end of " + tag);
}
HashMap<String, String> map = new HashMap<>();
// recursively parse out the name value pairs...
return parseNameQuotedValue(map, tag, 0);
}
/**
* recursively parse out name value pairs (where the value is quoted, with
* either single or double quotes).
*/
private static HashMap<String, String> parseNameQuotedValue(HashMap<String, String> map,
String tag, int pos) throws RuntimeException {
while (true) {
int equalsPos = tag.indexOf('=', pos);
if (equalsPos > -1) {
// check for begin quote...
char firstQuote = tag.charAt(equalsPos + 1);
if (firstQuote != SINGLE_QUOTE && firstQuote != DOUBLE_QUOTE) {
throw new RuntimeException("missing begin quote at " + (equalsPos) + "["
+ tag.charAt(equalsPos + 1) + "] in [" + tag + "]");
}
// check for end quote...
int endQuotePos = tag.indexOf(firstQuote, equalsPos + 2);
if (endQuotePos == -1) {
throw new RuntimeException("missing end quote [" + firstQuote + "] after " + pos + " in [" + tag + "]");
}
// we have a valid name and value...
// dp("pos="+pos+" equalsPos="+equalsPos+"
// endQuotePos="+endQuotePos);
String name = tag.substring(pos, equalsPos);
// dp("name="+name+"; value="+value+";");
// trim off any whitespace from the front of name...
name = trimFront(name, " ");
if ((name.indexOf(SINGLE_QUOTE) > -1) || (name.indexOf(DOUBLE_QUOTE) > -1)) {
throw new RuntimeException("attribute name contains a quote [" + name + "]");
}
String value = tag.substring(equalsPos + 2, endQuotePos);
map.put(name, value);
pos = endQuotePos + 1;
} else {
// no more equals... stop parsing...
return map;
}
}
}
/**
* Returns the number of times a particular String occurs in another String.
* e.g. count the number of single quotes.
*/
public static int countOccurances(String content, String occurs) {
return countOccurances(content, occurs, 0, 0);
}
private static int countOccurances(String content, String occurs, int pos, int countSoFar) {
while (true) {
int equalsPos = content.indexOf(occurs, pos);
if (equalsPos > -1) {
countSoFar += 1;
pos = equalsPos + occurs.length();
// dp("countSoFar="+countSoFar+" pos="+pos);
} else {
return countSoFar;
}
}
}
/**
* Parses out a list of Name Value pairs that are delimited together. Will
* always return a StringMap. If allNameValuePairs is null, or no name values
* can be parsed out an empty StringMap is returned.
*
* @param allNameValuePairs the entire string to be parsed.
* @param listDelimiter (typically ';') the delimited between the list
* @param nameValueSeparator (typically '=') the separator between the name and value
*/
public static Map<String, String> delimitedToMap(String allNameValuePairs,
String listDelimiter, String nameValueSeparator) {
HashMap<String, String> params = new HashMap<>();
if ((allNameValuePairs == null) || (allNameValuePairs.isEmpty())) {
return params;
}
// trim off any leading listDelimiter...
allNameValuePairs = trimFront(allNameValuePairs, listDelimiter);
return getKeyValue(params, 0, allNameValuePairs, listDelimiter, nameValueSeparator);
}
/**
* Trims off recurring strings from the front of a string.
*
* @param source the source string
* @param trim the string to trim off the front
*/
public static String trimFront(String source, String trim) {
while (true) {
if (source == null) {
return null;
}
if (source.indexOf(trim) == 0) {
// dp("trim ...");
source = source.substring(trim.length());
} else {
return source;
}
}
}
/**
* Return true if the value is null or an empty string.
*/
@@ -163,110 +20,76 @@ public class StringHelper {
return value == null || value.trim().isEmpty();
}
/**
* Parses out a list of Name Value pairs that are delimited together. Will
* always return a StringMap. If allNameValuePairs is null, or no name values
* can be parsed out an empty StringMap is returned.
*
* @param source the entire string to be parsed.
* @param listDelimiter (typically ';') the delimited between the list
* @param nameValueSeparator (typically '=') the separator between the name and value
*/
public static Map<String, String> delimitedToMap(String source, String listDelimiter, String nameValueSeparator) {
Map<String, String> params = new HashMap<>();
if (source == null || source.isEmpty()) {
return params;
}
// trim off any leading listDelimiter...
source = trimFront(source, listDelimiter);
return delimitedToMap(params, source, listDelimiter, nameValueSeparator);
}
/**
* Trims off recurring strings from the front of a string.
*
* @param source the source string
* @param trim the string to trim off the front
*/
private static String trimFront(String source, String trim) {
while (true) {
if (source.indexOf(trim) == 0) {
source = source.substring(trim.length());
} else {
return source;
}
}
}
/**
* Recursively pulls out the key value pairs from a raw string.
*/
private static HashMap<String, String> getKeyValue(HashMap<String, String> map, int pos,
String allNameValuePairs, String listDelimiter, String nameValueSeparator) {
private static Map<String, String> delimitedToMap(Map<String, String> map, String source, String listDelimiter, String nameValueSeparator) {
int pos = 0;
while (true) {
if (pos >= allNameValuePairs.length()) {
// dp("end as "+pos+" >= "+allNameValuePairs.length() );
if (pos >= source.length()) {
return map;
}
int equalsPos = allNameValuePairs.indexOf(nameValueSeparator, pos);
int delimPos = allNameValuePairs.indexOf(listDelimiter, pos);
int equalsPos = source.indexOf(nameValueSeparator, pos);
int delimPos = source.indexOf(listDelimiter, pos);
if (delimPos == -1) {
delimPos = allNameValuePairs.length();
delimPos = source.length();
}
if (equalsPos == -1) {
// dp("no more equals...");
return map;
}
if (delimPos == (equalsPos + 1)) {
// dp("Ignoring as nothing between delim and equals...
// delim:"+delimPos+" eq:"+equalsPos);
pos = delimPos + 1;
continue;
}
if (equalsPos > delimPos) {
// there is a key without a value?
String key = allNameValuePairs.substring(pos, delimPos);
String key = source.substring(pos, delimPos);
key = key.trim();
if (!key.isEmpty()) {
map.put(key, null);
}
pos = delimPos + 1;
continue;
}
String key = allNameValuePairs.substring(pos, equalsPos);
if (delimPos > -1) {
String value = allNameValuePairs.substring(equalsPos + 1, delimPos);
// dp("cont "+key+","+value+" pos:"+pos+"
// len:"+allNameValuePairs.length());
key = key.trim();
map.put(key, value);
pos = delimPos + 1;
// recurse the rest of the values...
} else {
// dp("ERROR: delimPos < 0 ???");
return map;
}
}
}
/**
* Convert a string that has delimited values (say comma delimited) in a
* String[]. You must explicitly choose whether or not to include empty values
* (say two commas that a right beside each other.
* <p>
* e.g. "alpha,beta,,theta"<br>
* With keepEmpties true, this results in a String[] of size 4 with the third
* one having a String of 0 length. With keepEmpties false, this results in a
* String[] of size 3.
* <p>
* e.g. ",alpha,beta,,theta,"<br>
* With keepEmpties true, this results in a String[] of size 6 with the
* 1st,4th and 6th one having a String of 0 length. With keepEmpties false,
* this results in a String[] of size 3.
*/
public static String[] delimitedToArray(String str, String delimiter, boolean keepEmpties) {
ArrayList<String> list = new ArrayList<>();
int startPos = 0;
delimiter(str, delimiter, keepEmpties, startPos, list);
String[] result = new String[list.size()];
return list.toArray(result);
}
private static void delimiter(String str, String delimiter, boolean keepEmpties, int startPos,
ArrayList<String> list) {
int endPos = str.indexOf(delimiter, startPos);
if (endPos == -1) {
if (startPos <= str.length()) {
String lastValue = str.substring(startPos, str.length());
if (keepEmpties || !lastValue.isEmpty()) {
list.add(lastValue);
}
}
// we have finished parsing the string...
} else {
// get the delimited value... add it..
String value = str.substring(startPos, endPos);
if (keepEmpties || !value.isEmpty()) {
list.add(value);
}
// recursively search as we are not at the end yet...
delimiter(str, delimiter, keepEmpties, endPos + 1, list);
String key = source.substring(pos, equalsPos);
String value = source.substring(equalsPos + 1, delimPos);
map.put(key.trim(), value);
pos = delimPos + 1;
}
}
@@ -279,177 +102,22 @@ public class StringHelper {
* @param replace the string used to replace match with
* @return the source string after the search and replace
*/
public static String replaceString(String source, String match, String replace) {
public static String replace(String source, String match, String replace) {
if (source == null) {
return null;
}
if (replace == null) {
return source;
}
if (match == null) {
throw new NullPointerException("match is null?");
}
if (match.equals(replace)) {
return source;
}
return replaceString(source, match, replace, 30, 0, source.length());
return source.replace(match, replace);
}
/**
* Additionally specify the additionalSize to add to the buffer. This will
* make the buffer bigger so that it doesn't have to grow when replacement
* occurs.
* Return new line and carriage return with space.
*/
public static String replaceString(String source, String match, String replace,
int additionalSize, int startPos, int endPos) {
if (source == null) {
return null;
}
char match0 = match.charAt(0);
int matchLength = match.length();
if (matchLength == 1 && replace.length() == 1) {
char replace0 = replace.charAt(0);
return source.replace(match0, replace0);
}
if (matchLength >= replace.length()) {
additionalSize = 0;
}
int sourceLength = source.length();
int lastMatch = endPos - matchLength;
StringBuilder sb = new StringBuilder(sourceLength + additionalSize);
if (startPos > 0) {
sb.append(source.substring(0, startPos));
}
char sourceChar;
boolean isMatch;
int sourceMatchPos;
for (int i = startPos; i < sourceLength; i++) {
sourceChar = source.charAt(i);
if (i > lastMatch || sourceChar != match0) {
sb.append(sourceChar);
} else {
// check to see if this is a match
isMatch = true;
sourceMatchPos = i;
// check each following character...
for (int j = 1; j < matchLength; j++) {
sourceMatchPos++;
if (source.charAt(sourceMatchPos) != match.charAt(j)) {
isMatch = false;
break;
}
}
if (isMatch) {
i = i + matchLength - 1;
sb.append(replace);
} else {
// was not a match
sb.append(sourceChar);
}
}
}
return sb.toString();
}
/**
* A search and replace with multiple matching strings.
* <p>
* Useful when converting CRNL CR and NL all to a BR tag for example.
* <pre>{@code
*
* String[] multi = { "\r\n", "\r", "\n" };
* content = StringHelper.replaceStringMulti(content, multi, "<br/>");
*
* }</pre>
*/
public static String replaceStringMulti(String source, String[] match, String replace) {
if (source == null) {
return null;
}
return replaceStringMulti(source, match, replace, 30, 0, source.length());
}
/**
* Additionally specify an additional size estimate for the buffer plus start
* and end positions.
* <p>
* The start and end positions can limit the search and replace. Otherwise
* these default to startPos = 0 and endPos = source.length().
* </p>
*/
public static String replaceStringMulti(String source, String[] match, String replace,
int additionalSize, int startPos, int endPos) {
if (source == null) {
return null;
}
int shortestMatch = match[0].length();
char[] match0 = new char[match.length];
for (int i = 0; i < match0.length; i++) {
match0[i] = match[i].charAt(0);
if (match[i].length() < shortestMatch) {
shortestMatch = match[i].length();
}
}
StringBuilder sb = new StringBuilder(source.length() + additionalSize);
char sourceChar;
int len = source.length();
int lastMatch = endPos - shortestMatch;
if (startPos > 0) {
sb.append(source.substring(0, startPos));
}
int matchCount;
for (int i = startPos; i < len; i++) {
sourceChar = source.charAt(i);
if (i > lastMatch) {
sb.append(sourceChar);
} else {
matchCount = 0;
for (int k = 0; k < match0.length; k++) {
if (matchCount == 0 && sourceChar == match0[k]) {
if (match[k].length() + i <= len) {
++matchCount;
int j = 1;
for (; j < match[k].length(); j++) {
if (source.charAt(i + j) != match[k].charAt(j)) {
--matchCount;
break;
}
}
if (matchCount > 0) {
i = i + j - 1;
sb.append(replace);
break;
}
}
}
}
if (matchCount == 0) {
sb.append(sourceChar);
}
}
}
return sb.toString();
public static String removeNewLines(String source) {
source = source.replace('\n', ' ');
return source.replace('\r', ' ');
}
/**
@@ -462,13 +130,13 @@ public class StringHelper {
}
String[] result = SPLIT_NAMES.split(names);
if (result.length == 0) {
return EMPTY_STRING_ARRAY; // don't know if this ever can happen
return EMPTY_STRING_ARRAY;
}
if ("".equals(result[0])) { // = input string starts with whitespace
if (result.length == 1) { // = input string contains only whitespace
if ("".equals(result[0])) { // input string starts with whitespace
if (result.length == 1) { // input string contains only whitespace
return EMPTY_STRING_ARRAY;
} else {
String ret[] = new String[result.length-1]; // remove first entry
String[] ret = new String[result.length-1]; // remove first entry
System.arraycopy(result, 1, ret, 0, ret.length);
return ret;
}
@@ -1,6 +1,6 @@
package io.ebeaninternal.api;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.server.type.ScalarType;
import java.util.List;
@@ -13,5 +13,5 @@ public interface ExtraTypeFactory {
/**
* Provide extra types to Ebean.
*/
List<? extends ScalarType<?>> createTypes(ServerConfig config, Object objectMapper);
List<? extends ScalarType<?>> createTypes(DatabaseConfig config, Object objectMapper);
}
@@ -2,6 +2,7 @@ package io.ebeaninternal.api;
import io.ebean.bean.BeanCollection;
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
/**
* Controls the loading of ManyToOne and OneToOne relationships.
@@ -11,5 +12,5 @@ public interface LoadBeanContext extends LoadSecondaryQuery {
/**
* Register a BeanCollection into the load context.
*/
void register(String manyProperty, BeanCollection<?> collection);
void register(BeanPropertyAssocMany<?> many, BeanCollection<?> collection);
}
@@ -5,6 +5,7 @@ import io.ebean.bean.EntityBeanIntercept;
import io.ebean.bean.ObjectGraphNode;
import io.ebean.bean.PersistenceContext;
import io.ebeaninternal.server.core.OrmQueryRequest;
import io.ebeaninternal.server.deploy.BeanPropertyAssocMany;
import io.ebeaninternal.server.deploy.BeanPropertyAssocOne;
/**
@@ -56,6 +57,5 @@ public interface LoadContext {
/**
* Register a collection for lazy loading.
*/
void register(String path, BeanCollection<?> bc);
void register(String path, BeanPropertyAssocMany<?> many, BeanCollection<?> bc);
}
@@ -2,7 +2,6 @@ package io.ebeaninternal.api;
import io.ebean.bean.BeanCollection;
import io.ebean.bean.EntityBean;
import io.ebean.util.StringHelper;
import io.ebeaninternal.server.core.BindPadding;
import io.ebeaninternal.server.core.OrmQueryRequest;
import io.ebeaninternal.server.deploy.BeanDescriptor;
@@ -125,8 +124,7 @@ public class LoadManyRequest extends LoadRequest {
if (extraWhere != null) {
// replace special ${ta} placeholder with the base table alias
// which is always t0 and add the extra where clause
String ew = StringHelper.replaceString(extraWhere, "${ta}", "t0");
query.where().raw(ew);
query.where().raw(extraWhere.replace("${ta}", "t0"));
}
query.setLazyLoadForParents(many);
@@ -10,9 +10,8 @@ import io.ebean.RowMapper;
import io.ebean.Transaction;
import io.ebean.TxScope;
import io.ebean.bean.BeanCollectionLoader;
import io.ebean.bean.BeanLoader;
import io.ebean.bean.CallOrigin;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.event.readaudit.ReadAuditLogger;
import io.ebean.event.readaudit.ReadAuditPrepare;
@@ -33,6 +32,11 @@ import java.util.function.Predicate;
*/
public interface SpiEbeanServer extends ExtendedServer, EbeanServer, BeanCollectionLoader {
/**
* Return true if the L2 cache has been disabled.
*/
boolean isDisableL2Cache();
/**
* Return the log manager.
*/
@@ -61,7 +65,7 @@ public interface SpiEbeanServer extends ExtendedServer, EbeanServer, BeanCollect
/**
* Return the server configuration.
*/
ServerConfig getServerConfig();
DatabaseConfig getServerConfig();
/**
* Return the DatabasePlatform for this server.
@@ -856,6 +856,11 @@ public interface SpiQuery<T> extends Query<T>, TxnProfileEventCodes {
*/
String getAlias();
/**
* Return root table alias with default option.
*/
String getAlias(String defaultAlias);
/**
* Validate the query returning the set of properties with unknown paths.
*/
@@ -100,7 +100,7 @@ public interface SpiTransaction extends Transaction {
/**
* Return true if this transaction has updateAllLoadedProperties set.
* If null is returned the server default is used (set on ServerConfig).
* If null is returned the server default is used (set on DatabaseConfig).
*/
Boolean isUpdateAllLoadedProperties();
@@ -1,8 +1,8 @@
package io.ebeaninternal.dbmigration;
import io.ebean.annotation.Platform;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DbMigrationConfig;
import io.ebean.config.ServerConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.migration.ddl.DdlRunner;
import io.ebean.migration.runner.ScriptTransform;
@@ -56,25 +56,25 @@ public class DdlGenerator {
private String createAllContent;
private File baseDir;
public DdlGenerator(SpiEbeanServer server, ServerConfig serverConfig) {
public DdlGenerator(SpiEbeanServer server, DatabaseConfig config) {
this.server = server;
this.jaxbPresent = serverConfig.getClassLoadConfig().isJavaxJAXBPresent();
this.generateDdl = serverConfig.isDdlGenerate();
this.extraDdl = serverConfig.isDdlExtra();
this.createOnly = serverConfig.isDdlCreateOnly();
this.dbSchema = serverConfig.getDbSchema();
this.jaxbPresent = config.getClassLoadConfig().isJavaxJAXBPresent();
this.generateDdl = config.isDdlGenerate();
this.extraDdl = config.isDdlExtra();
this.createOnly = config.isDdlCreateOnly();
this.dbSchema = config.getDbSchema();
final DatabasePlatform databasePlatform = server.getDatabasePlatform();
this.platform = databasePlatform.getPlatform();
this.platformName = platform.base().name();
if (!serverConfig.getTenantMode().isDdlEnabled() && serverConfig.isDdlRun()) {
log.warn("DDL can't be run on startup with TenantMode " + serverConfig.getTenantMode());
if (!config.getTenantMode().isDdlEnabled() && config.isDdlRun()) {
log.warn("DDL can't be run on startup with TenantMode " + config.getTenantMode());
this.runDdl = false;
this.ddlAutoCommit = false;
} else {
this.runDdl = serverConfig.isDdlRun();
this.runDdl = config.isDdlRun();
this.ddlAutoCommit = databasePlatform.isDdlAutoCommit();
}
this.scriptTransform = createScriptTransform(serverConfig.getMigrationConfig());
this.scriptTransform = createScriptTransform(config.getMigrationConfig());
this.baseDir = initBaseDir();
}
@@ -4,10 +4,10 @@ import io.ebean.DB;
import io.ebean.Database;
import io.ebean.EbeanServer;
import io.ebean.annotation.Platform;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DbConstraintNaming;
import io.ebean.config.DbMigrationConfig;
import io.ebean.config.PlatformConfig;
import io.ebean.config.ServerConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.clickhouse.ClickHousePlatform;
import io.ebean.config.dbplatform.cockroach.CockroachPlatform;
@@ -104,7 +104,7 @@ public class DefaultDbMigration implements DbMigration {
protected List<Pair> platforms = new ArrayList<>();
protected ServerConfig serverConfig;
protected DatabaseConfig databaseConfig;
protected DbConstraintNaming constraintNaming;
@@ -161,18 +161,18 @@ public class DefaultDbMigration implements DbMigration {
}
/**
* Set the serverConfig to use. Typically this is not called explicitly.
* Set the DatabaseConfig to use. Typically this is not called explicitly.
*/
@Override
public void setServerConfig(ServerConfig config) {
if (this.serverConfig == null) {
this.serverConfig = config;
public void setServerConfig(DatabaseConfig config) {
if (this.databaseConfig == null) {
this.databaseConfig = config;
}
if (migrationConfig == null) {
this.migrationConfig = serverConfig.getMigrationConfig();
this.migrationConfig = databaseConfig.getMigrationConfig();
}
if (constraintNaming == null) {
this.constraintNaming = serverConfig.getConstraintNaming();
this.constraintNaming = databaseConfig.getConstraintNaming();
}
}
@@ -383,7 +383,7 @@ public class DefaultDbMigration implements DbMigration {
*/
private void configurePlatforms() {
for (Pair pair : platforms) {
PlatformConfig config = serverConfig.newPlatformConfig("dbmigration.platform", pair.prefix);
PlatformConfig config = databaseConfig.newPlatformConfig("dbmigration.platform", pair.prefix);
pair.platform.configure(config);
}
}
@@ -660,7 +660,7 @@ public class DefaultDbMigration implements DbMigration {
}
private PlatformDdlWriter createDdlWriter(DatabasePlatform platform) {
return new PlatformDdlWriter(platform, serverConfig, migrationConfig, lockTimeoutSeconds);
return new PlatformDdlWriter(platform, databaseConfig, migrationConfig, lockTimeoutSeconds);
}
/**
@@ -1,6 +1,6 @@
package io.ebeaninternal.dbmigration.ddlgeneration;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.BaseTableDdl;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.PlatformDdl;
import io.ebeaninternal.dbmigration.migration.AddColumn;
@@ -27,11 +27,11 @@ public class BaseDdlHandler implements DdlHandler {
protected final TableDdl tableDdl;
public BaseDdlHandler(ServerConfig serverConfig, PlatformDdl platformDdl) {
this(serverConfig, platformDdl, new BaseTableDdl(serverConfig, platformDdl));
public BaseDdlHandler(DatabaseConfig config, PlatformDdl platformDdl) {
this(config, platformDdl, new BaseTableDdl(config, platformDdl));
}
protected BaseDdlHandler(ServerConfig serverConfig, PlatformDdl platformDdl, TableDdl tableDdl) {
protected BaseDdlHandler(DatabaseConfig config, PlatformDdl platformDdl, TableDdl tableDdl) {
this.tableDdl = tableDdl;
}
@@ -1,6 +1,6 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.DbPlatformType;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
@@ -90,8 +90,8 @@ public abstract class AbstractHanaDdl extends PlatformDdl {
}
@Override
public DdlHandler createDdlHandler(ServerConfig serverConfig) {
return new HanaDdlHandler(serverConfig, this);
public DdlHandler createDdlHandler(DatabaseConfig config) {
return new HanaDdlHandler(config, this);
}
@Override
@@ -1,9 +1,9 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.annotation.Platform;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DbConstraintNaming;
import io.ebean.config.NamingConvention;
import io.ebean.config.ServerConfig;
import io.ebean.config.dbplatform.DbHistorySupport;
import io.ebean.config.dbplatform.IdType;
import io.ebean.util.StringHelper;
@@ -33,13 +33,13 @@ import io.ebeaninternal.dbmigration.model.MTableIdentity;
import io.ebeaninternal.server.deploy.IdentityMode;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static io.ebean.util.StringHelper.replace;
import static io.ebeaninternal.api.PlatformMatch.matchPlatform;
import static io.ebeaninternal.dbmigration.ddlgeneration.platform.SplitColumns.split;
@@ -182,9 +182,9 @@ public class BaseTableDdl implements TableDdl {
* Replaces Table name (${table}), Column name (${column}) and default value (${default}) in DDL.
*/
private String translate(String ddl, String tableName, String columnName, String defaultValue) {
String ret = StringHelper.replaceString(ddl, "${table}", tableName);
ret = StringHelper.replaceString(ret, "${column}", columnName);
return StringHelper.replaceString(ret, "${default}", defaultValue);
String ret = replace(ddl, "${table}", tableName);
ret = replace(ret, "${column}", columnName);
return replace(ret, "${default}", defaultValue);
}
private void handleStrictError(String tableName, String columnName) {
@@ -202,13 +202,13 @@ public class BaseTableDdl implements TableDdl {
/**
* Construct with a naming convention and platform specific DDL.
*/
public BaseTableDdl(ServerConfig serverConfig, PlatformDdl platformDdl) {
this.namingConvention = serverConfig.getNamingConvention();
this.naming = serverConfig.getConstraintNaming();
this.historyTableSuffix = serverConfig.getHistoryTableSuffix();
public BaseTableDdl(DatabaseConfig config, PlatformDdl platformDdl) {
this.namingConvention = config.getNamingConvention();
this.naming = config.getConstraintNaming();
this.historyTableSuffix = config.getHistoryTableSuffix();
this.platformDdl = platformDdl;
this.platformDdl.configure(serverConfig);
this.strictMode = serverConfig.getMigrationConfig().isStrictMode();
this.platformDdl.configure(config);
this.strictMode = config.getMigrationConfig().isStrictMode();
DbHistorySupport hist = platformDdl.getPlatform().getHistorySupport();
if (hist == null) {
this.historySupport = HistorySupport.NONE;
@@ -1,6 +1,6 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
@@ -19,8 +19,8 @@ public class ClickHouseDdl extends PlatformDdl {
}
@Override
public DdlHandler createDdlHandler(ServerConfig serverConfig) {
return new ClickHouseDdlHandler(serverConfig, this);
public DdlHandler createDdlHandler(DatabaseConfig config) {
return new ClickHouseDdlHandler(config, this);
}
@Override
@@ -1,11 +1,11 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.dbmigration.ddlgeneration.BaseDdlHandler;
public class ClickHouseDdlHandler extends BaseDdlHandler {
public ClickHouseDdlHandler(ServerConfig serverConfig, PlatformDdl platformDdl) {
super(serverConfig, platformDdl, new ClickHouseTableDdl(serverConfig, platformDdl));
public ClickHouseDdlHandler(DatabaseConfig config, PlatformDdl platformDdl) {
super(config, platformDdl, new ClickHouseTableDdl(config, platformDdl));
}
}
@@ -1,13 +1,13 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.migration.CreateTable;
public class ClickHouseTableDdl extends BaseTableDdl {
public ClickHouseTableDdl(ServerConfig serverConfig, PlatformDdl platformDdl) {
super(serverConfig, platformDdl);
public ClickHouseTableDdl(DatabaseConfig config, PlatformDdl platformDdl) {
super(config, platformDdl);
}
@Override
@@ -1,7 +1,7 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DbConstraintNaming;
import io.ebean.config.ServerConfig;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
@@ -37,12 +37,12 @@ public abstract class DbTriggerBasedHistoryDdl implements PlatformHistoryDdl {
}
@Override
public void configure(ServerConfig serverConfig, PlatformDdl platformDdl) {
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
this.platformDdl = platformDdl;
this.sysPeriod = serverConfig.getAsOfSysPeriod();
this.viewSuffix = serverConfig.getAsOfViewSuffix();
this.historySuffix = serverConfig.getHistoryTableSuffix();
this.constraintNaming = serverConfig.getConstraintNaming();
this.sysPeriod = config.getAsOfSysPeriod();
this.viewSuffix = config.getAsOfViewSuffix();
this.historySuffix = config.getHistoryTableSuffix();
this.constraintNaming = config.getConstraintNaming();
this.sysPeriodStart = sysPeriod + "_start";
this.sysPeriodEnd = sysPeriod + "_end";
@@ -1,11 +1,11 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.dbmigration.ddlgeneration.BaseDdlHandler;
public class HanaDdlHandler extends BaseDdlHandler {
public HanaDdlHandler(ServerConfig serverConfig, PlatformDdl platformDdl) {
super(serverConfig, platformDdl, new HanaTableDdl(serverConfig, platformDdl));
public HanaDdlHandler(DatabaseConfig config, PlatformDdl platformDdl) {
super(config, platformDdl, new HanaTableDdl(config, platformDdl));
}
}
@@ -1,6 +1,6 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
@@ -24,11 +24,11 @@ public class HanaHistoryDdl implements PlatformHistoryDdl {
private Map<String, String> createdHistoryTables = new ConcurrentHashMap<>();
@Override
public void configure(ServerConfig serverConfig, PlatformDdl platformDdl) {
this.systemPeriodStart = serverConfig.getAsOfSysPeriod() + "_start";
this.systemPeriodEnd = serverConfig.getAsOfSysPeriod() + "_end";
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
this.systemPeriodStart = config.getAsOfSysPeriod() + "_start";
this.systemPeriodEnd = config.getAsOfSysPeriod() + "_end";
this.platformDdl = platformDdl;
this.historySuffix = serverConfig.getHistoryTableSuffix();
this.historySuffix = config.getHistoryTableSuffix();
}
@Override
@@ -1,7 +1,7 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.PropertiesWrapper;
import io.ebean.config.ServerConfig;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.AddColumn;
import io.ebeaninternal.dbmigration.migration.AlterColumn;
@@ -17,11 +17,11 @@ public class HanaTableDdl extends BaseTableDdl {
private final HanaHistoryDdl historyDdl;
private final boolean generateUniqueDdl;
public HanaTableDdl(ServerConfig serverConfig, PlatformDdl platformDdl) {
super(serverConfig, platformDdl);
public HanaTableDdl(DatabaseConfig config, PlatformDdl platformDdl) {
super(config, platformDdl);
this.historyDdl = (HanaHistoryDdl) platformDdl.historyDdl;
if (serverConfig.getProperties() != null) {
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "hana", serverConfig.getProperties(), serverConfig.getClassLoadConfig());
if (config.getProperties() != null) {
PropertiesWrapper wrapper = new PropertiesWrapper("ebean", "hana", config.getProperties(), config.getClassLoadConfig());
this.generateUniqueDdl = wrapper.getBoolean("generateUniqueDdl", false);
} else {
this.generateUniqueDdl = false;
@@ -1,6 +1,6 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
@@ -15,7 +15,7 @@ import java.io.IOException;
public class MariaDbHistoryDdl implements PlatformHistoryDdl {
@Override
public void configure(ServerConfig serverConfig, PlatformDdl platformDdl) {
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
// do nothing
}
@@ -1,6 +1,6 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
@@ -15,7 +15,7 @@ import java.io.IOException;
public class NoHistorySupportDdl implements PlatformHistoryDdl {
@Override
public void configure(ServerConfig serverConfig, PlatformDdl platformDdl) {
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
// does nothing
}
@@ -1,6 +1,7 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.annotation.ConstraintMode;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DbConstraintNaming;
import io.ebean.config.ServerConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
@@ -141,16 +142,16 @@ public class PlatformDdl {
/**
* Set configuration options.
*/
public void configure(ServerConfig serverConfig) {
historyDdl.configure(serverConfig, this);
naming = serverConfig.getConstraintNaming();
public void configure(DatabaseConfig config) {
historyDdl.configure(config, this);
naming = config.getConstraintNaming();
}
/**
* Create a DdlHandler for the specific database platform.
*/
public DdlHandler createDdlHandler(ServerConfig serverConfig) {
return new BaseDdlHandler(serverConfig, this);
public DdlHandler createDdlHandler(DatabaseConfig config) {
return new BaseDdlHandler(config, this);
}
/**
@@ -1,6 +1,6 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
import io.ebeaninternal.dbmigration.migration.DropHistoryTable;
@@ -14,9 +14,9 @@ import java.io.IOException;
public interface PlatformHistoryDdl {
/**
* Configure typically reading the necessary parameters from ServerConfig and Platform.
* Configure typically reading the necessary parameters from DatabaseConfig and Platform.
*/
void configure(ServerConfig serverConfig, PlatformDdl platformDdl);
void configure(DatabaseConfig config, PlatformDdl platformDdl);
/**
* Creates a new table and add history support to the table using platform specific mechanism.
@@ -1,6 +1,6 @@
package io.ebeaninternal.dbmigration.ddlgeneration.platform;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.AddHistoryTable;
@@ -19,9 +19,9 @@ public class SqlServerHistoryDdl implements PlatformHistoryDdl {
private PlatformDdl platformDdl;
@Override
public void configure(ServerConfig serverConfig, PlatformDdl platformDdl) {
this.systemPeriodStart = serverConfig.getAsOfSysPeriod() + "From";
this.systemPeriodEnd = serverConfig.getAsOfSysPeriod() + "To";
public void configure(DatabaseConfig config, PlatformDdl platformDdl) {
this.systemPeriodStart = config.getAsOfSysPeriod() + "From";
this.systemPeriodEnd = config.getAsOfSysPeriod() + "To";
this.platformDdl = platformDdl;
}
@@ -1,7 +1,7 @@
package io.ebeaninternal.dbmigration.model;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DbMigrationConfig;
import io.ebean.config.ServerConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlBuffer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlHandler;
@@ -27,7 +27,7 @@ public class PlatformDdlWriter {
private static final Logger logger = LoggerFactory.getLogger(PlatformDdlWriter.class);
private final ServerConfig serverConfig;
private final DatabaseConfig databaseConfig;
private final DbMigrationConfig config;
@@ -35,9 +35,9 @@ public class PlatformDdlWriter {
private final int lockTimeoutSeconds;
public PlatformDdlWriter(DatabasePlatform platform, ServerConfig serverConfig, DbMigrationConfig config, int lockTimeoutSeconds) {
public PlatformDdlWriter(DatabasePlatform platform, DatabaseConfig dbConfig, DbMigrationConfig config, int lockTimeoutSeconds) {
this.platformDdl = PlatformDdlBuilder.create(platform);
this.serverConfig = serverConfig;
this.databaseConfig = dbConfig;
this.config = config;
this.lockTimeoutSeconds = lockTimeoutSeconds;
}
@@ -123,7 +123,7 @@ public class PlatformDdlWriter {
* Return the platform specific DdlHandler (to generate DDL).
*/
protected DdlHandler handler() {
return platformDdl.createDdlHandler(serverConfig);
return platformDdl.createDdlHandler(databaseConfig);
}
/**
@@ -1,14 +1,13 @@
package io.ebeaninternal.server.autotune.service;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.server.autotune.AutoTuneService;
public class AutoTuneServiceFactory {
public static AutoTuneService create(SpiEbeanServer server, ServerConfig serverConfig) {
return new DefaultAutoTuneService(server, serverConfig);
public static AutoTuneService create(SpiEbeanServer server, DatabaseConfig config) {
return new DefaultAutoTuneService(server, config);
}
}
@@ -1,7 +1,7 @@
package io.ebeaninternal.server.autotune.service;
import io.ebean.config.AutoTuneConfig;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.autotune.AutoTuneCollection;
@@ -49,10 +49,8 @@ public class DefaultAutoTuneService implements AutoTuneService {
private long runtimeChangeCount;
public DefaultAutoTuneService(SpiEbeanServer server, ServerConfig serverConfig) {
AutoTuneConfig config = serverConfig.getAutoTuneConfig();
public DefaultAutoTuneService(SpiEbeanServer server, DatabaseConfig databaseConfig) {
AutoTuneConfig config = databaseConfig.getAutoTuneConfig();
this.server = server;
this.queryTuning = config.isQueryTuning();
this.profiling = config.isProfiling();
@@ -4,7 +4,7 @@ import io.ebean.cache.QueryCacheEntryValidate;
import io.ebean.cache.ServerCacheFactory;
import io.ebean.cache.ServerCacheOptions;
import io.ebean.config.CurrentTenantProvider;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.server.cluster.ClusterManager;
/**
@@ -14,7 +14,7 @@ public class CacheManagerOptions {
private final ClusterManager clusterManager;
private final ServerConfig serverConfig;
private final DatabaseConfig databaseConfig;
private final boolean localL2Caching;
@@ -29,17 +29,17 @@ public class CacheManagerOptions {
CacheManagerOptions() {
this.localL2Caching = true;
this.clusterManager = null;
this.serverConfig = null;
this.databaseConfig = null;
this.cacheFactory = new DefaultServerCacheFactory();
this.beanDefault = new ServerCacheOptions();
this.queryDefault = new ServerCacheOptions();
}
public CacheManagerOptions(ClusterManager clusterManager, ServerConfig serverConfig, boolean localL2Caching) {
public CacheManagerOptions(ClusterManager clusterManager, DatabaseConfig config, boolean localL2Caching) {
this.clusterManager = clusterManager;
this.serverConfig = serverConfig;
this.databaseConfig = config;
this.localL2Caching = localL2Caching;
this.currentTenantProvider = serverConfig.getCurrentTenantProvider();
this.currentTenantProvider = config.getCurrentTenantProvider();
}
public CacheManagerOptions with(ServerCacheOptions beanDefault, ServerCacheOptions queryDefault) {
@@ -60,7 +60,7 @@ public class CacheManagerOptions {
}
public String getServerName() {
return (serverConfig == null) ? "db" : serverConfig.getName();
return (databaseConfig == null) ? "db" : databaseConfig.getName();
}
public boolean isLocalL2Caching() {
@@ -11,11 +11,9 @@ import java.util.Map;
public class CachedBeanDataFromBean {
public static CachedBeanData extract(BeanDescriptor<?> desc, EntityBean bean) {
EntityBeanIntercept ebi = bean._ebean_getIntercept();
Map<String, Object> data = new LinkedHashMap<>();
BeanProperty idProperty = desc.getIdProperty();
@@ -25,11 +23,13 @@ public class CachedBeanDataFromBean {
data.put(idProperty.getName(), idProperty.getCacheDataValue(bean));
}
}
BeanProperty[] props = desc.propertiesNonMany();
// extract all the non-many properties
for (BeanProperty prop : props) {
if (ebi.isLoadedProperty(prop.getPropertyIndex())) {
final boolean dirty = ebi.isDirty();
for (BeanProperty prop : desc.propertiesNonMany()) {
if (dirty && ebi.isDirtyProperty(prop.getPropertyIndex())) {
data.put(prop.getName(), prop.getCacheDataValueOrig(ebi));
} else if (ebi.isLoadedProperty(prop.getPropertyIndex())) {
data.put(prop.getName(), prop.getCacheDataValue(bean));
}
}
@@ -72,5 +72,4 @@ public class CachedBeanDataFromBean {
return sharableBean;
}
}
@@ -3,7 +3,7 @@ package io.ebeaninternal.server.cache;
import io.ebean.BackgroundExecutor;
import io.ebean.cache.ServerCacheFactory;
import io.ebean.cache.ServerCachePlugin;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
/**
* Default implementation of ServerCachePlugin.
@@ -14,7 +14,7 @@ public class DefaultServerCachePlugin implements ServerCachePlugin {
* Creates the default ServerCacheFactory.
*/
@Override
public ServerCacheFactory create(ServerConfig config, BackgroundExecutor executor) {
public ServerCacheFactory create(DatabaseConfig config, BackgroundExecutor executor) {
return new DefaultServerCacheFactory(executor);
}
}
@@ -23,7 +23,7 @@ public class DefaultChangeLogRegister implements ChangeLogRegister {
private final boolean defaultInsertsInclude;
/**
* Create with the default insertsIncluded from ServerConfig.
* Create with the default insertsIncluded from DatabaseConfig.
*/
public DefaultChangeLogRegister(boolean defaultInsertsInclude) {
this.defaultInsertsInclude = defaultInsertsInclude;
@@ -60,7 +60,6 @@ public class DefaultChangeLogRegister implements ChangeLogRegister {
*/
private boolean insertModeInclude(ChangeLogInsertMode inserts) {
if (inserts == ChangeLogInsertMode.DEFAULT) {
// return the default as per the ServerConfig
return defaultInsertsInclude;
}
return ChangeLogInsertMode.INCLUDE == inserts;
@@ -2,7 +2,7 @@ package io.ebeaninternal.server.core;
import io.avaje.classpath.scanner.ClassPathScanner;
import io.avaje.classpath.scanner.ClassPathScannerFactory;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import java.util.ArrayList;
import java.util.List;
@@ -13,13 +13,12 @@ import java.util.List;
public class ClassPathScanners {
/**
* Return the list of ClassPathScanner services using serverConfig service loader.
* Return the list of ClassPathScanner services using DatabaseConfig service loader.
*/
public static List<ClassPathScanner> find(ServerConfig serverConfig) {
public static List<ClassPathScanner> find(DatabaseConfig config) {
List<ClassPathScanner> scanners = new ArrayList<>();
for (ClassPathScannerFactory factory : serverConfig.serviceLoad(ClassPathScannerFactory.class)) {
scanners.add(factory.createScanner(serverConfig.getClassLoadConfig().getClassLoader()));
for (ClassPathScannerFactory factory : config.serviceLoad(ClassPathScannerFactory.class)) {
scanners.add(factory.createScanner(config.getClassLoadConfig().getClassLoader()));
}
return scanners;
}
@@ -1,6 +1,6 @@
package io.ebeaninternal.server.core;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.clickhouse.ClickHousePlatform;
import io.ebean.config.dbplatform.cockroach.CockroachPlatform;
@@ -47,26 +47,24 @@ public class DatabasePlatformFactory {
/**
* Create the appropriate database specific platform.
*/
public DatabasePlatform create(ServerConfig serverConfig) {
public DatabasePlatform create(DatabaseConfig config) {
try {
String offlinePlatform = DbOffline.getPlatform();
if (offlinePlatform != null) {
logger.info("offline platform [{}]", offlinePlatform);
return byDatabaseName(offlinePlatform);
}
if (serverConfig.getDatabasePlatformName() != null) {
if (config.getDatabasePlatformName() != null) {
// choose based on dbName
return byDatabaseName(serverConfig.getDatabasePlatformName());
return byDatabaseName(config.getDatabasePlatformName());
}
if (serverConfig.getDataSourceConfig().isOffline()) {
if (config.getDataSourceConfig().isOffline()) {
throw new PersistenceException("You must specify a DatabasePlatformName when you are offline");
}
// guess using meta data from driver
return byDataSource(serverConfig.getDataSource());
return byDataSource(config.getDataSource());
} catch (Exception ex) {
throw new PersistenceException(ex);
@@ -1,6 +1,8 @@
package io.ebeaninternal.server.core;
import io.ebean.config.ContainerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DatabaseConfigProvider;
import io.ebean.config.ModuleInfoLoader;
import io.ebean.config.ServerConfig;
import io.ebean.config.ServerConfigProvider;
@@ -52,20 +54,16 @@ public class DefaultContainer implements SpiContainer {
*/
@Override
public SpiEbeanServer createServer(String name) {
ServerConfig config = new ServerConfig();
DatabaseConfig config = new DatabaseConfig();
config.setName(name);
config.loadFromProperties();
return createServer(config);
}
private SpiBackgroundExecutor createBackgroundExecutor(ServerConfig serverConfig) {
String namePrefix = "ebean-" + serverConfig.getName();
int schedulePoolSize = serverConfig.getBackgroundExecutorSchedulePoolSize();
int shutdownSecs = serverConfig.getBackgroundExecutorShutdownSecs();
private SpiBackgroundExecutor createBackgroundExecutor(DatabaseConfig config) {
String namePrefix = "ebean-" + config.getName();
int schedulePoolSize = config.getBackgroundExecutorSchedulePoolSize();
int shutdownSecs = config.getBackgroundExecutorShutdownSecs();
return new DefaultBackgroundExecutor(schedulePoolSize, shutdownSecs, namePrefix);
}
@@ -73,41 +71,39 @@ public class DefaultContainer implements SpiContainer {
* Create the implementation from the configuration.
*/
@Override
public SpiEbeanServer createServer(ServerConfig serverConfig) {
public SpiEbeanServer createServer(DatabaseConfig config) {
synchronized (this) {
applyConfigServices(serverConfig);
setNamingConvention(serverConfig);
BootupClasses bootupClasses = getBootupClasses(serverConfig);
applyConfigServices(config);
setNamingConvention(config);
BootupClasses bootupClasses = getBootupClasses(config);
boolean online = true;
if (serverConfig.isDocStoreOnly()) {
serverConfig.setDatabasePlatform(new H2Platform());
if (config.isDocStoreOnly()) {
config.setDatabasePlatform(new H2Platform());
} else {
TenantMode tenantMode = serverConfig.getTenantMode();
TenantMode tenantMode = config.getTenantMode();
if (TenantMode.DB != tenantMode) {
setDataSource(serverConfig);
setDataSource(config);
if (!tenantMode.isDynamicDataSource()) {
// check the autoCommit and Transaction Isolation
online = checkDataSource(serverConfig);
online = checkDataSource(config);
}
}
}
// determine database platform (Oracle etc)
setDatabasePlatform(serverConfig);
if (serverConfig.getDbEncrypt() != null) {
setDatabasePlatform(config);
if (config.getDbEncrypt() != null) {
// use a configured DbEncrypt rather than the platform default
serverConfig.getDatabasePlatform().setDbEncrypt(serverConfig.getDbEncrypt());
config.getDatabasePlatform().setDbEncrypt(config.getDbEncrypt());
}
// inform the NamingConvention of the associated DatabasePlatform
serverConfig.getNamingConvention().setDatabasePlatform(serverConfig.getDatabasePlatform());
config.getNamingConvention().setDatabasePlatform(config.getDatabasePlatform());
// executor and l2 caching service setup early (used during server construction)
SpiBackgroundExecutor executor = createBackgroundExecutor(serverConfig);
InternalConfiguration c = new InternalConfiguration(online, clusterManager, executor, serverConfig, bootupClasses);
SpiBackgroundExecutor executor = createBackgroundExecutor(config);
InternalConfiguration c = new InternalConfiguration(online, clusterManager, executor, config, bootupClasses);
DefaultServer server = new DefaultServer(c, c.cacheManager());
@@ -121,10 +117,17 @@ public class DefaultContainer implements SpiContainer {
}
}
private void applyConfigServices(ServerConfig config) {
private void applyConfigServices(DatabaseConfig config) {
if (config.isDefaultServer()) {
for (ServerConfigProvider configProvider : ServiceLoader.load(ServerConfigProvider.class)) {
boolean appliedConfig = false;
for (DatabaseConfigProvider configProvider : ServiceLoader.load(DatabaseConfigProvider.class)) {
configProvider.apply(config);
appliedConfig = true;
}
if (!appliedConfig && config instanceof ServerConfig) {
for (ServerConfigProvider configProvider : ServiceLoader.load(ServerConfigProvider.class)) {
configProvider.apply((ServerConfig)config);
}
}
if (config.isAutoLoadModuleInfo()) {
// auto register entity classes (default db)
@@ -157,42 +160,41 @@ public class DefaultContainer implements SpiContainer {
* Get the entities, scalarTypes, Listeners etc combining the class registered
* ones with the already created instances.
*/
private BootupClasses getBootupClasses(ServerConfig serverConfig) {
private BootupClasses getBootupClasses(DatabaseConfig config) {
BootupClasses bootup = getBootupClasses1(serverConfig);
bootup.addIdGenerators(serverConfig.getIdGenerators());
bootup.addPersistControllers(serverConfig.getPersistControllers());
bootup.addPostLoaders(serverConfig.getPostLoaders());
bootup.addPostConstructListeners(serverConfig.getPostConstructListeners());
bootup.addFindControllers(serverConfig.getFindControllers());
bootup.addPersistListeners(serverConfig.getPersistListeners());
bootup.addQueryAdapters(serverConfig.getQueryAdapters());
bootup.addServerConfigStartup(serverConfig.getServerConfigStartupListeners());
bootup.addChangeLogInstances(serverConfig);
BootupClasses bootup = getBootupClasses1(config);
bootup.addIdGenerators(config.getIdGenerators());
bootup.addPersistControllers(config.getPersistControllers());
bootup.addPostLoaders(config.getPostLoaders());
bootup.addPostConstructListeners(config.getPostConstructListeners());
bootup.addFindControllers(config.getFindControllers());
bootup.addPersistListeners(config.getPersistListeners());
bootup.addQueryAdapters(config.getQueryAdapters());
bootup.addServerConfigStartup(config.getServerConfigStartupListeners());
bootup.addChangeLogInstances(config);
// run any ServerConfigStartup instances
bootup.runServerConfigStartup(serverConfig);
bootup.runServerConfigStartup(config);
return bootup;
}
/**
* Get the class based entities, scalarTypes, Listeners etc.
*/
private BootupClasses getBootupClasses1(ServerConfig serverConfig) {
private BootupClasses getBootupClasses1(DatabaseConfig config) {
List<Class<?>> entityClasses = serverConfig.getClasses();
if (serverConfig.isDisableClasspathSearch() || (entityClasses != null && !entityClasses.isEmpty())) {
List<Class<?>> entityClasses = config.getClasses();
if (config.isDisableClasspathSearch() || (entityClasses != null && !entityClasses.isEmpty())) {
// use classes we explicitly added via configuration
return new BootupClasses(entityClasses);
}
return BootupClassPathSearch.search(serverConfig);
return BootupClassPathSearch.search(config);
}
/**
* Set the naming convention to underscore if it has not already been set.
*/
private void setNamingConvention(ServerConfig config) {
private void setNamingConvention(DatabaseConfig config) {
if (config.getNamingConvention() == null) {
config.setNamingConvention(new UnderscoreNamingConvention());
}
@@ -201,12 +203,12 @@ public class DefaultContainer implements SpiContainer {
/**
* Set the DatabasePlatform if it has not already been set.
*/
private void setDatabasePlatform(ServerConfig config) {
private void setDatabasePlatform(DatabaseConfig config) {
DatabasePlatform platform = config.getDatabasePlatform();
if (platform == null) {
if (config.getTenantMode().isDynamicDataSource()) {
throw new IllegalStateException("DatabasePlatform must be explicitly set on ServerConfig for TenantMode "+config.getTenantMode());
throw new IllegalStateException("DatabasePlatform must be explicitly set on DatabaseConfig for TenantMode "+config.getTenantMode());
}
// automatically determine the platform
platform = new DatabasePlatformFactory().create(config);
@@ -219,7 +221,7 @@ public class DefaultContainer implements SpiContainer {
/**
* Set the DataSource if it has not already been set.
*/
private void setDataSource(ServerConfig config) {
private void setDataSource(DatabaseConfig config) {
if (isOfflineMode(config)) {
logger.debug("... DbOffline using platform [{}]", DbOffline.getPlatform());
} else {
@@ -227,8 +229,8 @@ public class DefaultContainer implements SpiContainer {
}
}
private boolean isOfflineMode(ServerConfig serverConfig) {
return serverConfig.isDbOffline() || DbOffline.isSet();
private boolean isOfflineMode(DatabaseConfig config) {
return config.isDbOffline() || DbOffline.isSet();
}
/**
@@ -241,26 +243,22 @@ public class DefaultContainer implements SpiContainer {
* checking may not work as expected.
* </p>
*/
private boolean checkDataSource(ServerConfig serverConfig) {
if (isOfflineMode(serverConfig)) {
private boolean checkDataSource(DatabaseConfig config) {
if (isOfflineMode(config)) {
return false;
}
if (serverConfig.getDataSource() == null) {
if (serverConfig.getDataSourceConfig().isOffline()) {
if (config.getDataSource() == null) {
if (config.getDataSourceConfig().isOffline()) {
// this is ok - offline DDL generation etc
return false;
}
throw new RuntimeException("DataSource not set?");
}
try (Connection connection = serverConfig.getDataSource().getConnection()) {
try (Connection connection = config.getDataSource().getConnection()) {
if (connection.getAutoCommit()) {
logger.warn("DataSource [{}] has autoCommit defaulting to true!", serverConfig.getName());
logger.warn("DataSource [{}] has autoCommit defaulting to true!", config.getName());
}
return true;
} catch (SQLException ex) {
throw new PersistenceException(ex);
}
@@ -44,8 +44,8 @@ import io.ebean.bean.PersistenceContext.WithOption;
import io.ebean.cache.ServerCacheManager;
import io.ebean.common.CopyOnFirstWriteList;
import io.ebean.config.CurrentTenantProvider;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.EncryptKeyManager;
import io.ebean.config.ServerConfig;
import io.ebean.config.SlowQueryEvent;
import io.ebean.config.SlowQueryListener;
import io.ebean.config.TenantMode;
@@ -158,7 +158,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
private static final Logger logger = LoggerFactory.getLogger(DefaultServer.class);
private final ServerConfig serverConfig;
private final DatabaseConfig config;
private final String serverName;
@@ -249,31 +249,34 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
private final SlowQueryListener slowQueryListener;
private final boolean disableL2Cache;
/**
* Create the DefaultServer.
*/
public DefaultServer(InternalConfiguration config, ServerCacheManager cache) {
this.logManager = config.getLogManager();
this.dtoBeanManager = config.getDtoBeanManager();
this.serverConfig = config.getServerConfig();
this.config = config.getConfig();
this.disableL2Cache = this.config.isDisableL2Cache();
this.serverCacheManager = cache;
this.databasePlatform = config.getDatabasePlatform();
this.backgroundExecutor = config.getBackgroundExecutor();
this.extraMetrics = config.getExtraMetrics();
this.serverName = serverConfig.getName();
this.lazyLoadBatchSize = serverConfig.getLazyLoadBatchSize();
this.queryBatchSize = serverConfig.getQueryBatchSize();
this.serverName = this.config.getName();
this.lazyLoadBatchSize = this.config.getLazyLoadBatchSize();
this.queryBatchSize = this.config.getQueryBatchSize();
this.cqueryEngine = config.getCQueryEngine();
this.expressionFactory = config.getExpressionFactory();
this.encryptKeyManager = serverConfig.getEncryptKeyManager();
this.defaultPersistenceContextScope = serverConfig.getPersistenceContextScope();
this.currentTenantProvider = serverConfig.getCurrentTenantProvider();
this.encryptKeyManager = this.config.getEncryptKeyManager();
this.defaultPersistenceContextScope = this.config.getPersistenceContextScope();
this.currentTenantProvider = this.config.getCurrentTenantProvider();
this.slowQueryMicros = config.getSlowQueryMicros();
this.slowQueryListener = config.getSlowQueryListener();
this.beanDescriptorManager = config.getBeanDescriptorManager();
beanDescriptorManager.setEbeanServer(this);
this.updateAllPropertiesInBatch = serverConfig.isUpdateAllPropertiesInBatch();
this.callStackFactory = initCallStackFactory(serverConfig);
this.updateAllPropertiesInBatch = this.config.isUpdateAllPropertiesInBatch();
this.callStackFactory = initCallStackFactory(this.config);
this.persister = config.createPersister(this);
this.queryEngine = config.createOrmQueryEngine();
this.relationalQueryEngine = config.createRelationalQueryEngine();
@@ -292,7 +295,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
this.queryPlanManager = config.initQueryPlanManager(transactionManager);
this.metaInfoManager = new DefaultMetaInfoManager(this);
this.serverPlugins = config.getPlugins();
this.ddlGenerator = new DdlGenerator(this, serverConfig);
this.ddlGenerator = new DdlGenerator(this, this.config);
this.scriptRunner = new DScriptRunner(this);
configureServerPlugins();
@@ -303,12 +306,12 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
/**
* Create the CallStackFactory depending if AutoTune is being used.
*/
private CallOriginFactory initCallStackFactory(ServerConfig serverConfig) {
if (!serverConfig.getAutoTuneConfig().isActive()) {
private CallOriginFactory initCallStackFactory(DatabaseConfig config) {
if (!config.getAutoTuneConfig().isActive()) {
// use a common CallStack for performance as we don't care with no AutoTune
return new NoopCallOriginFactory();
}
return new DefaultCallOriginFactory(serverConfig.getMaxCallStack());
return new DefaultCallOriginFactory(config.getMaxCallStack());
}
private void configureServerPlugins() {
@@ -322,7 +325,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
* Execute all the plugins with an online flag indicating the DB is up or not.
*/
public void executePlugins(boolean online) {
if (!serverConfig.isDocStoreOnly()) {
if (!config.isDocStoreOnly()) {
ddlGenerator.execute(online);
}
for (Plugin plugin : serverPlugins) {
@@ -330,6 +333,11 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
}
@Override
public boolean isDisableL2Cache() {
return disableL2Cache;
}
@Override
public SpiLogManager log() {
return logManager;
@@ -355,8 +363,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
@Override
public ServerConfig getServerConfig() {
return serverConfig;
public DatabaseConfig getServerConfig() {
return config;
}
@Override
@@ -371,7 +379,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
public DdlHandler createDdlHandler() {
return PlatformDdlBuilder.create(databasePlatform).createDdlHandler(serverConfig);
return PlatformDdlBuilder.create(databasePlatform).createDdlHandler(config);
}
@Override
@@ -436,15 +444,15 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
if (encryptKeyManager != null) {
encryptKeyManager.initialise();
}
serverCacheManager.setEnabledRegions(serverConfig.getEnabledL2Regions());
serverCacheManager.setEnabledRegions(config.getEnabledL2Regions());
}
/**
* Start any services after registering with the ClusterManager.
*/
public void start() {
if (TenantMode.DB != serverConfig.getTenantMode()) {
serverConfig.runDbMigration(serverConfig.getDataSource());
if (TenantMode.DB != config.getTenantMode()) {
config.runDbMigration(config.getDataSource());
}
}
@@ -487,14 +495,13 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
transactionManager.shutdown(shutdownDataSource, deregisterDriver);
shutdown = true;
if (shutdownDataSource) {
// deregister the DataSource in case ServerConfig is re-used
serverConfig.setDataSource(null);
config.setDataSource(null);
}
}
private void shutdownPlugins() {
if (serverConfig.isDumpMetricsOnShutdown()) {
new DumpMetrics(this, serverConfig.getDumpMetricsOptions()).dump();
if (config.isDumpMetricsOnShutdown()) {
new DumpMetrics(this, config.getDumpMetricsOptions()).dump();
}
for (Plugin plugin : serverPlugins) {
try {
@@ -1786,7 +1793,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
private EntityBean checkEntityBean(Object bean) {
if (bean == null) {
throw new IllegalArgumentException(Message.msg("bean.isnull"));
throw new IllegalArgumentException("The bean is null?");
}
if (!(bean instanceof EntityBean)) {
throw new IllegalArgumentException("Was expecting an EntityBean but got a " + bean.getClass());
@@ -1,6 +1,6 @@
package io.ebeaninternal.server.core;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.datasource.DataSourceAlertFactory;
import io.ebean.datasource.DataSourceConfig;
import io.ebean.datasource.DataSourceFactory;
@@ -16,16 +16,16 @@ class InitDataSource {
private final JndiDataSourceLookup jndiDataSourceFactory = new JndiDataSourceLookup();
private final ServerConfig config;
private final DatabaseConfig config;
/**
* Create and set the main DataSource and read-only DataSource.
*/
static void init(ServerConfig config) {
static void init(DatabaseConfig config) {
new InitDataSource(config).initialise();
}
InitDataSource(ServerConfig config) {
InitDataSource(DatabaseConfig config) {
this.config = config;
}
@@ -98,7 +98,7 @@ class InitDataSource {
}
if (dsConfig.isOffline()) {
if (config.getDatabasePlatformName() == null) {
throw new PersistenceException("You MUST specify a DatabasePlatformName on ServerConfig when offline");
throw new PersistenceException("You MUST specify a DatabasePlatformName on DatabaseConfig when offline");
}
return null;
}
@@ -7,22 +7,18 @@ import java.util.HashMap;
* <p>
* Using this for now instead of String.intern() to avoid any unexpected
* increase in PermGen space.
* </p>
*/
public final class InternString {
private static final HashMap<String, String> map = new HashMap<>();
/**
* Return the shared instance of this string.
*/
public static String intern(String s) {
if (s == null) {
return null;
}
//noinspection SynchronizationOnStaticField
synchronized (map) {
String v = map.get(s);
@@ -32,7 +28,6 @@ public final class InternString {
map.put(s, s);
return s;
}
}
}
}
@@ -2,7 +2,7 @@ package io.ebeaninternal.server.core;
import io.avaje.classpath.scanner.ClassPathScanner;
import io.avaje.classpath.scanner.Resource;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.server.dto.DtoNamedQueries;
import io.ebeaninternal.xmlmapping.XmlMappingReader;
import io.ebeaninternal.xmlmapping.model.XmDto;
@@ -23,7 +23,7 @@ class InternalConfigXmlRead {
private static final Logger log = LoggerFactory.getLogger(InternalConfigXmlRead.class);
private final ServerConfig serverConfig;
private final DatabaseConfig config;
private final ClassLoader classLoader;
@@ -31,10 +31,10 @@ class InternalConfigXmlRead {
private List<XmEbean> xmlEbeanList;
InternalConfigXmlRead(ServerConfig serverConfig) {
this.serverConfig = serverConfig;
this.classLoader = serverConfig.getClassLoadConfig().getClassLoader();
if (serverConfig.getClassLoadConfig().isJavaxJAXBPresent()) {
InternalConfigXmlRead(DatabaseConfig config) {
this.config = config;
this.classLoader = config.getClassLoadConfig().getClassLoader();
if (config.getClassLoadConfig().isJavaxJAXBPresent()) {
init();
}
}
@@ -45,10 +45,9 @@ class InternalConfigXmlRead {
}
private List<Resource> xmlMappingResources() {
List<ClassPathScanner> scanners = ClassPathScanners.find(serverConfig);
List<String> mappingLocations = serverConfig.getMappingLocations();
List<ClassPathScanner> scanners = ClassPathScanners.find(config);
List<String> mappingLocations = config.getMappingLocations();
List<Resource> resourceList = new ArrayList<>();
long st = System.currentTimeMillis();
if (mappingLocations != null && !mappingLocations.isEmpty()) {
for (ClassPathScanner finder : scanners) {
@@ -57,7 +56,6 @@ class InternalConfigXmlRead {
}
}
}
long searchTime = System.currentTimeMillis() - st;
log.debug("Classpath search mappings[{}] searchTime[{}]", resourceList.size(), searchTime);
return resourceList;
@@ -9,9 +9,9 @@ import io.ebean.cache.ServerCacheNotify;
import io.ebean.cache.ServerCacheNotifyPlugin;
import io.ebean.cache.ServerCacheOptions;
import io.ebean.cache.ServerCachePlugin;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.ExternalTransactionManager;
import io.ebean.config.ProfilingConfig;
import io.ebean.config.ServerConfig;
import io.ebean.config.SlowQueryListener;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.DbHistorySupport;
@@ -104,8 +104,8 @@ import java.util.Map;
import java.util.ServiceLoader;
/**
* Used to extend the ServerConfig with additional objects used to configure and
* construct an EbeanServer.
* Used to extend the DatabaseConfig with additional objects used to configure and
* construct an Database.
*/
public class InternalConfiguration {
@@ -115,7 +115,7 @@ public class InternalConfiguration {
private final boolean online;
private final ServerConfig serverConfig;
private final DatabaseConfig config;
private final BootupClasses bootupClasses;
@@ -171,49 +171,42 @@ public class InternalConfiguration {
private final ExtraMetrics extraMetrics = new ExtraMetrics();
InternalConfiguration(boolean online, ClusterManager clusterManager, SpiBackgroundExecutor backgroundExecutor,
ServerConfig serverConfig, BootupClasses bootupClasses) {
DatabaseConfig config, BootupClasses bootupClasses) {
this.online = online;
this.serverConfig = serverConfig;
this.clockService = new ClockService(serverConfig.getClock());
this.config = config;
this.clockService = new ClockService(config.getClock());
this.tableModState = new TableModState();
this.logManager = initLogManager();
this.docStoreFactory = initDocStoreFactory(serverConfig.service(DocStoreFactory.class));
this.jsonFactory = serverConfig.getJsonFactory();
this.docStoreFactory = initDocStoreFactory(config.service(DocStoreFactory.class));
this.jsonFactory = config.getJsonFactory();
this.clusterManager = clusterManager;
this.backgroundExecutor = backgroundExecutor;
this.bootupClasses = bootupClasses;
this.databasePlatform = serverConfig.getDatabasePlatform();
this.expressionFactory = initExpressionFactory(serverConfig);
this.typeManager = new DefaultTypeManager(serverConfig, bootupClasses);
this.databasePlatform = config.getDatabasePlatform();
this.expressionFactory = initExpressionFactory(config);
this.typeManager = new DefaultTypeManager(config, bootupClasses);
this.multiValueBind = createMultiValueBind(databasePlatform.getPlatform());
this.deployInherit = new DeployInherit(bootupClasses);
this.deployCreateProperties = new DeployCreateProperties(typeManager);
this.deployUtil = new DeployUtil(typeManager, serverConfig);
this.deployUtil = new DeployUtil(typeManager, config);
this.serverCachePlugin = initServerCachePlugin();
this.cacheManager = initCacheManager();
InternalConfigXmlRead xmlRead = new InternalConfigXmlRead(serverConfig);
InternalConfigXmlRead xmlRead = new InternalConfigXmlRead(config);
this.dtoBeanManager = new DtoBeanManager(typeManager, xmlRead.readDtoMapping());
this.beanDescriptorManager = new BeanDescriptorManager(this);
Map<String, String> asOfTableMapping = beanDescriptorManager.deploy(xmlRead.xmlDeployment());
Map<String, String> draftTableMap = beanDescriptorManager.getDraftTableMap();
beanDescriptorManager.scheduleBackgroundTrim();
this.dataTimeZone = initDataTimeZone();
this.binder = getBinder(typeManager, databasePlatform, dataTimeZone);
this.cQueryEngine = new CQueryEngine(serverConfig, databasePlatform, binder, asOfTableMapping, draftTableMap);
this.cQueryEngine = new CQueryEngine(config, databasePlatform, binder, asOfTableMapping, draftTableMap);
}
private SpiLogManager initLogManager() {
// allow plugin - i.e. capture executed SQL for testing/asserts
SpiLoggerFactory loggerFactory = serverConfig.service(SpiLoggerFactory.class);
SpiLoggerFactory loggerFactory = config.service(SpiLoggerFactory.class);
if (loggerFactory == null) {
loggerFactory = new DLoggerFactory();
}
@@ -227,10 +220,9 @@ public class InternalConfiguration {
/**
* Create and return the ExpressionFactory based on configuration and database platform.
*/
private ExpressionFactory initExpressionFactory(ServerConfig serverConfig) {
boolean nativeIlike = serverConfig.isExpressionNativeIlike() && databasePlatform.isSupportsNativeIlike();
return new DefaultExpressionFactory(serverConfig.isExpressionEqualsWithNullAsNoop(), nativeIlike);
private ExpressionFactory initExpressionFactory(DatabaseConfig config) {
boolean nativeIlike = config.isExpressionNativeIlike() && databasePlatform.isSupportsNativeIlike();
return new DefaultExpressionFactory(config.isExpressionEqualsWithNullAsNoop(), nativeIlike);
}
private DocStoreFactory initDocStoreFactory(DocStoreFactory service) {
@@ -289,7 +281,7 @@ public class InternalConfiguration {
* Return the ChangeLogRegister to use with a default implementation if none defined.
*/
public ChangeLogRegister changeLogRegister(ChangeLogRegister register) {
boolean includeInserts = serverConfig.isChangeLogIncludeInserts();
boolean includeInserts = config.isChangeLogIncludeInserts();
return plugin((register != null) ? register : new DefaultChangeLogRegister(includeInserts));
}
@@ -350,7 +342,7 @@ public class InternalConfiguration {
}
AutoTuneService createAutoTuneService(SpiEbeanServer server) {
return AutoTuneServiceFactory.create(server, serverConfig);
return AutoTuneServiceFactory.create(server, config);
}
DtoQueryEngine createDtoQueryEngine() {
@@ -358,7 +350,7 @@ public class InternalConfiguration {
}
RelationalQueryEngine createRelationalQueryEngine() {
return new DefaultRelationalQueryEngine(binder, serverConfig.getDatabaseBooleanTrue(), serverConfig.getPlatformConfig().getDbUuid().useBinaryOptimized());
return new DefaultRelationalQueryEngine(binder, config.getDatabaseBooleanTrue(), config.getPlatformConfig().getDbUuid().useBinaryOptimized());
}
OrmQueryEngine createOrmQueryEngine() {
@@ -382,11 +374,11 @@ public class InternalConfiguration {
}
public DatabasePlatform getDatabasePlatform() {
return serverConfig.getDatabasePlatform();
return config.getDatabasePlatform();
}
public ServerConfig getServerConfig() {
return serverConfig;
public DatabaseConfig getConfig() {
return config;
}
public ExpressionFactory getExpressionFactory() {
@@ -422,8 +414,8 @@ public class InternalConfiguration {
}
public GeneratedPropertyFactory getGeneratedPropertyFactory() {
boolean offlineMode = serverConfig.isDbOffline() || DbOffline.isSet();
return new GeneratedPropertyFactory(offlineMode, serverConfig, bootupClasses.getIdGenerators());
boolean offlineMode = config.isDbOffline() || DbOffline.isSet();
return new GeneratedPropertyFactory(offlineMode, config, bootupClasses.getIdGenerators());
}
/**
@@ -439,14 +431,14 @@ public class InternalConfiguration {
TransactionManager createTransactionManager(DocStoreUpdateProcessor indexUpdateProcessor) {
TransactionScopeManager scopeManager = createTransactionScopeManager();
boolean notifyL2CacheInForeground = cacheManager.isLocalL2Caching() || serverConfig.isNotifyL2CacheInForeground();
boolean notifyL2CacheInForeground = cacheManager.isLocalL2Caching() || config.isNotifyL2CacheInForeground();
TransactionManagerOptions options =
new TransactionManagerOptions(notifyL2CacheInForeground, serverConfig, scopeManager, clusterManager, backgroundExecutor,
new TransactionManagerOptions(notifyL2CacheInForeground, config, scopeManager, clusterManager, backgroundExecutor,
indexUpdateProcessor, beanDescriptorManager, dataSource(), profileHandler(), logManager,
tableModState, cacheNotify, clockService);
if (serverConfig.isDocStoreOnly()) {
if (config.isDocStoreOnly()) {
return new DocStoreTransactionManager(options);
}
return new TransactionManager(options);
@@ -454,11 +446,11 @@ public class InternalConfiguration {
private SpiProfileHandler profileHandler() {
ProfilingConfig profilingConfig = serverConfig.getProfilingConfig();
ProfilingConfig profilingConfig = config.getProfilingConfig();
if (!profilingConfig.isEnabled()) {
return new NoopProfileHandler();
}
SpiProfileHandler handler = serverConfig.service(SpiProfileHandler.class);
SpiProfileHandler handler = config.service(SpiProfileHandler.class);
if (handler == null) {
handler = new DefaultProfileHandler(profilingConfig);
}
@@ -469,16 +461,16 @@ public class InternalConfiguration {
* Return the DataSource supplier based on the tenancy mode.
*/
private DataSourceSupplier dataSource() {
switch (serverConfig.getTenantMode()) {
switch (config.getTenantMode()) {
case DB:
case DB_WITH_MASTER:
return new MultiTenantDbSupplier(serverConfig.getCurrentTenantProvider(), serverConfig.getTenantDataSourceProvider());
return new MultiTenantDbSupplier(config.getCurrentTenantProvider(), config.getTenantDataSourceProvider());
case SCHEMA:
return new MultiTenantDbSchemaSupplier(serverConfig.getCurrentTenantProvider(), serverConfig.getDataSource(), serverConfig.getReadOnlyDataSource(), serverConfig.getTenantSchemaProvider());
return new MultiTenantDbSchemaSupplier(config.getCurrentTenantProvider(), config.getDataSource(), config.getReadOnlyDataSource(), config.getTenantSchemaProvider());
case CATALOG:
return new MultiTenantDbCatalogSupplier(serverConfig.getCurrentTenantProvider(), serverConfig.getDataSource(), serverConfig.getReadOnlyDataSource(), serverConfig.getTenantCatalogProvider());
return new MultiTenantDbCatalogSupplier(config.getCurrentTenantProvider(), config.getDataSource(), config.getReadOnlyDataSource(), config.getTenantCatalogProvider());
default:
return new SimpleDataSourceProvider(serverConfig.getDataSource(), serverConfig.getReadOnlyDataSource());
return new SimpleDataSourceProvider(config.getDataSource(), config.getReadOnlyDataSource());
}
}
@@ -486,9 +478,8 @@ public class InternalConfiguration {
* Create the TransactionScopeManager taking into account JTA or external transaction manager.
*/
private TransactionScopeManager createTransactionScopeManager() {
ExternalTransactionManager externalTransactionManager = serverConfig.getExternalTransactionManager();
if (externalTransactionManager == null && serverConfig.isUseJtaTransactionManager()) {
ExternalTransactionManager externalTransactionManager = config.getExternalTransactionManager();
if (externalTransactionManager == null && config.isUseJtaTransactionManager()) {
externalTransactionManager = new JtaTransactionManager();
}
if (externalTransactionManager != null) {
@@ -503,7 +494,7 @@ public class InternalConfiguration {
* Create the DataTimeZone implementation to use.
*/
private DataTimeZone initDataTimeZone() {
String tz = serverConfig.getDataTimeZone();
String tz = config.getDataTimeZone();
if (tz == null) {
if (isMySql(getPlatform())) {
return new MySqlDataTimeZone();
@@ -533,7 +524,7 @@ public class InternalConfiguration {
* Return the slow query warning limit in micros.
*/
long getSlowQueryMicros() {
long millis = serverConfig.getSlowQueryMillis();
long millis = config.getSlowQueryMillis();
return (millis < 1) ? Long.MAX_VALUE : millis * 1000L;
}
@@ -541,13 +532,13 @@ public class InternalConfiguration {
* Return the SlowQueryListener with a default that logs a warning message.
*/
SlowQueryListener getSlowQueryListener() {
long millis = serverConfig.getSlowQueryMillis();
long millis = config.getSlowQueryMillis();
if (millis < 1) {
return null;
}
SlowQueryListener listener = serverConfig.getSlowQueryListener();
SlowQueryListener listener = config.getSlowQueryListener();
if (listener == null) {
listener = serverConfig.service(SlowQueryListener.class);
listener = config.service(SlowQueryListener.class);
if (listener == null) {
listener = new DefaultSlowQueryListener();
}
@@ -571,11 +562,11 @@ public class InternalConfiguration {
}
private ServerCachePlugin initServerCachePlugin() {
if (serverConfig.isLocalOnlyL2Cache()) {
if (config.isLocalOnlyL2Cache()) {
localL2Caching = true;
return new DefaultServerCachePlugin();
}
ServerCachePlugin plugin = serverConfig.getServerCachePlugin();
ServerCachePlugin plugin = config.getServerCachePlugin();
if (plugin == null) {
ServiceLoader<ServerCachePlugin> cacheFactories = ServiceLoader.load(ServerCachePlugin.class);
Iterator<ServerCachePlugin> iterator = cacheFactories.iterator();
@@ -597,34 +588,33 @@ public class InternalConfiguration {
*/
private SpiCacheManager initCacheManager() {
if (!online || serverConfig.isDisableL2Cache()) {
if (!online || config.isDisableL2Cache()) {
// use local only L2 cache implementation as placeholder
return new DefaultServerCacheManager();
}
ServerCacheFactory factory = serverCachePlugin.create(serverConfig, backgroundExecutor);
ServerCacheNotifyPlugin notifyPlugin = serverConfig.service(ServerCacheNotifyPlugin.class);
ServerCacheFactory factory = serverCachePlugin.create(config, backgroundExecutor);
ServerCacheNotifyPlugin notifyPlugin = config.service(ServerCacheNotifyPlugin.class);
if (notifyPlugin != null) {
// plugin supplied so use that to send notifications
cacheNotify = notifyPlugin.create(serverConfig);
cacheNotify = notifyPlugin.create(config);
} else {
cacheNotify = factory.createCacheNotify(tableModState);
}
// reasonable default settings are for a cache per bean type
ServerCacheOptions beanOptions = new ServerCacheOptions();
beanOptions.setMaxSize(serverConfig.getCacheMaxSize());
beanOptions.setMaxIdleSecs(serverConfig.getCacheMaxIdleTime());
beanOptions.setMaxSecsToLive(serverConfig.getCacheMaxTimeToLive());
beanOptions.setMaxSize(config.getCacheMaxSize());
beanOptions.setMaxIdleSecs(config.getCacheMaxIdleTime());
beanOptions.setMaxSecsToLive(config.getCacheMaxTimeToLive());
// reasonable default settings for the query cache per bean type
ServerCacheOptions queryOptions = new ServerCacheOptions();
queryOptions.setMaxSize(serverConfig.getQueryCacheMaxSize());
queryOptions.setMaxIdleSecs(serverConfig.getQueryCacheMaxIdleTime());
queryOptions.setMaxSecsToLive(serverConfig.getQueryCacheMaxTimeToLive());
queryOptions.setMaxSize(config.getQueryCacheMaxSize());
queryOptions.setMaxIdleSecs(config.getQueryCacheMaxIdleTime());
queryOptions.setMaxSecsToLive(config.getQueryCacheMaxTimeToLive());
CacheManagerOptions builder = new CacheManagerOptions(clusterManager, serverConfig, localL2Caching)
CacheManagerOptions builder = new CacheManagerOptions(clusterManager, config, localL2Caching)
.with(beanOptions, queryOptions)
.with(factory, tableModState);
@@ -632,10 +622,10 @@ public class InternalConfiguration {
}
public QueryPlanManager initQueryPlanManager(TransactionManager transactionManager) {
if (!serverConfig.isCollectQueryPlans()) {
if (!config.isCollectQueryPlans()) {
return QueryPlanManager.NOOP;
}
long threshold = serverConfig.getCollectQueryPlanThresholdMicros();
long threshold = config.getCollectQueryPlanThresholdMicros();
return new CQueryPlanManager(transactionManager, threshold, queryPlanLogger(databasePlatform.getPlatform()), extraMetrics);
}
@@ -1,64 +0,0 @@
package io.ebeaninternal.server.core;
import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
* Utility object used for internationalising log messages.
*/
public class Message {
private static final String bundle = "io.ebeaninternal.api.message";
/**
* Return a message that has a single argument.
*/
public static String msg(String key, Object arg) {
Object[] args = new Object[1];
args[0] = arg;
return MessageFormat.format(getPattern(key), args);
}
/**
* Return a message that has a two arguments.
*/
public static String msg(String key, Object arg, Object arg2) {
Object[] args = new Object[2];
args[0] = arg;
args[1] = arg2;
return MessageFormat.format(getPattern(key), args);
}
public static String msg(String key, Object arg, Object arg2, Object arg3) {
Object[] args = new Object[3];
args[0] = arg;
args[1] = arg2;
args[2] = arg3;
return MessageFormat.format(getPattern(key), args);
}
/**
* Return a message that has an array of arguments.
*/
public static String msg(String key, Object[] args) {
return MessageFormat.format(getPattern(key), args);
}
/**
* Return a message that has a no arguments.
*/
public static String msg(String key) {
return MessageFormat.format(getPattern(key), new Object[0]);
}
private static String getPattern(String key) {
try {
ResourceBundle myResources = ResourceBundle.getBundle(bundle);
return myResources.getString(key);
} catch (MissingResourceException e) {
return "MissingResource " + bundle + ":" + key;
}
}
}
@@ -358,7 +358,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
* Will end a locally created transaction.
* <p>
* It ends the query only transaction.
* </p>
*/
@Override
public void endTransIfRequired() {
@@ -385,17 +384,11 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return query.getType() == Type.ITERATE;
}
/**
* Execute the query as a delete.
*/
@Override
public int delete() {
return notifyCache(queryEngine.delete(this), false);
}
/**
* Execute the query as a update.
*/
@Override
public int update() {
return notifyCache(queryEngine.update(this), true);
@@ -413,9 +406,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return queryEngine.findResultSet(this);
}
/**
* Execute the query as findById.
*/
@Override
public Object findId() {
return queryEngine.findId(this);
@@ -456,9 +446,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return queryEngine.findIterate(this);
}
/**
* Execute the query as findList.
*/
@Override
@SuppressWarnings("unchecked")
public List<T> findList() {
@@ -470,18 +457,12 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return queryEngine.findVersions(this);
}
/**
* Execute the query as findSet.
*/
@Override
@SuppressWarnings("unchecked")
public Set<T> findSet() {
return (Set<T>) queryEngine.findMany(this);
}
/**
* Execute the query as findMap.
*/
@Override
@SuppressWarnings("unchecked")
public <K> Map<K, T> findMap() {
@@ -497,9 +478,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return (Map<K, T>) queryEngine.findMany(this);
}
/**
* Execute the findSingleAttributeList query.
*/
@Override
public <A> List<A> findSingleAttributeList() {
return queryEngine.findSingleAttributeList(this);
@@ -512,9 +490,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return finder;
}
/**
* Return the find that is to be performed.
*/
@Override
public SpiQuery<T> getQuery() {
return query;
@@ -652,11 +627,9 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
@Override
public boolean getFromBeanCache() {
if (!query.isBeanCacheGet()) {
return false;
}
// check if the query can use the bean cache
// 1. Find by Ids
// - hit beanCache with Ids
@@ -664,7 +637,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
// - query and Load misses into bean cache
// - merge the 2 results and return
//
CacheIdLookup<T> idLookup = query.cacheIdLookup();
if (idLookup != null) {
BeanCacheResult<T> cacheResult = beanDescriptor.cacheIdLookup(persistenceContext, idLookup.idValues());
@@ -672,7 +644,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
this.cacheBeans = idLookup.removeHits(cacheResult);
return idLookup.allHits();
}
if (!beanDescriptor.isNaturalKeyCaching()) {
return false;
}
@@ -688,7 +659,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
return data.allHits();
}
}
return false;
}
@@ -698,8 +668,9 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
@Override
@SuppressWarnings("unchecked")
public Object getFromQueryCache() {
if (query.getUseQueryCache() == CacheMode.OFF || (transaction != null && transaction.isSkipCache())) {
if (query.getUseQueryCache() == CacheMode.OFF
|| (transaction != null && transaction.isSkipCache())
|| ebeanServer.isDisableL2Cache()) {
return null;
} else {
cacheKey = query.queryHash();
@@ -778,7 +749,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
* Return the batch size for lazy loading on this bean query request.
*/
public int getLazyLoadBatchSize() {
int batchSize = query.getLazyLoadBatchSize();
return (batchSize > 0) ? batchSize : ebeanServer.getLazyLoadBatchSize();
}
@@ -797,7 +767,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
* Return the base table alias for this query.
*/
public String getBaseTableAlias() {
return query.getAlias() == null ? beanDescriptor.getBaseTableAlias() : query.getAlias();
return query.getAlias(beanDescriptor.getBaseTableAlias());
}
/**
@@ -117,6 +117,11 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
*/
private Map<String, Object> collectionChanges;
/**
* Set true when the request includes cascade save to a many.
*/
private boolean updatedMany;
/**
* Many properties that were cascade saved (and hence might need caches updated later).
*/
@@ -850,7 +855,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
public final void checkRowCount(int rowCount) {
if (rowCount != 1 && rowCount != Statement.SUCCESS_NO_INFO) {
if (ConcurrencyMode.VERSION == concurrencyMode) {
throw new OptimisticLockException(Message.msg("persist.conc2", String.valueOf(rowCount)), null, bean);
throw new OptimisticLockException("Data has changed. updated row count " + rowCount, null, bean);
} else if (rowCount == 0 && type == Type.UPDATE) {
throw new EntityNotFoundException("No rows updated");
}
@@ -1031,21 +1036,24 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
return beanDescriptor.isReference(intercept);
}
/**
* This many property has been cascade saved. Keep note of this and update the 'many property'
* cache on post commit.
*/
public void addUpdatedManyProperty(BeanPropertyAssocMany<?> updatedAssocMany) {
if (updatedManys == null) {
updatedManys = new ArrayList<>(5);
}
updatedManys.add(updatedAssocMany);
public void setUpdatedMany() {
this.updatedMany = true;
}
/**
* Return the list of cascade updated many properties (can be null).
* This many property has potential L2 cache update for many Ids.
*/
public List<BeanPropertyAssocMany<?>> getUpdatedManyCollections() {
public void addUpdatedManyForL2Cache(BeanPropertyAssocMany<?> many) {
if (updatedManys == null) {
updatedManys = new ArrayList<>(5);
}
updatedManys.add(many);
}
/**
* Return the list of updated many properties for L2 cache update (can be null).
*/
public List<BeanPropertyAssocMany<?>> getUpdatedManyForL2Cache() {
return updatedManys;
}
@@ -1061,7 +1069,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
* many properties were updated.
*/
public void completeUpdate() {
if (!dirty && updatedManys != null) {
if (!dirty && updatedMany) {
// set the flag and register for post commit processing if there
// is caching or registered listeners
if (idValue == null) {
@@ -1,7 +1,7 @@
package io.ebeaninternal.server.core.bootup;
import io.avaje.classpath.scanner.ClassPathScanner;
import io.ebean.config.ServerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebeaninternal.server.core.ClassPathScanners;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -24,21 +24,19 @@ public class BootupClassPathSearch {
* Search the classPath for the classes we are interested in returning
* them as BootupClasses.
*/
public static BootupClasses search(ServerConfig serverConfig) {
return new BootupClassPathSearch(serverConfig).getBootupClasses();
public static BootupClasses search(DatabaseConfig config) {
return new BootupClassPathSearch(config).getBootupClasses();
}
private BootupClassPathSearch(ServerConfig serverConfig) {
private BootupClassPathSearch(DatabaseConfig config) {
// find packages defined in ebean.mf resources
Set<String> mfPackages = ManifestReader.create(serverConfig.getClassLoadConfig().getClassLoader())
Set<String> mfPackages = ManifestReader.create(config.getClassLoadConfig().getClassLoader())
.read("META-INF/ebean.mf")
.read("ebean.mf")
.entityPackages();
this.packages = DistillPackages.distill(serverConfig.getPackages(), mfPackages);
this.scanners = ClassPathScanners.find(serverConfig);
this.packages = DistillPackages.distill(config.getPackages(), mfPackages);
this.scanners = ClassPathScanners.find(config);
}
/**
@@ -2,9 +2,9 @@ package io.ebeaninternal.server.core.bootup;
import io.avaje.classpath.scanner.ClassFilter;
import io.ebean.annotation.DocStore;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.IdGenerator;
import io.ebean.config.ScalarTypeConverter;
import io.ebean.config.ServerConfig;
import io.ebean.event.BeanFindController;
import io.ebean.event.BeanPersistController;
import io.ebean.event.BeanPersistListener;
@@ -106,12 +106,11 @@ public class BootupClasses implements ClassFilter {
/**
* Run any ServerConfigStartup listeners.
*/
public void runServerConfigStartup(ServerConfig serverConfig) {
public void runServerConfigStartup(DatabaseConfig config) {
for (Class<?> cls : serverConfigStartupCandidates) {
try {
ServerConfigStartup newInstance = (ServerConfigStartup) cls.newInstance();
newInstance.onStart(serverConfig);
newInstance.onStart(config);
} catch (Exception e) {
// assume that the desired behavior is to fail - add your own try catch if needed
throw new IllegalStateException("Error running ServerConfigStartup " + cls, e);
@@ -119,7 +118,7 @@ public class BootupClasses implements ClassFilter {
}
for (ServerConfigStartup startup : serverConfigStartupInstances) {
try {
startup.onStart(serverConfig);
startup.onStart(config);
} catch (Exception e) {
// assume that the desired behavior is to fail - add your own try catch if needed
throw new IllegalStateException("Error running ServerConfigStartup " + startup.getClass(), e);
@@ -188,13 +187,13 @@ public class BootupClasses implements ClassFilter {
add(startupInstances, serverConfigStartupInstances, serverConfigStartupCandidates);
}
public void addChangeLogInstances(ServerConfig serverConfig) {
public void addChangeLogInstances(DatabaseConfig config) {
readAuditPrepare = serverConfig.getReadAuditPrepare();
readAuditLogger = serverConfig.getReadAuditLogger();
changeLogPrepare = serverConfig.getChangeLogPrepare();
changeLogListener = serverConfig.getChangeLogListener();
changeLogRegister = serverConfig.getChangeLogRegister();
readAuditPrepare = config.getReadAuditPrepare();
readAuditLogger = config.getReadAuditLogger();
changeLogPrepare = config.getChangeLogPrepare();
changeLogListener = config.getChangeLogListener();
changeLogRegister = config.getChangeLogRegister();
// if not already set create the implementations found
// via classpath scanning

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