H2 Database Backup Restore Sequence Already Exists Exception - java

I have an application that uses an embedded H2 database. I want to implement a backup and restore feature. I can successfully backup my data, but I get a hurdle when I try to restore it. This is how i'm backing it up:
String DBQ = "SCRIPT TO ?";
PreparedStatement myStatement = connection.prepareStatement(DBQ);
myStatement.setString(1, backupFile.getAbsolutePath());
myStatement.executeQuery();
I get my backup file generated just fine with the data. I can't seem to restore it however. This is how I try to restore it:
String DBQ = "RUNSCRIPT FROM ?";
PreparedStatement preparedStatement = connection.prepareStatement(DBQ);
preparedStatement.setString(1,unencryptedFile.getAbsolutePath());
preparedStatement.executeUpdate();
I get a org.h2.jdbc.JdbcSQLSyntaxErrorException: Sequence already exists. I've looked around and pretty much the only thing I could find on it was from 2013, with no answer Backup and Restore h2 and I'm sure my database isn't corrupted. I can't seem to find any documentation to help me resolve this too. How can I resolve this?

Here is an whole example how to backup+restore:
https://gist.github.com/cwdesautels/11188409

Related

Using resultset data after closing the connection

I'm trying to write a small code snippet where I need to get some data from a database and then process the result in some other java file. I tried writing a program and the execution for the same was failing with error "Cannot access resultset as the connection was already closed".
Is there any way can we store the result fetched from database some where (Ex.some arraylist) and use it for computation after closing the connection? If yes, can someone please explain it with example?
Slightly handicapped since I'm new to it.
Class A {
public Map<String, Object> loadDat(int acc,Map<String,Object> result)
throws Exception {
Class.forName("com.teradata.jdbc.TeraDriver");
Connection conn = DriverManager.getConnection(connectionString, user, password);
query = "select * from mytable where id="+acc;
PreparedStatement stmt = conn.prepareStatement(query);
ResultSet rs=stmt.executeQuery();
result.put(" Result", rs) ;
return result;
}
}
In general,
don't code JDBC database access by hand.
Libraries already exist that do all the low level JDBC handling now and
they do it correctly.
You will never do it better than an one of the mature,
open source projects already do it.
Instead,
learn and use something like MyBatis.
If you use Spring,
here is a link to the Mybatis-Spring project.
MyBatis conceals all of the data conversion and JDBC junk.
Instead, you define your query in a simple XML file and receive a List
as the result of a query.
Just to add to #DwB's answer that is correct.
You can 1) retrieve all rows from your query into a Java List, 2) then close the connection, and 3) then use the Java List in another class (for further processing).
If you close the connection after retrieving only part of the result set, you'll lose the rest of it and will receive the error you mention. Don't do it this way.

Why do I recover a deleted record with UCanAccess?

I have been using UCanAccess to use Access databases my problem is when i want to delete a recor this returns automatically.
For example if i have:
Table Names
Id Name
1 Jessy
2 Abraham
String deleteQuery = "DELETE From Names where Id =?";
PreparedStatement pstm = con.getConnection().prepareStatement(deleteQuery);
pstm.setInt(1, 1); // "id" is type numeric
pstm.executeUpdate();
pstm.close();
it will works And then if i open the database the recor will be there!
that's my problem. (i hide the connection code but i have it)
Try to use compact feature provided by Access. On the Tools menu, point to Database Utilities, and then click Compact and Repair Database. This might help.
Do you do the commit after? If not and autocommit=false, just do it.
I found the problem, I was using data type OLE to save images simple sentences doesn't works so the way to delete a row with OLE field is creating Database and Table objects from java. It works.

Will ResultSet be updated with the underlying database?

Before I explain my problem I would like to say that I know the basics of JDBC but not really used to it.
I am using an updatable result set to hold data from 2 different tables, as in the following sample code:
searchQry = "SELECT ct.CustomerName, ct.Email, ct.PhoneNo, ot.ItemName
FROM CUSTOMER_TABLE ct JOIN ORDER_Table ot
ON ct.OrderID = ot.OrderID";
prestmt = dbcon.prepareStatement(searchQry, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
uprs = prestmt.executeQuery();
uprs.updateLong("ut.PhoneNo", 7240987456L);
uprs.updateString("otItemName", "GTA5");
uprs.updateRow();
I would like to know if I will update the database from somewhere else (not using the same result set object) while the result set, upsr, connected to the database, whether uprs will get updated with it or it will throw an error or it will go with the old data itself. Sorry if it a newbie question but I can't really test that on my DB without knowing the outcomes and safe measures.
Please, suggest me if there is any better way to update the underlining db along with the data in the ResultSet without having any transaction issues when changing from different places.
Using:
Oracle Database for JDBC connection.

How to "package" an SQL database

I am looking for a way to save an SQL database and then reference it by means other than localhost which would not work because it is being used on other computers.
I realize that my terminology may not be correct in asking for a means to "package" an SQL database however I am not very sure how to put my desire such a concise title.
I have a database that I created through mySQL here: http://gyazo.com/fcac155a60c0d2587442c3e4807ef98a
I can access this database with no problems through the following code...
try
{
//Get connection
Connection myConn = DriverManager.getConnection("jdbc:mysql://localhost:3306/term_database","root", "_cA\"#8X(XHm+++E");
//**********
//Connection myConn = DriverManager.getConnection("jdbc:mysql:translationDatabase","root", "_cA\"#8X(XHm+++E");
//**********
//create statement
Statement myStmt = myConn.createStatement();
//execute sql query
ResultSet myRs = myStmt.executeQuery("select * from terms WHERE idNumber=" +termNumber);
//process result set
while(myRs.next()){
term= (myRs.getString(language));
}
}
catch (Exception exc)
{
exc.printStackTrace();
}
However, I assume that my users will be on different computers and so a "//localhost" reference will not work. They do not have access to the internet either. So I aim to include the database in my program's files to be downloaded with the software or to include it in the jar. I was not able to find any means to do that online. The code I surrounded with *'s was an attempt to reference translationDatabase.sql which I saved through the program mySQL into my software's directory but it did not work as shown here: http://gyazo.com/e9d4339435dedecab4e7ad960e9b13b6
To recap: I am looking for a way to save an SQL database and then reference it by means other than localhost which would not work because it is being used on other computers.
The idiomatic terminology is "embedded" or "serverless" database.
There are several pure-java solutions. There is also the popular SQLite, which you can manipulate via its command line client, or via a third-party JDBC driver (example 1, example 2)
Any of the above solutions will require that you convert your existing MySQL database to the target system..
Alternatively, you may consider bundling your application with MySQL server (possibly with an automated installation process, so that installation is invisible to the end-user).

Java Statement.executeUpdate(sql) not working when executeQuery(sql) works

I have a wierd behavior in a Java application.
It issues simple queries and modifications to a remote MySQL database. I found that queries, run by executeQuery() work just fine, but inserts or delete to the database run through executeUpdate() will fail.
Ruling out the first thing that comes to mind: the user the app connects with has correct privilledges set up, as the same INSERT run from the same machine, but in DBeaver, will produce the desired modification.
Some code:
Connection creation
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(url, user, pass);
Problematic part:
Statement parentIdStatement = connection.createStatement();
String parentQuery = String.format(ProcessDAO.GET_PARENT_ID, parentName);
if (DEBUG_SQL) {
plugin.getLogger().log(Level.INFO, parentQuery);
}
ResultSet result = parentIdStatement.executeQuery(parentQuery);
result.first();
parentId = result.getInt(1);
if (DEBUG_SQL) {
plugin.getLogger().log(Level.INFO, parentId.toString()); // works, expected value
}
Statement createContainerStatement = connection.createStatement();
String containerQuery = String.format(ContainerDAO.CREATE_CONTAINER, parentId, myName);
if (DEBUG_SQL) {
plugin.getLogger().log(Level.INFO, containerQuery); // works when issued through DBeaver
}
createContainerStatement.executeUpdate(containerQuery); // does nothing
"DAOs":
ProcessDAO.GET_PARENT_ID = "SELECT id FROM mon_process WHERE proc_name = '%1$s'";
ContainerDAO.CREATE_CONTAINER = "INSERT INTO mon_container (cont_name, proc_id, cont_expiry, cont_size) VALUES ('%2$s', %1$d, CURRENT_TIMESTAMP(), NULL)";
I suspect this might have to do with my usage of Statement and Connection.
This being a lightweight lightly-used app, I went to simplicity, so no framework, and no specific isntructions regarding transactions or commits.
So, in the end, this code was just fine. It worked today.
To answer the question: where to look first in a similar case (SELECT works but UPDATE / INSERT / DELETE does not)
If rights are not the problem, then there is probably a lock on the table you try to modify. In my case, someone left with an uncommited transaction open.
Proper SQL exceptions logging (which was suboptimal in my case) will help you figure it out.

Categories