I have a Oracle table, say, mytbl
, which has a column, OFFSET
. I am trying to create unit tests using H2
and because OFFSET
is a keyword for H2
, I am having to re-write the queries using a double quoted, "OFFSET"
, instead of simply referring to the column as offset
. I am using SpringFramework's EmbeddedDatabaseBuilder
to spinup the H2. When instantiating the database for unit tests, I use the specification, NON_KEYWORDS=OFFSET
, in the url. This specification is honored during instantiation, that is, I can refer to the column simply as offset
. But the NON_KEYWORDS
spec is ignored when the actual queries are invoked.
FWIW:
- versions: H2:2.1.x, Oracle:19.4, Java:11, jUnit:4, Spring:5.3.x.
- I am not using JPA or Hibernate.
- SO references: ref1, ref2
Here is the test class (the actual tests are irrelevant):
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
public class MyClassDaoTest {
private EmbeddedDatabase ds;
private MyClassDao myClassDao;
@Before
public void setup() {
this.ds = new EmbeddedDatabaseBuilder()
.setType( EmbeddedDatabaseType.H2 )
.setName( "dummy;MODE=Oracle;DATABASE_TO_UPPER=true;NON_KEYWORDS=OFFSET" )
.addScript( "/initialize-mytbl.sql" )
.build();
this.myClassDao = new MyClassDao( new JdbcTemplate( this.ds ) );
}
@After
public void shutdown() {
this.ds.shutdown();
}
}
Here is the loading script (note: I do not have to use "OFFSET"
here), initialize-mytbl.sql:
CREATE TABLE MYTBL ( offset INTEGER NOT NULL );
INSERT INTO MYTBL ( offset ) VALUES (1);
And here is the actual query:
import org.springframework.jdbc.core.JdbcOperations;
public class MyClassDao {
private final JdbcOperation j;
public MyClassDao( JdbcOperations j ) { this.j = j; }
public int fetchOffset() {
// this fails in H2 but works in Oracle:
//return j.queryForObject( "select offset from mytbl", Integer.class );
// this works in both H2 and Oracle:
return j.queryForObject( "select \"OFFSET\" from mytbl", Integer.class );
}
}
So, my question is: why is the NON_KEYWORDS
spec in the url being ignored in the actual queries? Obviously, I do not prefer to re-write all the queries replacing offset
with "OFFSET"
. And, more obviously, I can not alter the Oracle table, mytbl
.
The actual exception thrown is:
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "SELECT offset[*] from mytbl" ....