Error When Setting up H2 Database - java

I have been getting this error when I'm starting my application which on start up reads some data from a table:
org.h2.jdbc.JdbcSQLException: Unknown data type: "ENUM"; SQL statement:
CREATE CACHED TABLE PUBLIC.POWERPLANT(
POWERPLANTID INT NOT NULL,
ORGNAME VARCHAR(25) NOT NULL,
ISACTIVE BOOL NOT NULL,
MINPOWER INT NOT NULL,
MAXPOWER INT NOT NULL,
RAMPRATE INT,
RAMPRATESECS INT,
POWERPLANTTYPE ENUM('OnOffType','RampUpType'),
CREATEDAT TIMESTAMP NOT NULL,
UPDATEDAT TIMESTAMP NOT NULL
) [50004-186]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.command.Parser.parseColumnWithType(Parser.java:3990)
at org.h2.command.Parser.parseColumnForTable(Parser.java:3853)
at org.h2.command.Parser.parseCreateTable(Parser.java:5761)
at org.h2.command.Parser.parseCreate(Parser.java:4149)
at org.h2.command.Parser.parsePrepared(Parser.java:350)
at org.h2.command.Parser.parse(Parser.java:305)
at org.h2.command.Parser.parse(Parser.java:277)
Here is my connection string:
db.url = "jdbc:h2:~/path/to/db/file;MODE=MySQL;INIT=CREATE DOMAIN IF NOT EXISTS enum as VARCHAR(255);IFEXISTS=TRUE"
Any idea as to how to solve this?

I've solved the same problem by updating h2 Maven library version to 1.4.200 instead of 1.4.187

Here is how I solved it. The Enum type should be written like this!
powerPlantType VARCHAR(25) check (powerPlantType in ('OnOffType', 'RampUpType')),

Related

How to Insert binary data with in insert query into Postgresql using jdbc

I have table structure like below
CREATE TABLE PUBLIC.STAFF(
STAFF_ID INT NOT NULL,
FIRST_NAME VARCHAR(45) NOT NULL,
LAST_NAME VARCHAR(45) NOT NULL,
ADDRESS_ID SMALLINT NOT NULL,
PICTURE BYTEA,
EMAIL VARCHAR(50),
STORE_ID INT NOT NULL,
ACTIVE BOOLEAN NOT NULL,
USERNAME VARCHAR(16) NOT NULL,
PASSWORD VARCHAR(40),
LAST_UPDATE TIMESTAMP NOT NULL
);
and I have couple of insert queries in script file or stored in arraylist like
INSERT INTO STAFF(STAFF_ID, FIRST_NAME, LAST_NAME, ADDRESS_ID, PICTURE, EMAIL, STORE_ID, ACTIVE, USERNAME, PASSWORD, LAST_UPDATE)
VALUES (
1,
'Mike',
'Hillyer',
3,
X'89504e470d0a1a0a0000000d4948445200000079000000750802000000e55ad965000000097048597300000ec300000ec301c76fa8640000200049444154789c4cbb7794246779ffbbf78f7b7ebe466177677772ce3d9d667aa67ba62776ce39545557ce3974ee9eb049ab95563922104142580830d10203061bb049064cb031d916c160100284505aedee4cdd3f16b8b7ce73de53f5d61f75cee7bcf53ccff7fb561dbb7ce9ad972fbdf5aecb6fbd74e7a3b75f7ef4ce7bde72e9ae375fbaffcd676ebff7e29d658c864812c0e90acec0040d123aad8a284f950906205810672b140d900226b218c713028f0a5c8',
'Mike.Hillyer#sakilastaff.com',
1,
TRUE,
'Mike',
'8cb2237d0679ca88db6464eac60da96345513964',
TIMESTAMP '2006-02-15 04:57:16.0'
);
When I am trying to insert the data into postgres using JDBC program I am getting the following error:
ERROR: column "picture" is of type bytea but expression is of type bit
LINE 2: (1, 'Mike', 'Hillyer', 3, X'89504e470d0a1a0a0000000d49484452..
HINT: You will need to rewrite or cast the expression.
********** Error **********
ERROR: column "picture" is of type bytea but expression is of type bit
How to solve this issue using Java?
Try this:
E'\\x89504e470d0a1a0a0000000d4948445200000079000000750802000000e55ad965000000097048597300000ec300000ec301c76fa8640000200049444154789c4cbb7794246779ffbbf78f7b7ebe466177677772ce3d9d667aa67ba62776ce39545557ce3974ee9eb049ab95563922104142580830d10203061bb049064cb031d916c160100284505aedee4cdd3f16b8b7ce73de53f5d61f75cee7bcf53ccff7fb561dbb7ce9ad972fbdf5aecb6fbd74e7a3b75f7ef4ce7bde72e9ae375fbaffcd676ebff7e29d658c864812c0e90acec0040d123aad8a284f950906205810672b140d900226b218c713028f0a5c8'
Yes, when accessing form java it is recommended to use prepared statement. An example can be found here.
But sometimes you need to do it in SQL. In this case should use slightly different notation. Just use \x at the beginning of a string like follows (no need for any special prefixes, but note that x is lowercase):
'\x89504e470d0a1a0a0000000d4948445200000079000000750802000000e55ad965000000097048597300000ec300000ec301c76fa8640000200049444154789c4cbb7794246779ffbbf78f7b7ebe466177677772ce3d9d667aa67ba62776ce39545557ce3974ee9eb049ab95563922104142580830d10203061bb049064cb031d916c160100284505aedee4cdd3f16b8b7ce73de53f5d61f75cee7bcf53ccff7fb561dbb7ce9ad972fbdf5aecb6fbd74e7a3b75f7ef4ce7bde72e9ae375fbaffcd676ebff7e29d658c864812c0e90acec0040d123aad8a284f950906205810672b140d900226b218c713028f0a5c8'
Note that older versions of PostgreSQL only supported Escape Format which uses octal form to encode arbitrary bytes, not hex. Also note that Escape Format needs ::bytea ending.
Details can be found here (substitute version in the url to whichever you are using).
P.S. Obviously way too late for the original question, but this is where an online search lands. So, documenting it here.

java.sql.SQLException: Unexpected token: REFERENCES

I'm getting an exception for my Create Statement query when using hibernate-sql mapping. Here is the create statement (Postgres) and the error it complains about.
Query:
CREATE TABLE translation (
translation_id INTEGER NOT NULL DEFAULT nextval('translation_seq'::regclass) PRIMARY KEY,
category TEXT NOT NULL,
sub_category TEXT DEFAULT NULL,
prod_id INTEGER NOT NULL REFERENCES product(product_id),
date_created DATE DEFAULT now() NOT NULL,
expired BOOLEAN DEFAULT FALSE NOT NULL
);
Exception / failure in the Test:
java.lang.RuntimeException: HypersonicAccessor.dbInitSchema() failure.
at com.package1.package2.package3.database.HypersonicAccessor.dbInitSchema(HypersonicAccessor.java:210)
at com.package1.package2.package3.someDbConfig.initialize(ProdDbConfig.java:145)
at com.package1.package2.package3.backend.client.UpdaterTest.setUp(UpdaterTest.java:57)
Caused by: java.sql.SQLException: Unexpected token: REFERENCES in statement
[CREATE TABLE TRANSLATION (TRANSLATION_ID BIGINT NOT NULL PRIMARY KEY,
CATEGORY VARCHAR NOT NULL, SUB_CATEGORY VARCHAR DEFAULT NULL,
PROD_ID BIGINT NOT NULL REFERENCES]
at com.package1.package2.package3.database.HypersonicDatabase.execute(HypersonicDatabase.java:146)
at com.package1.package2.package3.database.HypersonicDatabase.runSqlScript(HypersonicDatabase.java:169)
at com.package1.package2.package3.database.HypersonicAccessor.runScriptList(HypersonicAccessor.java:123)
at com.package1.package2.package3.database.HypersonicAccessor.dbInitSchema(HypersonicAccessor.java:157)
Im not sure if my query is wrong or something else is. Any clue what could possibly be wrong ? This actually is the same issue with a few of my tests that previously were passing but now they are not.

Creating table dynamically by SQL in Servlet

I am getting error in this: prepared statement.
Prepared Statement:
PreparedStatement pStatement=connection.prepareStatement
("CREATE TABLE `details`.?(`ID` VARCHAR(255) NOT NULL,`Score` VARCHAR(255) NULL);
INSERT INTO `testdetails`.? (`ID`) VALUES (?);");
pStatement.setString(1, "usrname");
pStatement.setString(2, "usrname");
pStatement.setString(3, "001");
pStatement.executeUpdate();
Error details:
Severe: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near
''usrname'(`ID` VARCHAR(255) NOT NULL,`Score` VARCHAR(255) NULL);INSER' at line 1
How to fix this error?
JDBC parameters aren't usually usable for table and column names - they're only for values.
Unfortunately, I think this is one of those cases where you will need to be build the SQL dynamically. You will want to be very careful about which values you allow, of course.
This error appears because, you use #setString, and the string gets wrapped by ''.
To fix this, you can use one of this snippets:
"CREATE TABLE `details`.#tableName#(`ID` VARCHAR(255) NOT NULL,`Score` VARCHAR(255) NULL); INTO `testdetails`.#tableName# (`ID`) VALUES (?);".replaceAll("#tableName#", "usrname");
or
new StringBuilder("CREATE TABLE `details`.").append("usrname").append("(`ID` VARCHAR(255) NOT NULL,`Score` VARCHAR(255) NULL); INTO `testdetails`.").append("usrname").append("(`ID`) VALUES (?);").toString();
and pass resulted string into #prepareStatement() method.

Running h2 in MODE=MySQL doesn't support MySQL dumps

I'm trying to embed h2 to test my mysql-application (integration-test)
I added com.h2database:h2:1.3.170 via maven and run the following code:
public class InMemoryTest
{
#Test
public void test() throws Exception {
Class.forName("org.h2.Driver");
Connection conn = DriverManager.
getConnection("jdbc:h2:mem:test;MODE=MySQL;IGNORECASE=TRUE;INIT=RUNSCRIPT FROM 'src/test/resources/test.sql'");
}
}
which gives me the following Exception:
Syntax error in SQL statement "
CREATE TABLE IF NOT EXISTS ""usr_avatar"" (
""usr_avatar_id"" INT(11) NOT NULL AUTO_INCREMENT,
""usr_avatar_user_id"" INT(11) NOT NULL,
""usr_avatar_img"" BLOB NOT NULL,
PRIMARY KEY (""usr_avatar_id""),
UNIQUE KEY ""usr_avatar_id_UNIQUE"" (""usr_avatar_id""),
UNIQUE KEY ""usr_avatar_user_id_UNIQUE"" (""usr_avatar_user_id""),
KEY ""usr_user_id"" (""usr_avatar_user_id""),
KEY ""fk_user_id"" (""usr_avatar_user_id"")
) AUTO_INCREMENT[*]=1 ";
Apparently, the "AUTO_INCREMENT" causes this?
Since this is valid MySQL (I exported the dump from my real database using MySQL Workbench), I'm a bit confused since h2 claims to support MySQL?
Here are a few lines from the .sql:
DROP TABLE IF EXISTS `usr_avatar`;
CREATE TABLE IF NOT EXISTS "usr_avatar" (
"usr_avatar_id" int(11) NOT NULL AUTO_INCREMENT,
"usr_avatar_user_id" int(11) NOT NULL,
"usr_avatar_img" blob NOT NULL,
PRIMARY KEY ("usr_avatar_id"),
UNIQUE KEY "usr_avatar_id_UNIQUE" ("usr_avatar_id"),
UNIQUE KEY "usr_avatar_user_id_UNIQUE" ("usr_avatar_user_id"),
KEY "usr_user_id" ("usr_avatar_user_id"),
KEY "fk_user_id" ("usr_avatar_user_id")
) AUTO_INCREMENT=1 ;
DROP TABLE IF EXISTS `usr_restriction`;
CREATE TABLE IF NOT EXISTS "usr_restriction" (
"usr_restriction_id" int(11) NOT NULL AUTO_INCREMENT,
"usr_restriction_user_id" int(11) DEFAULT NULL,
"usr_restriction_ip" varchar(39) DEFAULT NULL,
"usr_restriction_valid_from" date NOT NULL,
"usr_restriction_valid_to" date DEFAULT NULL,
PRIMARY KEY ("usr_restriction_id"),
UNIQUE KEY "usr_restriction_id_UNIQUE" ("usr_restriction_id"),
KEY "user_id" ("usr_restriction_user_id"),
KEY "usr_user_id" ("usr_restriction_user_id")
) AUTO_INCREMENT=1 ;
What are my options? Should I export the dump with a different software and force it to be plain SQL? Which software could do that? Or am I doing something wrong?
The problem is that H2 doesn't support AUTO_INCREMENT=1, which you have specified in the SQL statement. Try removing it. I don't think it's necessary for MySQL either.
The source SQL exported from MySQL has double-quotes surrounding it's literals. The first DROP statement also has a "back-tick" (`). But when H2 is reporting the error, H2 is showing the literals surrounded by double-double quotes. I think this is the problem.
Try a couple of things. First, take the back-tick in the DROP statement and convert it to single quotes. If that doesn't work, convert all of the double-quotes to single-quotes. If that doesn't work, remove all of the quotes.
I think H2 is trying to create tables with the double-quotes as a part of the actual table names/column names and this is causing it to bomb.
H2 doesn't support AUTO_INCREMENT=1.
Use this instead:
ALTER TABLE table_name ALTER COLUMN id RESTART WITH 1;

query runs fine in mysql and php but not in java

I have the following mysql query in PHP and it works fine.
$strUpdate = "INSERT INTO `batchfolder`.`newbatch` (`BatchID` ,`Batch` ,`barcode` ,`PG`)VALUES (NULL , '', '1', '')";
and is also fine when i run it directly in database.
However when I run it in java,
try {
conn = DriverManager.getConnection (url, userName, password);
Statement st = conn.createStatement();
st.execute("INSERT INTO `batchfolder`.`newbatch` (`BatchID` ,`Batch` ,`barcode` ,`PG`)VALUES (NULL , '', '1', '')");
st.close();
}
It gives the following error.
Exception in thread "main" java.sql.SQLException: Field 'Pre' doesn't have a default value
Pre is the the next row in the database and it does not have a default value.
My question is, then how does this query run fine in mysql and php.
P.S BatchID is an int(10) autoincremented value in newbatch.
This is my table structure.
CREATE TABLE IF NOT EXISTS `newbatch` (
`BatchID` int(10) NOT NULL AUTO_INCREMENT,
`Batch` varchar(100) NOT NULL,
`barcode` varchar(5) NOT NULL,
`Ly` varchar(5) NOT NULL DEFAULT '0',
`PG` varchar(5) NOT NULL,
`Pre` varchar(5) NOT NULL,
`Flu` varchar(5) NOT NULL,
`FluID` varchar(100) DEFAULT NULL,
`DateCreated` varchar(100) DEFAULT NULL,
`Comments` varchar(500) DEFAULT NULL,
PRIMARY KEY (`BatchID`),
UNIQUE KEY `FluID` (`FluID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1000160 ;
Are you absolutely sure this actually runs in PHP? You may just not be seeing the error message.
Try this again with display_errors = 'on' and error_reporting(E_ALL | E_STRICT);
This is a SQL error, it doesn't depend on the driver. The driver just displays the message to you.
UPDATE:
It looks like Java is turning off MySQL's strict mode for some reason. The only thing that (to my knowledge) should be able to cause this behavior is MySQL strict mode being off.
If strict mode is not enabled, MySQL sets the column to the implicit
default value for the column data type.
You can check the mode that your server is running on by SELECT ##GLOBAL.sql_mode;. Try that in both Java and PHP. If the results differ then that's your answer.
UPDATE2: Jep!
Looked at your table definition, you have Pre defined as not null, but you didnt specify a value for it in the insert, so it should show an error proper.
You have several database fields that are 'NOT NULL', so you must specify these in your INSERT statement. I couldn't imagine how this would work in PHP either.

Categories