In my integration test, I am creating an H2 database with two schemas, A
and B
. A
is set as the default schema, like it is in the normal setup for the application when it is running with a PostgreSQL database. During the integration test, I am starting both the H2 database and an embedded Tomcat server and execute the SQL files to initialise the database via Liquibase.
All models that are connected to tables in schema A
are annotated with @Table("tablename")
, whereas models for schema B
are annotated with @Table("B.tablename")
. When I call a REST endpoint in the embedded server, activeJDBC warns me:
WARN org.javalite.activejdbc.Registry - Failed to retrieve metadata for table: 'B.tablename'. Are you sure this table exists? For some databases table names are case sensitive.
When I then try to access a table in schema B
in my Java code, activeJDBC throws the following exception (which is expected after the previous warning):
org.javalite.activejdbc.InitException: Failed to find table: B.tablename
at org.javalite.activejdbc.MetaModel.getAttributeNames(MetaModel.java:248)
at org.javalite.activejdbc.Model.hydrate(Model.java:207)
at org.javalite.activejdbc.ModelDelegate.instance(ModelDelegate.java:247)
at org.javalite.activejdbc.ModelDelegate.instance(ModelDelegate.java:241)
...
Accessing tables in schema A
works as expected.
I am sure that the tables in schema B
are actually created and contain data, because on top of Liquibase log entries for executing the files I can also access the database directly and get the table content as a result:
Initialisation of Database and server:
private String H2_CONNECTION_STRING = "jdbc:h2:mem:testdb;INIT=CREATE SCHEMA IF NOT EXISTS A\\;SET SCHEMA A\\;CREATE SCHEMA IF NOT EXISTS B\\;";
@Before
public void initializeDatabase() {
connection = DriverManager.getConnection(H2_CONNECTION_STRING);
Statement stat = connection.createStatement();
stat.execute("GRANT ALTER ANY SCHEMA TO PUBLIC");
LiquibaseInitialisation.initH2(H2_CONNECTION_STRING); // execute SQL scripts
EmbeddedServer.startServer();
}
Query to print content of B.tablename
:
Logger Log = LoggerFactory.getLogger("test");
Statement stat = connection.createStatement();
stat.execute("SELECT * FROM B.tablename;");
connection.commit();
resultSet = stat4.getResultSet();
rsmd = resultSet.getMetaData();
columnsNumber = rsmd.getColumnCount();
while (resultSet.next()) {
builder = new StringBuilder();
for (int i = 1; i <= columnsNumber; i++) {
builder.append(resultSet.getString(i));
builder.append(" ");
}
Log.info(builder.toString());
}
This produces the desired output of the content of B.tablename
.
The question is this: Why doesn't activeJDBC find the tables in schema B
in the H2 database when it's clearly present, but works flawlessly in PostgreSQL? Am I missing something with regards to schemas in H2 or activeJDBC?