Spring JDBC lob insertion fails: Invalid column type - oracle

The code:
jdbcTemplate.update("MERGE INTO app_role_data x USING (select ? name, ? xml FROM dual) d ON (x.app_name = d.name) WHEN MATCHED THEN UPDATE SET x.xml_blob = d.xml WHEN NOT MATCHED THEN INSERT(app_name, xml_blob) VALUES(d.name, d.xml)",
new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException {
ps.setString(1, appName);
lobCreator.setClobAsString(ps, 2, xmlBlob);
}
});
lobHandler is an instance of OracleLobHandler that's injected in the context.
The exception:
Caused by: java.sql.SQLException: Invalid column type
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:9231)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8812)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:9534)
at oracle.jdbc.driver.OraclePreparedStatement.setObject(OraclePreparedStatement.java:9517)
at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:351)
at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:216)
at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:144)
at org.springframework.jdbc.core.ArgPreparedStatementSetter.doSetValue(ArgPreparedStatementSetter.java:65)
at org.springframework.jdbc.core.ArgPreparedStatementSetter.setValues(ArgPreparedStatementSetter.java:46)
at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:815)
at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:1)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:586)
This is Spring framework 3.0.5.RELEASE.
Our oracle driver dependency is
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.3.0</version>
</dependency>
The table:
SQL> desc app_role_data
Name Null? Type
----------------------------------------- -------- ----------------------------
APP_NAME VARCHAR2(64)
XML_BLOB CLOB
I'm not even sure what other information I can add, but I'll be happy to do so if I've left something out.

Turns out, execute() takes a PreparedStatementCallback, while update() takes a PreparedStatementSetter. But both have overloads that take Object, so the compiler doesn't complain.
Grumble. That's a day of my life I'll never get back.

I am being a little skeptical about the column names here
Can you try something like below in your MERGE
select ? as name, ? as xml FROM dual
But I am skeptical of that too since the way you can have dynamic column names is by creating a dynamic sql and executing it with EXECUTE IMMEDIATE.
Or may be something like this (not best in terms of Oracle)-
jdbcTemplate.update("MERGE INTO app_role_data x USING dual d ON (x.app_name = ?) WHEN MATCHED THEN UPDATE SET x.xml_blob = ? WHEN NOT MATCHED THEN INSERT(app_name, xml_blob) VALUES(?, ?)",......

Related

SpringBootTest in error with h2 v2.1.214 because of PageRequest

I have some tests in error after upgrading from Spring boot 2.5.6 to 2.7.3.
For information we use Oracle for the database and h2 for tests.
I have some tests in failure with the following error:
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException
In fact, the version of h2 was 1.4.200 before and is 2.1.214 now and a lot of things seem to have changed. The reason of the error is not always the same according to the test in error. Sometimes it is an error with a table not found (not solved yet), sometimes it is an error with "Values of types "BOOLEAN" and "INTEGER" are not comparable" (solved by updating a query where a comparison was done with a boolean column like this myBoolean = 0 and it has been updated to myBoolean = false) and I also have an error on a query done with a PageRequest.
For this last case, I have a Controller like this:
public Page<MyEntity> doSomething() {
final Sort sort = Sort.by(Order.desc("column1"));
final PageRequest pageRequest = PageRequest.of(0, 1000, sort);
return myEntityRepository.findAll(pageRequest);
}
But I have an error like that:
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "select myentity0_.id as id1_47_, myentity0_.column1 as column1_47_, myentity0_.column2 as column2_47_ from my_table myentity0_ order by myentity0_.column1 desc [*]limit ?"; SQL statement:
select myentity0_.id as id1_47_, myentity0_.column1 as column1_47_, myentity0_.column2 as column2_47_ from my_table myentity0_ order by myentity0_.column1 desc limit ? [42000-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:502)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
at org.h2.message.DbException.get(DbException.java:223)
at org.h2.message.DbException.get(DbException.java:199)
at org.h2.message.DbException.getSyntaxError(DbException.java:247)
at org.h2.command.Parser.getSyntaxError(Parser.java:898)
at org.h2.command.Parser.prepareCommand(Parser.java:572)
at org.h2.engine.SessionLocal.prepareLocal(SessionLocal.java:631)
at org.h2.engine.SessionLocal.prepareCommand(SessionLocal.java:554)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1116)
at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:92)
at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:288)
at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:337)
at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:149)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176)
... 205 more
If I change the Controller like this,the test is in success:
public Page<MyEntity> doSomething() {
List<MyEntity> result = myEntityRepository.findAll();
return new PageImpl<MyEntity>(result);
}
So It seems that the problem was due by the use of PageRequest.
Do you have an idea please?
Java persistence libraries are usually tested only with default Regular mode of H2 and may not work well with other modes.
Oracle doesn't support MySQL/PostgreSQL-style LIMIT, and H2 doesn't allow it in Oracle compatibility mode, but some libraries produce LIMIT instead of standard OFFSET / FETCH for H2.
Spring Data JDBC (spring-data-relational) added support of custom compatibility modes of H2 only about a month ago and version 2.4.3 with this fix isn't released yet.
Hibernate ORM 6.*.* should work well, but Hibernate ORM 5.6.* has a known issue:
https://hibernate.atlassian.net/jira/software/c/projects/HHH/issues/HHH-15318
You can enable LIMIT in Oracle compatibility mode of H2 as a temporary workaround. To do that, you need to execute the following Java code during initialization of your application:
org.h2.engine.Mode mode = org.h2.engine.Mode.getInstance("ORACLE");
mode.limit = true;

Function not found when generating code with DDL Database - jooq

I have a spring boot gradle project with a mysql database. Previously under jooq version 3.13.6 my sql was parsed without errors. When updating to a higher jooq version (3.14.X and 3.15.X) and generating/parsing the migrations with jooq, I get the following output:
SEVERE DDLDatabase Error: Your SQL string could not be parsed or
interpreted. This may have a variety of reasons, including:
The jOOQ parser doesn't understand your SQL
The jOOQ DDL simulation logic (translating to H2) cannot simulate your SQL
org.h2.jdbc.JdbcSQLSyntaxErrorException: Function "coalesce" not found;
A basic sql example where the error occurs is given below. Parsing the same view worked with jooq 3.13.6.
DROP VIEW IF EXISTS view1;
CREATE VIEW view1 AS
SELECT COALESCE(SUM(table1.col1), 0) AS 'sum'
FROM table1;
I am currently lost here. I don't see any related changes in the jooq changelog.
Any help or directions to further have a look into are highly appreciated.
Extended Stacktrace:
11:10:30 SEVERE DDLDatabase Error : Your SQL string could not be parsed or interpreted. This may have a variety of reasons, including:
- The jOOQ parser doesn't understand your SQL
- The jOOQ DDL simulation logic (translating to H2) cannot simulate your SQL
If you think this is a bug or a feature worth requesting, please report it here: https://github.com/jOOQ/jOOQ/issues/new/choose
As a workaround, you can use the Settings.parseIgnoreComments syntax documented here:
https://www.jooq.org/doc/latest/manual/sql-building/dsl-context/custom-settings/settings-parser/
11:10:30 SEVERE Error while loading file: /Users/axel/projects/service/./src/main/resources/db/migration/V5__create_view1.sql
11:10:30 SEVERE Error in file: /Users/axel/projects/service/build/tmp/generateJooq/config.xml. Error : Error while exporting schema
org.jooq.exception.DataAccessException: Error while exporting schema
at org.jooq.meta.extensions.AbstractInterpretingDatabase.connection(AbstractInterpretingDatabase.java:103)
at org.jooq.meta.extensions.AbstractInterpretingDatabase.create0(AbstractInterpretingDatabase.java:77)
at org.jooq.meta.AbstractDatabase.create(AbstractDatabase.java:332)
at org.jooq.meta.AbstractDatabase.create(AbstractDatabase.java:322)
at org.jooq.meta.AbstractDatabase.setConnection(AbstractDatabase.java:312)
at org.jooq.codegen.GenerationTool.run0(GenerationTool.java:531)
at org.jooq.codegen.GenerationTool.run(GenerationTool.java:237)
at org.jooq.codegen.GenerationTool.generate(GenerationTool.java:232)
at org.jooq.codegen.GenerationTool.main(GenerationTool.java:204)
Caused by: org.jooq.exception.DataAccessException: SQL [create view "view1" as select "coalesce"("sum"("table1"."col1"), 0) "sum" from "table1"]; Function "coalesce" not found; SQL statement:
create view "view1" as select "coalesce"("sum"("table1"."col1"), 0) "sum" from "table1" [90022-200]
at org.jooq_3.15.5.H2.debug(Unknown Source)
at org.jooq.impl.Tools.translate(Tools.java:2988)
at org.jooq.impl.DefaultExecuteContext.sqlException(DefaultExecuteContext.java:639)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:349)
at org.jooq.meta.extensions.ddl.DDLDatabase.load(DDLDatabase.java:183)
at org.jooq.meta.extensions.ddl.DDLDatabase.lambda$export$0(DDLDatabase.java:156)
at org.jooq.FilePattern.load0(FilePattern.java:307)
at org.jooq.FilePattern.load(FilePattern.java:287)
at org.jooq.FilePattern.load(FilePattern.java:300)
at org.jooq.FilePattern.load(FilePattern.java:251)
at org.jooq.meta.extensions.ddl.DDLDatabase.export(DDLDatabase.java:156)
at org.jooq.meta.extensions.AbstractInterpretingDatabase.connection(AbstractInterpretingDatabase.java:100)
... 8 more
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Function "coalesce" not found; SQL statement:
create view "view1" as select "coalesce"("sum"("table1"."col1"), 0) "sum" from "table1" [90022-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:576)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
at org.h2.message.DbException.get(DbException.java:205)
at org.h2.message.DbException.get(DbException.java:181)
at org.h2.command.Parser.readJavaFunction(Parser.java:3565)
at org.h2.command.Parser.readFunction(Parser.java:3770)
at org.h2.command.Parser.readTerm(Parser.java:4305)
at org.h2.command.Parser.readFactor(Parser.java:3343)
at org.h2.command.Parser.readSum(Parser.java:3330)
at org.h2.command.Parser.readConcat(Parser.java:3305)
at org.h2.command.Parser.readCondition(Parser.java:3108)
at org.h2.command.Parser.readExpression(Parser.java:3059)
at org.h2.command.Parser.readFunctionParameters(Parser.java:3778)
at org.h2.command.Parser.readFunction(Parser.java:3772)
at org.h2.command.Parser.readTerm(Parser.java:4305)
at org.h2.command.Parser.readFactor(Parser.java:3343)
at org.h2.command.Parser.readSum(Parser.java:3330)
at org.h2.command.Parser.readConcat(Parser.java:3305)
at org.h2.command.Parser.readCondition(Parser.java:3108)
at org.h2.command.Parser.readExpression(Parser.java:3059)
at org.h2.command.Parser.parseSelectExpressions(Parser.java:2931)
at org.h2.command.Parser.parseSelect(Parser.java:2952)
at org.h2.command.Parser.parseQuerySub(Parser.java:2817)
at org.h2.command.Parser.parseSelectUnion(Parser.java:2649)
at org.h2.command.Parser.parseQuery(Parser.java:2620)
at org.h2.command.Parser.parseCreateView(Parser.java:6950)
at org.h2.command.Parser.parseCreate(Parser.java:6223)
at org.h2.command.Parser.parsePrepared(Parser.java:903)
at org.h2.command.Parser.parse(Parser.java:843)
at org.h2.command.Parser.parse(Parser.java:815)
at org.h2.command.Parser.prepareCommand(Parser.java:738)
at org.h2.engine.Session.prepareLocal(Session.java:657)
at org.h2.engine.Session.prepareCommand(Session.java:595)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1235)
at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:212)
at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:201)
at org.jooq.tools.jdbc.DefaultStatement.execute(DefaultStatement.java:102)
at org.jooq.impl.SettingsEnabledPreparedStatement.execute(SettingsEnabledPreparedStatement.java:227)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:414)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:335)
... 16 more
> Task :generateJooq FAILED
Jooq Configuration:
jooq {
version = "3.15.5"
edition = JooqEdition.OSS
configurations {
main {
generationTool {
generator {
name = 'org.jooq.codegen.KotlinGenerator'
strategy {
name = 'org.jooq.codegen.DefaultGeneratorStrategy'
}
generate {
relations = true
deprecated = false
records = true
immutablePojos = true
fluentSetters = true
daos = false
pojosEqualsAndHashCode = true
javaTimeTypes = true
}
target {
packageName = 'de.project.service.jooq'
}
database {
name = 'org.jooq.meta.extensions.ddl.DDLDatabase'
properties {
property {
key = 'scripts'
value = 'src/main/resources/db/migration/*.sql'
}
property {
key = 'sort'
value = 'semantic'
}
property {
key = 'unqualifiedSchema'
value = 'none'
}
property {
key = 'defaultNameCase'
value = 'lower'
}
}
}
}
}
}
}
You probably have the following configuration set:
<property>
<key>defaultNameCase</key>
<value>lower</value>
</property>
In jOOQ 3.15, this transforms all identifiers to lower case and quotes them before handing the SQL statement to H2 behind the scenes for DDL simulation, in order to emulate e.g. PostgreSQL behaviour, where unquoted identifiers are lower case, not upper case as in many other RDBMS.
There's a bug in the current implementation, which also quotes built-in functions, not just user defined objects. See:
https://github.com/jOOQ/jOOQ/issues/9931 (general problem related to "system names")
https://github.com/jOOQ/jOOQ/issues/12752 (DDLDatabase specific problem)
The only workaround I can think of would be to turn off that property again, and manually quote all identifiers to be lower case. Alternatively, instead of using the DDLDatabase, you can always connect to an actual database instead, e.g. by using testcontainers. This will be much more robust in many ways, anyway, than the DDLDatabase
In any case, this is quite the frequent problem, so, I've fixed this for the upcoming jOOQ 3.16. The above setting will no longer quote "system names", which are well known identifiers of built-in functions

Write custom H2 DB function Java

I am trying to run the below code using H2DB (via junit test), while doing so i get error message as below. I understand that, there are no function available as "days" in H2. So i am trying to write a custom function, but it does not work out, can any one help on writing this function.
SQLBuilder class code:
public String dummy() {
return new StringBuilder(new SQL() {
{
SELECT("date(CREATE_TMS)");
SELECT("CASE WHEN date(CREATE_TMS) >= (CURRENT DATE - cast('1' AS integer) days) THEN 'Y' ELSE 'N' END NEW_B");
FROM("Q.DUMMY");
}
}.toString().concat(" FOR READ ONLY WITH UR")).toString();
}
Error message:
org.springframework.jdbc.BadSqlGrammarException:
### Error querying database. Cause: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "SELECT DATE(CREATE_TMS), CASE WHEN DATE(CREATE_TMS) >= (CURRENT DATE - CAST('1' AS INTEGER) DAYS[*]) THEN 'Y' ELSE 'N' END NEW_BILLING
FROM Q.DUMMY FOR READ ONLY WITH UR "; expected "[, ::, *, /, %, +, -, ||, ~, !~, NOT, LIKE, ILIKE, REGEXP, IS, IN, BETWEEN, AND, OR, ,, )"; SQL statement:
SELECT date(CREATE_TMS), CASE WHEN date(CREATE_TMS) >= (CURRENT DATE - cast('1' AS integer) days) THEN 'Y' ELSE 'N' END NEW_BILLING
FROM Q.DUMMY FOR READ ONLY WITH UR [42001-199]
For some reason days are converted to DAYS[*], we can see that in error message.
Customer method i tried in schema-db2.sql:
drop ALIAS if exists days;
CREATE ALIAS days as '
import java.lang.String;
#CODE
java.lang.String days() throws Exception {
return "days";
}
';
applicaiton.properties:
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false;Mode=DB2
DAYS is not a function and is not a something that other databases support. Db2 also uses non-standard interval literals.
If you can build H2 from its current sources, you can use cast('1' AS integer) day in it (not the days) and such construction is also supported by Db2. You can also simply use 1 DAY, it is supported by current H2 and Db2 too.
(CURRENT_DAY - 1 DAY)
Sources of H2 are available on GitHub:
https://github.com/h2database/h2database
Building instructions are here:
https://h2database.com/html/build.html#building
You need a jar target.
To compile H2 from the current sources you need JDK 8, 9, 10, 11, or 12. Compiled jar will be compatible with more recent versions.

jdbcType=BIGDECIMAL not supported in mybatis and ibatis

Using jdbcType=BIGDECIMAL is not supported in myBatis and ibatis and is throwing the next error:
Error resolving JdbcType. Cause: java.lang.IllegalArgumentException:
No enum constant org.apache.ibatis.type.JdbcType.BIGDECIMAL
What is the jdbcType alternative instead of BIGDECIMAL?
I'm using mybatis-3.4.4 version
That's happen because BIGDECIMAL jdbc type doesn't exist. Just take a look the enum JdbcType of org.apache.ibatis.type.
You should use DECIMAL.
The list of JdbcTypes available in JdbcType enum:
ARRAY(2003),
BIT(-7),
TINYINT(-6),
SMALLINT(5),
INTEGER(4),
BIGINT(-5),
FLOAT(6),
REAL(7),
DOUBLE(8),
NUMERIC(2),
DECIMAL(3),
CHAR(1),
VARCHAR(12),
LONGVARCHAR(-1),
DATE(91),
TIME(92),
TIMESTAMP(93),
BINARY(-2),
VARBINARY(-3),
LONGVARBINARY(-4),
NULL(0),
OTHER(1111),
BLOB(2004),
CLOB(2005),
BOOLEAN(16),
CURSOR(-10),
UNDEFINED(-2147482648),
NVARCHAR(-9),
NCHAR(-15),
NCLOB(2011),
STRUCT(2002),
JAVA_OBJECT(2000),
DISTINCT(2001),
REF(2006),
DATALINK(70),
ROWID(-8),
LONGNVARCHAR(-16),
SQLXML(2009),
DATETIMEOFFSET(-155);
By using below type handler I have resolved my same issue:
<insert id=".......">
INSERT INTO demo (number_of_cities)
VALUES( #{numberOfCities, typeHandler=org.apache.ibatis.type.BigDecimalTypeHandler});
</insert>

H2 database inserting data exception after adding new column with ALTER TABLE

I am adding new column to my table like below code:
String sql = "ALTER TABLE PROJE_ALAN ADD NEWCOLUMN VARCHAR(30)";
PreparedStatement ps = conn.prepareStatement(sql.toString());
ps.execute();
conn.close();
ps.close();
This is adding a new column to my table but when I want to add new data throws an exception:
Caused by: org.h2.jdbc.JdbcSQLException: General error: "net.sourceforge.hatbox.RTreeInternalException: Unable to select meta node"; SQL statement: INSERT INTO "PROJE_ALAN" ( "THE_GEOM","JJ","KK","NEWCOLUMN" ) VALUES ( ST_GeomFromText ('MULTIPOLYGON (((-244856.06897661195 4166022.019422841, 189248.78294214187 4442270.561552957, 778743.439809086 4301679.785647452, 662817.7123080553 4101892.893571207, 83189.0748029009 3707252.1190996123, -244856.06897661195 4166022.019422841)))',23036),'','','') [50000-172]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.get(DbException.java:158)
at org.h2.message.DbException.convert(DbException.java:281)
at org.h2.schema.TriggerObject.fireRow(TriggerObject.java:215)
at org.h2.table.Table.fireRow(Table.java:904)
at org.h2.table.Table.fireAfterRow(Table.java:895)
at org.h2.command.dml.Insert.insertRows(Insert.java:128)
at org.h2.command.dml.Insert.update(Insert.java:86)
at org.h2.command.CommandContainer.update(CommandContainer.java:79)
at org.h2.command.Command.executeUpdate(Command.java:235)
at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:180)
at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:155)
at org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:264)
at org.apache.commons.dbcp.DelegatingStatement.execute(DelegatingStatement.java:264)
at org.geotools.jdbc.JDBCDataStore.insert(JDBCDataStore.java:1447)
... 17 more
Caused by: net.sourceforge.hatbox.RTreeInternalException: Unable to select meta node
at net.sourceforge.hatbox.Lock.<init>(Lock.java:88)
at net.sourceforge.hatbox.RTreeSessionDb.<init>(RTreeSessionDb.java:75)
at net.sourceforge.hatbox.jts.InsertTrigger.fire(InsertTrigger.java:43)
at org.h2.schema.TriggerObject.fireRow(TriggerObject.java:201)
... 28 more
Caused by: org.h2.jdbc.JdbcSQLException: Table "PROJE_ALAN_COPY_11_5_HATBOX" not found; SQL statement: select node_data, id from "PUBLIC"."PROJE_ALAN_COPY_11_5_HATBOX" where id = ? FOR UPDATE [42102-172]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.get(DbException.java:169)
at org.h2.message.DbException.get(DbException.java:146)
at org.h2.schema.Schema.getTableOrView(Schema.java:419)
at org.h2.command.Parser.readTableOrView(Parser.java:4808)
at org.h2.command.Parser.readTableFilter(Parser.java:1099)
at org.h2.command.Parser.parseSelectSimpleFromPart(Parser.java:1705)
at org.h2.command.Parser.parseSelectSimple(Parser.java:1813)
at org.h2.command.Parser.parseSelectSub(Parser.java:1699)
at org.h2.command.Parser.parseSelectUnion(Parser.java:1542)
at org.h2.command.Parser.parseSelect(Parser.java:1530)
at org.h2.command.Parser.parsePrepared(Parser.java:405)
at org.h2.command.Parser.parse(Parser.java:279)
at org.h2.command.Parser.parse(Parser.java:251)
at org.h2.command.Parser.prepareCommand(Parser.java:218)
at org.h2.engine.Session.prepareLocal(Session.java:425)
at org.h2.engine.Session.prepareCommand(Session.java:374)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1138)
at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:70)
at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:644)
at net.sourceforge.hatbox.Lock.<init>(Lock.java:72)
... 31 more
If I restart my application then I can add new data to new table. I think problem can be refreshing indexes without restarting application. Maybe It is related with Hat Box.
So what am I missing?
It's not Hatbox's fault. It's a bug in H2. H2 engine is recreates triggers after an ALTER TABLE statement, but calling trigger.init with TEMP TABLE NAME. Because of that, the trigger is being initialized with the wrong table name. After creating triggers, H2 renames the table to the original value.
My workaround for this bug is (it's buggy too, but working):
Changed net.sourceforge.hatbox.jts.Insert, Update, Delete trigger init methods to
public void init(Connection con, String schema, String trigger, String table,
boolean before, int type) throws SQLException {
this.schema = schema;
this.table = table;
if(this.table.contains("_COPY_")) {
this.table = table.substring(0, table.indexOf("_COPY_"));
}
}
You have to be while using this, if you have COPY on your table name, it will not work. You may change _COPY_ to *_COPY_?_? like regex matching.

Resources