NullPointerException while accessing HSQLDB database - java

I am accessing HSQLDB through A jdbc drive in my java program. The script file of the database is as follows.
CREATE SCHEMA PUBLIC AUTHORIZATION DBA
CREATE CACHED TABLE TBL1(ID CHAR(5),NAME VARCHAR(11),ZIP VARCHAR(11))
CREATE UNIQUE INDEX IDX_ID ON TBL1(ID)
CREATE CACHED TABLE TBL2(ID CHAR(5),STREET CHAR(5))
CREATE INDEX IDX_RS_ID ON TBL2(ID)
CREATE CACHED TABLE TBL3(ID VARCHAR(8) NOT NULL PRIMARY KEY,LON FLOAT,LAT FLOAT)
CREATE GLOBAL TEMPORARY MEMORY TABLE OVERLAY(ID CHAR(8),AROUTE CHAR(10),ZROUTE
CHAR(10),TYPE CHAR(8)) ON COMMIT PRESERVE ROWS
SET TABLE TBL1 INDEX'4490648 5643624 0'
SET TABLE TBL2 INDEX'529105280 529105280 0'
SET TABLE TBL3 INDEX'775814624 0'
CREATE VIEW OVERLAYSPAN (ID,STREET) AS SELECT DISTINCT ID, NAME FROM OVERLAY AS O, TBL2 as
R WHERE O.ID = R.ID
CREATE USER SA PASSWORD ""
GRANT DBA TO SA
SET WRITE_DELAY 10
In the java program, I am first removing all entries (1000 entries) from TBL1 and reinserting new entries (1500) in the same table. The program executes normally, but, when I am attempting to re-execute the same program, I am getting the following error.
java.sql.SQLException: error in script file line: 9 S1000 General error
java.lang.NullPointerException in statement [SET TABLE TBL2 INDEX'529105280 529105280 0']
Here is the fill stack trace from the program.
java.sql.SQLException: error in script file line: 9 S1000 General error java.lang.NullPointerException in statement [SET TABLE TBL2 INDEX'529105280 529105280 0']
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.jdbcConnection.<init>(Unknown Source)
at org.hsqldb.jdbcDriver.getConnection(Unknown Source)
at org.hsqldb.jdbcDriver.connect(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at HSQLTesting.main(HSQLTesting.java:98)
Where at line 98, the program is attempting to make a connection with the database.
Connection sqlconnect = DriverManager.getConnection("jdbc:hsqldb:file:C:/birdseyedb/birdseye", "SA", "");
Any idea what's going wrong here?
Thanks in advance.

Related

UCanAccess exception on open connection - UNIQUE constraint does not exist on referenced columns

I am trying to create a very simple connection to an access database (.accdb) in my java maven project using ucanaccess. The database is an external database and I just need to read the content of some tables for a migration task. I don't want to and shouldn't modify the tables or write anything in the database.
The java code, that I used is totally simple:
try (Connection connection = DriverManager.getConnection(databaseURL);) {
} catch (SQLException ex) { ex.printStackTrace(); }
But the connection fails right at the beginning with the following exception:
net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::5.0.0 a UNIQUE constraint does not exist on referenced columns: T1 in statement [ALTER TABLE T2 ADD CONSTRAINT "T2{2EB41B92-C3AB-4A64-A53C-B83095D76202}" FOREIGN KEY (C2) REFERENCES T1 (C1) ]
at net.ucanaccess.jdbc.UcanaccessDriver.connect(UcanaccessDriver.java:231)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:251)
at myproject.Application.main(Application.java:42)
Caused by: java.sql.SQLSyntaxErrorException: a UNIQUE constraint does not exist on referenced columns: T1 in statement [ALTER TABLE T2 ADD CONSTRAINT "T2{2EB41B92-C3AB-4A64-A53C-B83095D76202}" FOREIGN KEY (C2) REFERENCES T1 (C1) ]
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.executeUpdate(Unknown Source)
at net.ucanaccess.converters.LoadJet.exec(LoadJet.java:1510)
at net.ucanaccess.converters.LoadJet.access$000(LoadJet.java:74)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadForeignKey(LoadJet.java:695)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTableFKs(LoadJet.java:918)
at net.ucanaccess.converters.LoadJet$TablesLoader.recreate(LoadJet.java:807)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTableData(LoadJet.java:877)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTableData(LoadJet.java:871)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTableData(LoadJet.java:837)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTablesData(LoadJet.java:1029)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTables(LoadJet.java:1077)
at net.ucanaccess.converters.LoadJet$TablesLoader.access$3200(LoadJet.java:264)
at net.ucanaccess.converters.LoadJet.loadDB(LoadJet.java:1579)
at net.ucanaccess.jdbc.UcanaccessDriver.connect(UcanaccessDriver.java:218)
... 3 more
Caused by: org.hsqldb.HsqlException: a UNIQUE constraint does not exist on referenced columns: T1
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.TableWorks.checkCreateForeignKey(Unknown Source)
at org.hsqldb.TableWorks.addForeignKey(Unknown Source)
at org.hsqldb.StatementSchema.getResult(Unknown Source)
at org.hsqldb.StatementSchema.execute(Unknown Source)
at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
at org.hsqldb.Session.executeDirectStatement(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
... 18 more
I tried to make my connection "readonly", so that it doesn't check for this constraint and doesn't throw an exception. But I didn't have any success.
try (Connection connection = DriverManager.getConnection(databaseURL + ";readonly=true");) {
} catch (SQLException ex) { ex.printStackTrace(); }
Is there any way to turn off this constraint check, while creating the connection for reading some tables?
I can't post the database for reproducing the issue! Because it is a very complex database with many tables and relationships and it doesn't belong to me. I am not allowed to share it (even without data) because of General Data Protection Regulation.
Furthermore I didn't want to change anything in the database, therefore I wanted to turn off the constraint checks to be able to just connect to the database and just READ the rows of some tables.
At the end I made a copy of the database and delete all the relationships between the tables and the code could then connect to the db,
BUT:
IT TOOK 30 MINUTES TO CONNECT!!!! So, even if, I would have managed to make a copy from the database and delete all relationships between all tables each time I want to run my code (which actually isn't possible in my task), I should have waited 30 minutes to just open a connection!!!
I find it really ridiculous, that there is no possibility to turn off the constraint checks and open the connection for reading data, when some constraint aren't satisfied!!!
But anyway, at the end (after two days searching!) I found a solution for my work. I don't use any kind of Connection of DriverManager of this type:
Connection connection = DriverManager.getConnection(databaseURL)
Instead I use a DatabaseBuilder to open my database and get the tables and read the rows!
For anyone else, who have the same problem and just wants to connect to a MS-Access database in order to READ some data, without changing anything, I suggest this way. It is very easy and fast!
String fileName = "my_database.accdb";
File file = new File(fileName);
Database db = null;
DatabaseBuilder databaseBuilder = new DatabaseBuilder(file);
try {
db = databaseBuilder.open();
} catch(IOException e) {
e.printStackTrace();
}
Table myTable = db.getTable("myAccessTableName");
for(Row row : myTable) {
String firstName = row.getString("first_name");
String lastName = row.getString("last_name");
}
The Database, DatabaseBuilder, Row and Table are from "jackcess". So these imports are needed:
import com.healthmarketscience.jackcess.Database;
import com.healthmarketscience.jackcess.DatabaseBuilder;
import com.healthmarketscience.jackcess.Row;
import com.healthmarketscience.jackcess.Table;
More examples of using this way can be found here:
Java Code Examples
and here:
UCanAccess

HSQLDB INSERT Value in a Database

Hi i have a Problem while inserting data in my databases ...
String query = "INSERT INTO gutscheine (code, Wert) values ("+Code+","+Wert+")";
SQLConnection sql = new SQLConnection("Gutscheine.db");
PreparedStatement ps;
try {
ps = sql.con.prepareStatement(query);
int i = ps.executeUpdate();
if (i == -1) {
System.out.println("db error : " + query);
}
} catch (SQLException e) {
e.printStackTrace();
}
sql.CloseConnection(); // my own funktion
My Error:
java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: GUTSCHEINE
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source)
at org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source)
at com.daniel.guthaben.Gutschein.<init>(Gutschein.java:33)
at com.daniel.guthaben.Main.main(Main.java:7)
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: GUTSCHEINE
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.SchemaManager.getTable(Unknown Source)
at org.hsqldb.ParserDQL.readTableName(Unknown Source)
at org.hsqldb.ParserDQL.readRangeVariableForDataChange(Unknown Source)
at org.hsqldb.ParserDML.compileInsertStatement(Unknown Source)
at org.hsqldb.ParserCommand.compilePart(Unknown Source)
at org.hsqldb.ParserCommand.compileStatement(Unknown Source)
at org.hsqldb.Session.compileStatement(Unknown Source)
at org.hsqldb.StatementManager.compile(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
... 4 more
Here i am trying adding context from the root user ... (on the left you can see the table exists)
http://i.stack.imgur.com/FS5ws.png
Sorry I was using diffrent databases ... :(
it's generally not advised to use string building for your query. String query = "INSERT INTO gutscheine (code, Wert) values (?, ?)"; and then running it through a safe query preparation is going to be better.
That said, the error sounds pretty obvious? user lacks privilege or object not found: GUTSCHEINE. Doesn't look like you're connecting as a particular user from your code, so I suspect you forgot to pass along your username and password when setting up the database connection. If that part's fine, verify Gutscheine.db exists.
The problem here is simple. When you are inserting string values, you need to enclose them in single quotes.
For example, "insert into table(col1, col2) values ('ABC','xyz');"
Have a look at the example provided in this link:
https://www.tutorialspoint.com/hsqldb/hsqldb_insert_query.htm
In your case, you need to enclose the values of Code and Wert in single quotes before you insert, or at the time of insert.
The following approach worked for me:
Code = "'" + Code + "'";
Wert = "'" + Wert + "'";
Use your insert query now, and it should work.
Even though hsql is quite forgiving and requires no infrastructure, you need to create the table upfront - e.g.
CREATE TABLE Gutscheine ( code varchar 20, Wert varchar 20 )
Also, you might want to read about SQL-Injection and use PreparedStatement. While you're at it, google for "little bobby tables"
I haven't run into privilege issues with hsql yet, but you might want to check how you open the connection, e.g. if you give a proper user account. You can actually check a proper one by looking at the hsql storage, which is clear text. It should contain the required user name - e.g. "SA"
Also, with that error message on google, several threads come up that suggest that hsql version upgrade might help, or that you ended up with a corrupt database after not executing "SHUTDOWN;" after creation of the database. Another one is the database name "null" in your .script file. Well, check them for yourself and try which solution matches your problem (the two linked threads point to several possible solutions):
http://sourceforge.net/p/hsqldb/mailman/message/28944633/
http://www.coderanch.com/t/460394/JDBC/databases/HSQLDB-user-lacks-privilege-object

Derby SQL Script Bulk Import

my goal is to import data into a derby database. The data was extracted from a MySQL instance in form of a SQL dump and I took care with a script that I only use the insert-statements and also that the escaping of the MySQL specific syntax is transformed to Derby correctly.
To Test, I use the derby-maven-plugin:
export MAVEN_OPTS=-Xmx2048m; mvn derby:run
In the first step, I create the schema in the derby instance (using DDLUtils from MySQL, this works fine).
Second, I try to import the data. I use ij on the command line with the following (shortend) script:
CONNECT 'jdbc:derby://localhost:1527/foodmart';
SET SCHEMA APP;
autocommit off;
INSERT INTO "ACCOUNT" VALUES (1000,NULL,'Assets','Asset','~',NULL), (2000,NULL,'Liabilities','Liability','~',NULL),(3000,5000,'Net Sales','Income','+',NULL),(3100,3000,'Gross Sales','Income','+','LookUpCube(\"[Sales]\",\"(Measures.[Store Sales],\"+time.currentmember.UniqueName+\",\"+ Store.currentmember.UniqueName+\")\")'),(3200,3000,'Cost of Goods Sold','Income','-',NULL),(4000,5000,'Total Expense','Expense','-',NULL),(4100,4000,'General & Administration','Expense','+',NULL),(4200,4000,'Information Systems','Expense','+',NULL),(4300,4000,'Marketing','Expense','+',NULL),(4400,4000,'Lease','Expense','+',NULL),(5000,NULL,'Net Income','Income','+',NULL);
...
commit;
As you can see, for every row of a table there is a bracket containing the sample data.
There are of course several more insert statments for other tables. After finishing some inserts correctly, the bulk importing process chokes at a really big dataset (> 1000 rows) due to following exception (from the derby-logs):
java.lang.StackOverflowError
at org.apache.derby.impl.sql.compile.SetOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.UnionNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.TableOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.SetOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.UnionNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.TableOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.SetOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.UnionNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.TableOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.SetOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.UnionNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.TableOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.SetOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.UnionNode.bindExpressions(Unknown Source)
... and many lines more repeatingly because of the recursive nature...
Cleanup action completed
ij prints on the command line:
FEHLER XJ001: DERBY SQL error: SQLCODE: -1, SQLSTATE: XJ001, SQLERRMC: java.lang.StackOverflowError^T^TXJ001.U
Is this meaning, that derby is not capable using SQL-bulk-import scenarios?
Should I instead switching to an csv based import?
I assume from the stacktrace method calls that derby is not able to create the query plan.
Could it be possible, that for every 'data bracket' of an insert statement it will create internly an UNION statement, adding a big amount of overhead to each INSERT query.
So should I try to split my long INSERT-statements in many concise statements?
I don't have the time to look at the derby sources, so please help me!
I just used many Import statements and it worked.
It seems that for every data bracket of an INSERT statement Derby generates a method call on the stack, leeding for many brackets to a stackoverflow due to many recursive method calls.
However You just need to transform an INSERT statement from
Insert INTO VALUES (1,2,3), ..., (4,5,6);
To multiple statements:
Insert INTO VALUES (1,2,3);
...
Insert INTO VALUES (4,5,6);

Weird java.sql.SQLException error

I have a weird issue and most the stuff I seem to find on the web is referring to a driver or connection problem...
I am parsing threw a dBASE table to get some id numbers:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection cnxn = DriverManager.getConnection("jdbc:odbc:dBASE Files;DefaultDir=\"C:\"");
Statement stmt = cnxn.createStatement();
command = "SELECT * FROM table";
ResultSet result = stmt.executeQuery(command);
while (result.next()) {
System.out.println(result.getInt(1));
}
The result that i get in the console is
1
2
3
4
...
1312
1313
1314
java.sql.SQLException: [Microsoft][ODBC Driver Manager] Invalid string or buffer length
at sun.jdbc.odbc.JdbcOdbc.createSQLException(Unknown Source)
at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source)
at sun.jdbc.odbc.JdbcOdbc.SQLGetDataString(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcResultSet.getDataString(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcResultSet.getString(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcResultSet.getString(Unknown Source)
the line that generated the error is:
System.out.println(result.getInt(1));
Since i am getting a result out of it, I don't think it's a connection error or a driver one. I looked at the table and I don't seem to have anything wrong with the row 1315, i tried deleting it and nothing. Btw the table used has 2376 rows.
I have tried with another table with a different length and I also get the error after 417 rows.
Just in case it helps I am on windows 7, 64 bit, the tables are dBASE IV.
Thx in advance!
Another idea still. How about selecting 1,314 records from the table, but with a different range (for example, rows 1,000 -> 2,313)? I am wondering if the error still occur.

Jasper Reports: Error executing SQL statement (ORA-00942): Table or view does not exist

I have a report called Analysis which is populated by this simple query:
SELECT * FROM TB_ANL analysis WHERE analysis.CD_ANL = $P{FILTER}
Only one element will be selected (CD_ANL is unique).
When I edit this query in iReports (version 4.7), the Edit Query window actually shows the columns of the table (so it recognizes the table) and I successfully compile the report.
When I try to run it in my server, it accuses a ORA-00942 and says:
net.sf.jasperreports.engine.JRException: Error executing SQL statement for : AnalysisTemplate
at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.createDatasource(JRJdbcQueryExecuter.java:229)
at net.sf.jasperreports.engine.fill.JRFillDataset.createQueryDatasource(JRFillDataset.java:758)
at net.sf.jasperreports.engine.fill.JRFillDataset.initDatasource(JRFillDataset.java:623)
at net.sf.jasperreports.engine.fill.JRBaseFiller.setParameters(JRBaseFiller.java:1160)
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:802)
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:746)
at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:58)
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:417)
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:247)
at gov.chesf.leilaovenda.nucleo.negocio.analise.RelatorioGerador.gerarRelatorio(RelatorioGerador.java:57)
at gov.chesf.leilaovenda.web.analise.analise.action.Index.gerarAnalise(Index.java:725)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:452)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:291)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:254)
...
Caused by: java.sql.SQLException: ORA-00942: table or view does not exist
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:745)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:219)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:813)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1049)
at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:854)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1154)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3370)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3415)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.createDatasource(JRJdbcQueryExecuter.java:222)
... 85 more
So, basically, the problem is: I can view the table in iReports and in SQLDeveloper but I can't fill the report with it because the table or view "Does not exist". What is wrong with it? Is there any other reason why Jasper wouldn't be able to see the table?
Things I've done before posting here:
I Granted the user that Jasper is using.
The table exists, yes.
I checked the connection in Jasper. It's the same that Hibernate is using.
Problem solved.
Here was the problem:
It had nothing to do with the iReport itself, but with the schema being used by the user that the connection was logging in as.
The table TB_ANL should be referenced as OWNER.TB_ANL and not just as TB_ANL.
Possible solutions to this:
1) Update the schema to contain TB_ANL
2) Create a Synonym for OWNER.TB_ANL as TB_ANL so everytime you reference the table it will look in OWNER's schema.

Categories