diff --git a/ebean-api/src/main/java/io/ebean/Database.java b/ebean-api/src/main/java/io/ebean/Database.java
index 31064ee3c..509fd4764 100644
--- a/ebean-api/src/main/java/io/ebean/Database.java
+++ b/ebean-api/src/main/java/io/ebean/Database.java
@@ -1746,7 +1746,7 @@ public interface Database {
* TenantMode that does not support DDL run on startup.
*
* Note: runDdl is normally executed at startup automatically, if
- * ebean.db.runDdl=true is set. Calling this method, will not check
+ * ebean.db.ddl.run=true is set. Calling this method, will not check
* that flag.
*
*/
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java
index 392f509b2..9e3aadc86 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java
@@ -387,6 +387,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
if (config.isRunMigration()) {
runMigration();
}
+ } else if (config.isDdlRun() || config.isRunMigration()) {
+ log.warn("There was a request to run DDL or migration, but this is currently not possible, as the database is not available");
}
startQueryPlanCapture();
}
diff --git a/ebean-test/pom.xml b/ebean-test/pom.xml
index 76b06fa60..f3ff709bb 100644
--- a/ebean-test/pom.xml
+++ b/ebean-test/pom.xml
@@ -187,8 +187,8 @@
com.oracle.database.jdbc
-
ojdbc8
19.12.0.0
diff --git a/ebean-test/src/test/java/io/ebean/config/TestServerOffline.java b/ebean-test/src/test/java/io/ebean/config/TestServerOffline.java
new file mode 100644
index 000000000..bed9ab01e
--- /dev/null
+++ b/ebean-test/src/test/java/io/ebean/config/TestServerOffline.java
@@ -0,0 +1,151 @@
+package io.ebean.config;
+
+
+import io.ebean.Database;
+import io.ebean.DatabaseFactory;
+import io.ebean.annotation.ForPlatform;
+import io.ebean.annotation.Platform;
+import io.ebean.datasource.DataSourceAlert;
+import io.ebean.datasource.DataSourceInitialiseException;
+
+import org.junit.jupiter.api.Test;
+import org.tests.model.basic.EBasicVer;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
+
+import javax.persistence.PersistenceException;
+import javax.sql.DataSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class TestServerOffline {
+
+ @Test
+ @ForPlatform({Platform.H2})
+ public void testOffline_default() throws SQLException {
+
+ String url = "jdbc:h2:mem:testoffline1";
+ try (Connection bootup = DriverManager.getConnection(url, "sa", "secret")) {
+ Properties props = props(url);
+ DatabaseConfig config = config(props);
+
+ assertThatThrownBy(() -> DatabaseFactory.create(config))
+ .isInstanceOf(DataSourceInitialiseException.class);
+ }
+
+ }
+
+ private static class LazyDatasourceInitializer implements DataSourceAlert {
+
+ public Database server;
+
+ private boolean initialized;
+
+ @Override
+ public void dataSourceUp(DataSource dataSource) {
+ if (!initialized) {
+ initDatabase();
+ }
+ }
+
+ public synchronized void initDatabase() {
+ if (!initialized) {
+ server.runDdl();
+ server.runMigration();
+ initialized = true;
+ }
+ }
+
+ @Override
+ public void dataSourceDown(DataSource dataSource, SQLException reason) {}
+
+ @Override
+ public void dataSourceWarning(DataSource dataSource, String msg) {}
+
+ }
+
+ @Test
+ @ForPlatform({Platform.H2})
+ public void testOffline_recovery() throws SQLException {
+
+ String url = "jdbc:h2:mem:testoffline3";
+ try (Connection bootup = DriverManager.getConnection(url, "sa", "secret")) {
+
+ Properties props = props(url);
+
+ // to bring up ebean without a database, we must disable varous things
+ // that happen on startup
+ props.setProperty("datasource.h2_offline.failOnStart", "false");
+ props.setProperty("ebean.h2_offline.skipDataSourceCheck", "true");
+ props.setProperty("ebean.h2_offline.ddl.run", "false");
+ DatabaseConfig config = config(props);
+
+ LazyDatasourceInitializer alert = new LazyDatasourceInitializer() ;
+ config.getDataSourceConfig().setAlert(alert);
+ config.getDataSourceConfig().setHeartbeatFreqSecs(1);
+
+ Database h2Offline = DatabaseFactory.create(config);
+ alert.server = h2Offline;
+ assertThat(h2Offline).isNotNull();
+ // DB is online now in offline mode
+
+ // Accessing the DB will throw a PE
+ assertThatThrownBy(() -> alert.initDatabase())
+ .isInstanceOf(PersistenceException.class)
+ .hasMessageContaining("Failed to obtain connection to run DDL");
+
+ assertThatThrownBy(() -> h2Offline.find(EBasicVer.class).findCount()).isInstanceOf(PersistenceException.class);
+
+ // so - reset the password so that the server can reconnect
+ try (Statement stmt = bootup.createStatement()) {
+ stmt.execute("alter user sa set password 'sa'");
+ }
+
+ assertThat(alert.initialized).isFalse();
+
+ // next access to ebean should bring DS online
+ h2Offline.find(EBasicVer.class).findCount();
+ assertThat(alert.initialized).isTrue();
+
+ // check if server is working (ie ddl was run)
+ EBasicVer bean = new EBasicVer("foo");
+ h2Offline.save(bean);
+ assertThat(h2Offline.find(EBasicVer.class).findCount()).isEqualTo(1);
+ h2Offline.delete(bean);
+ }
+ }
+
+ private Properties props(String url) {
+
+ Properties props = new Properties();
+
+ props.setProperty("datasource.h2_offline.username", "sa");
+ props.setProperty("datasource.h2_offline.password", "sa");
+ props.setProperty("datasource.h2_offline.url", url);
+ props.setProperty("datasource.h2_offline.driver", "org.h2.Driver");
+
+ props.setProperty("ebean.h2_offline.databasePlatformName", "h2");
+ props.setProperty("ebean.h2_offline.ddl.extra", "false");
+
+ props.setProperty("ebean.h2_offline.ddl.generate", "true");
+ props.setProperty("ebean.h2_offline.ddl.run", "true");
+
+ return props;
+ }
+
+ private DatabaseConfig config(Properties props) {
+ DatabaseConfig config = new DatabaseConfig();
+ config.setName("h2_offline");
+ config.loadFromProperties(props);
+ config.setDefaultServer(false);
+ config.setRegister(false);
+ config.getClasses().add(EBasicVer.class);
+ return config;
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index 76c596d4d..99861c0e2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
org.avaje
java8-oss
- 3.2
+ 3.3
io.ebean
diff --git a/release.properties b/release.properties
deleted file mode 100644
index e846a5665..000000000
--- a/release.properties
+++ /dev/null
@@ -1,83 +0,0 @@
-#release configuration
-#Fri Dec 17 17:24:24 NZDT 2021
-projectVersionPolicyId=default
-project.scm.io.ebean\:ebean-core-type.tag=HEAD
-scm.branchCommitComment=@{prefix} prepare branch @{releaseLabel}
-project.rel.io.ebean\:ebean-ddl-generator=12.13.2
-project.dev.io.ebean\:ebean-core=12.13.3-SNAPSHOT
-project.scm.io.ebean\:ebean-api.tag=HEAD
-project.scm.io.ebean\:ebean-redis.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-project.scm.io.ebean\:ebean-querybean.tag=HEAD
-project.scm.io.ebean\:ebean-api.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-project.dev.io.ebean\:ebean-api=12.13.3-SNAPSHOT
-project.rel.io.ebean\:ebean=12.13.2
-project.dev.io.ebean\:ebean-core-type=12.13.3-SNAPSHOT
-project.scm.io.ebean\:ebean-ddl-generator.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-exec.activateProfiles=release
-project.dev.io.ebean\:ebean-test=12.13.3-SNAPSHOT
-project.scm.io.ebean\:kotlin-querybean-generator.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-project.scm.io.ebean\:ebean-querybean.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-project.scm.io.ebean\:ebean-bom.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-project.scm.io.ebean\:ebean-core.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-project.rel.io.ebean\:ebean-core-type=12.13.2
-project.rel.io.ebean\:kotlin-querybean-generator=12.13.2
-project.dev.io.ebean\:querybean-generator=12.13.3-SNAPSHOT
-project.scm.io.ebean\:ebean-autotune.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-scm.commentPrefix=[maven-release-plugin]
-releaseStrategyId=default
-project.rel.io.ebean\:ebean-querybean=12.13.2
-project.scm.io.ebean\:ebean-externalmapping-api.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-project.scm.io.ebean\:querybean-generator.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-project.dev.io.ebean\:kotlin-querybean-generator=12.13.3-SNAPSHOT
-project.scm.io.ebean\:ebean-core-type.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-completedPhase=generate-release-poms
-project.rel.io.ebean\:ebean-redis=12.13.2
-project.scm.io.ebean\:ebean-test.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-project.scm.io.ebean\:ebean-postgis.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-project.dev.io.ebean\:ebean-autotune=12.13.3-SNAPSHOT
-project.rel.io.ebean\:ebean-api=12.13.2
-project.scm.io.ebean\:ebean-postgis.tag=HEAD
-project.scm.io.ebean\:querybean-generator.tag=HEAD
-project.rel.io.ebean\:querybean-generator=12.13.2
-scm.tag=ebean-parent-12.13.2
-project.rel.io.ebean\:ebean-externalmapping-xml=12.13.2
-project.scm.io.ebean\:ebean-ddl-generator.tag=HEAD
-project.rel.io.ebean\:ebean-externalmapping-api=12.13.2
-project.scm.io.ebean\:ebean-externalmapping-xml.tag=HEAD
-preparationGoals=clean verify
-exec.pomFileName=pom.xml
-project.dev.io.ebean\:ebean-externalmapping-api=12.13.3-SNAPSHOT
-project.dev.io.ebean\:ebean=12.13.3-SNAPSHOT
-project.scm.io.ebean\:ebean.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-project.dev.io.ebean\:ebean-parent=12.13.3-SNAPSHOT
-project.dev.io.ebean\:ebean-externalmapping-xml=12.13.3-SNAPSHOT
-project.rel.io.ebean\:ebean-core=12.13.2
-project.dev.io.ebean\:ebean-redis=12.13.3-SNAPSHOT
-project.dev.io.ebean\:ebean-postgis=12.13.3-SNAPSHOT
-project.scm.io.ebean\:ebean-redis.tag=HEAD
-project.scm.io.ebean\:ebean-parent.tag=HEAD
-pushChanges=true
-project.scm.io.ebean\:ebean-externalmapping-xml.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-project.rel.io.ebean\:ebean-test=12.13.2
-project.scm.io.ebean\:kotlin-querybean-generator.tag=HEAD
-project.scm.io.ebean\:ebean-bom.tag=HEAD
-project.scm.io.ebean\:ebean-autotune.tag=HEAD
-project.scm.io.ebean\:ebean.tag=HEAD
-project.scm.io.ebean\:ebean-core.tag=HEAD
-project.rel.io.ebean\:ebean-autotune=12.13.2
-scm.rollbackCommitComment=@{prefix} rollback the release of @{releaseLabel}
-remoteTagging=true
-project.dev.io.ebean\:ebean-bom=12.13.3-SNAPSHOT
-project.dev.io.ebean\:ebean-querybean=12.13.3-SNAPSHOT
-project.rel.io.ebean\:ebean-bom=12.13.2
-project.scm.io.ebean\:ebean-parent.developerConnection=scm\:git\:git@github.com\:ebean-orm/ebean.git
-scm.url=scm\:git\:git@github.com\:ebean-orm/ebean.git
-scm.developmentCommitComment=@{prefix} prepare for next development iteration
-project.scm.io.ebean\:ebean-externalmapping-api.tag=HEAD
-scm.tagNameFormat=@{project.artifactId}-@{project.version}
-project.scm.io.ebean\:ebean-test.tag=HEAD
-project.dev.io.ebean\:ebean-ddl-generator=12.13.3-SNAPSHOT
-exec.snapshotReleasePluginAllowed=false
-scm.releaseCommitComment=@{prefix} prepare release @{releaseLabel}
-project.rel.io.ebean\:ebean-postgis=12.13.2
-project.rel.io.ebean\:ebean-parent=12.13.2