Subject | Batch Update and Blobs |
---|---|
Author | Michael Kaegi |
Post date | 2007-03-01T11:54:11Z |
Hi Jaybird Developers
I'm using Hibernate 3.2 + Jaybird 2.1.1 + Firebird 1.5
In hibernate I try to save a bean that contains a collection of other
beans that contains a collection of blobs...
E.g..
Foo
Bar
Blob
Blob
Bar
Blob
Blob
session.save(foo);
... but following exception is thrown:
org.hibernate.exception.GenericJDBCException: could not insert:
[ch.bw.worknavigator.hibernatetest.FooBlob]
at
org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at
org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
at
org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2263)
at
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2656)
at
org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:52)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at
org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at
org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
at
org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at
org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at
ch.bw.worknavigator.hibernatetest.Test.testFooBlobs(Test.java:56)
at ch.bw.worknavigator.hibernatetest.Test.main(Test.java:32)
Caused by: org.firebirdsql.jdbc.FBDriverNotCapableException: Not yet
implemented.
at
org.firebirdsql.jdbc.field.FBBlobField.getCachedObject(FBBlobField.java:178)
at
org.firebirdsql.jdbc.AbstractPreparedStatement.addBatch(AbstractPreparedStatement.java:767)
at
org.hibernate.jdbc.BatchingBatcher.addToBatch(BatchingBatcher.java:31)
at
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2243)
... 10 more
I have written a small example(testcase) in jdbc to reproduce the problem
without hibernate:
The example inserts two records in a batch update...
import java.io.ByteArrayInputStream;
import java.sql.*;
public class Test {
public static void main(String[] args) throws Exception {
// get driver...
String databaseURL =
"jdbc:firebirdsql:127.0.0.1:d:/test.fdb?sql_dialect=3";
String user = "sysdba";
String password = "masterkey";
String driverName = "org.firebirdsql.jdbc.FBDriver";
Driver d = null;
Connection c = null;
Statement s = null;
PreparedStatement ps = null;
try {
Class.forName(driverName);
} catch (java.lang.ClassNotFoundException e) {
System.out.println("Firebird JCA-JDBC driver not found in
class path");
System.out.println(e.getMessage());
return;
}
try {
d = DriverManager.getDriver(databaseURL);
System.out.println("Firebird JCA-JDBC driver version " +
d.getMajorVersion() + "." + d.getMinorVersion() + " registered with driver
manager.");
} catch (SQLException e) {
System.out.println("Unable to find Firebird JCA-JDBC driver
among the registered drivers.");
showSQLException(e);
return;
}
// get connection...
try {
c = DriverManager.getConnection(databaseURL, user, password);
System.out.println("Connection established.");
} catch (SQLException e) {
e.printStackTrace();
System.out.println("Unable to establish a connection through
the driver manager.");
showSQLException(e);
return;
}
// get driver info...
try {
java.sql.DatabaseMetaData dbMetaData = c.getMetaData ();
// Ok, let's query a driver/database capability
if (dbMetaData.supportsBatchUpdates())
System.out.println ("Batch updates are supported.");
else
System.out.println ("Batch updates are not supported.");
}
catch (java.sql.SQLException e) {
System.out.println ("Unable to extract database meta data.");
showSQLException (e);
}
// create table...
c.setAutoCommit(true);
s = c.createStatement();
try {
System.out.println("DROP TABLE BLOBTEST");
s.executeUpdate("DROP TABLE BLOBTEST");
} catch (java.sql.SQLException e) {
}
System.out.println("CREATE TABLE BLOBTEST(ID NUMERIC(18,0) NOT
NULL PRIMARY KEY, NAME VARCHAR(10), DATA BLOB SUB_TYPE 0 SEGMENT SIZE
80)");
s.executeUpdate("CREATE TABLE BLOBTEST(ID NUMERIC(18,0) NOT NULL
PRIMARY KEY, NAME VARCHAR(10), DATA BLOB SUB_TYPE 0 SEGMENT SIZE 80)");
c.setAutoCommit(false);
// -->>
// -->>
// insert two records in a batch update...
try {
// record 1...
byte[] bytes1 = new byte[]{65, 65, 65, 65};
ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
System.out.println("INSERT INTO BLOBTEST ( ID, NAME, DATA )
VALUES ( ?, ?, ?)");
ps = c.prepareStatement("INSERT INTO BLOBTEST ( ID, NAME, DATA
) VALUES ( ?, ?, ?)");
ps.setLong(1, 1);
ps.setString(2, "One");
ps.setBinaryStream(3, bais, bytes1.length);
ps.addBatch(); // => throws
org.firebirdsql.jdbc.FBDriverNotCapableException: Not yet implemented.
<------------------
// record 2...
// byte[] bytes2 = new byte[]{66, 66, 66, 66};
//
// bais = new ByteArrayInputStream(bytes2);
//
// System.out.println("INSERT INTO BLOBTEST ( ID, NAME, DATA )
VALUES ( ?, ?, ?)");
// ps.setLong(1, 2);
// ps.setString(2, "Two");
// ps.setBinaryStream(3, bais, bytes2.length);
// ps.addBatch();
ps.executeBatch();
c.commit();
// <<--
// <<--
} catch (Exception ex) {
ex.printStackTrace();
try {
if (c != null)
c.rollback();
} catch (SQLException e) {
showSQLException(e);
}
} finally {
System.out.println("Closing database resources.");
try {
if (s != null)
s.close();
} catch (SQLException e) {
showSQLException(e);
}
try {
if (ps != null)
ps.close();
} catch (SQLException e) {
showSQLException(e);
}
try {
if (c != null)
c.close();
} catch (SQLException e) {
showSQLException(e);
}
}
}
// Display an SQLException which has occured in this application.
private static void showSQLException(SQLException e) {
java.sql.SQLException next = e;
while (next != null) {
System.out.println(next.getMessage());
System.out.println("Error Code: " + next.getErrorCode());
System.out.println("SQL State: " + next.getSQLState());
next = next.getNextException();
}
}
}
If I execute it...
org.firebirdsql.jdbc.FBDriverNotCapableException: Not yet implemented.
at
org.firebirdsql.jdbc.field.FBBlobField.getCachedObject(FBBlobField.java:178)
at
org.firebirdsql.jdbc.AbstractPreparedStatement.addBatch(AbstractPreparedStatement.java:767)
at Test.main(Test.java:101)
Note: If I just insert the id and name (no Blob) it works...
I read in the Jaybird FAQ that the driver dosn't support Batch Updates.
Can somebody tell me if you plan to implement or allready working on...
java.sql.PreparedStatement:
addBatch(String sql)
clearBatch()
executeBatch()
...and if so when (in which release) it will be available?
Thanx
Michi
[Non-text portions of this message have been removed]
I'm using Hibernate 3.2 + Jaybird 2.1.1 + Firebird 1.5
In hibernate I try to save a bean that contains a collection of other
beans that contains a collection of blobs...
E.g..
Foo
Bar
Blob
Blob
Bar
Blob
Blob
session.save(foo);
... but following exception is thrown:
org.hibernate.exception.GenericJDBCException: could not insert:
[ch.bw.worknavigator.hibernatetest.FooBlob]
at
org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at
org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
at
org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2263)
at
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2656)
at
org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:52)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at
org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at
org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
at
org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at
org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at
ch.bw.worknavigator.hibernatetest.Test.testFooBlobs(Test.java:56)
at ch.bw.worknavigator.hibernatetest.Test.main(Test.java:32)
Caused by: org.firebirdsql.jdbc.FBDriverNotCapableException: Not yet
implemented.
at
org.firebirdsql.jdbc.field.FBBlobField.getCachedObject(FBBlobField.java:178)
at
org.firebirdsql.jdbc.AbstractPreparedStatement.addBatch(AbstractPreparedStatement.java:767)
at
org.hibernate.jdbc.BatchingBatcher.addToBatch(BatchingBatcher.java:31)
at
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2243)
... 10 more
I have written a small example(testcase) in jdbc to reproduce the problem
without hibernate:
The example inserts two records in a batch update...
import java.io.ByteArrayInputStream;
import java.sql.*;
public class Test {
public static void main(String[] args) throws Exception {
// get driver...
String databaseURL =
"jdbc:firebirdsql:127.0.0.1:d:/test.fdb?sql_dialect=3";
String user = "sysdba";
String password = "masterkey";
String driverName = "org.firebirdsql.jdbc.FBDriver";
Driver d = null;
Connection c = null;
Statement s = null;
PreparedStatement ps = null;
try {
Class.forName(driverName);
} catch (java.lang.ClassNotFoundException e) {
System.out.println("Firebird JCA-JDBC driver not found in
class path");
System.out.println(e.getMessage());
return;
}
try {
d = DriverManager.getDriver(databaseURL);
System.out.println("Firebird JCA-JDBC driver version " +
d.getMajorVersion() + "." + d.getMinorVersion() + " registered with driver
manager.");
} catch (SQLException e) {
System.out.println("Unable to find Firebird JCA-JDBC driver
among the registered drivers.");
showSQLException(e);
return;
}
// get connection...
try {
c = DriverManager.getConnection(databaseURL, user, password);
System.out.println("Connection established.");
} catch (SQLException e) {
e.printStackTrace();
System.out.println("Unable to establish a connection through
the driver manager.");
showSQLException(e);
return;
}
// get driver info...
try {
java.sql.DatabaseMetaData dbMetaData = c.getMetaData ();
// Ok, let's query a driver/database capability
if (dbMetaData.supportsBatchUpdates())
System.out.println ("Batch updates are supported.");
else
System.out.println ("Batch updates are not supported.");
}
catch (java.sql.SQLException e) {
System.out.println ("Unable to extract database meta data.");
showSQLException (e);
}
// create table...
c.setAutoCommit(true);
s = c.createStatement();
try {
System.out.println("DROP TABLE BLOBTEST");
s.executeUpdate("DROP TABLE BLOBTEST");
} catch (java.sql.SQLException e) {
}
System.out.println("CREATE TABLE BLOBTEST(ID NUMERIC(18,0) NOT
NULL PRIMARY KEY, NAME VARCHAR(10), DATA BLOB SUB_TYPE 0 SEGMENT SIZE
80)");
s.executeUpdate("CREATE TABLE BLOBTEST(ID NUMERIC(18,0) NOT NULL
PRIMARY KEY, NAME VARCHAR(10), DATA BLOB SUB_TYPE 0 SEGMENT SIZE 80)");
c.setAutoCommit(false);
// -->>
// -->>
// insert two records in a batch update...
try {
// record 1...
byte[] bytes1 = new byte[]{65, 65, 65, 65};
ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
System.out.println("INSERT INTO BLOBTEST ( ID, NAME, DATA )
VALUES ( ?, ?, ?)");
ps = c.prepareStatement("INSERT INTO BLOBTEST ( ID, NAME, DATA
) VALUES ( ?, ?, ?)");
ps.setLong(1, 1);
ps.setString(2, "One");
ps.setBinaryStream(3, bais, bytes1.length);
ps.addBatch(); // => throws
org.firebirdsql.jdbc.FBDriverNotCapableException: Not yet implemented.
<------------------
// record 2...
// byte[] bytes2 = new byte[]{66, 66, 66, 66};
//
// bais = new ByteArrayInputStream(bytes2);
//
// System.out.println("INSERT INTO BLOBTEST ( ID, NAME, DATA )
VALUES ( ?, ?, ?)");
// ps.setLong(1, 2);
// ps.setString(2, "Two");
// ps.setBinaryStream(3, bais, bytes2.length);
// ps.addBatch();
ps.executeBatch();
c.commit();
// <<--
// <<--
} catch (Exception ex) {
ex.printStackTrace();
try {
if (c != null)
c.rollback();
} catch (SQLException e) {
showSQLException(e);
}
} finally {
System.out.println("Closing database resources.");
try {
if (s != null)
s.close();
} catch (SQLException e) {
showSQLException(e);
}
try {
if (ps != null)
ps.close();
} catch (SQLException e) {
showSQLException(e);
}
try {
if (c != null)
c.close();
} catch (SQLException e) {
showSQLException(e);
}
}
}
// Display an SQLException which has occured in this application.
private static void showSQLException(SQLException e) {
java.sql.SQLException next = e;
while (next != null) {
System.out.println(next.getMessage());
System.out.println("Error Code: " + next.getErrorCode());
System.out.println("SQL State: " + next.getSQLState());
next = next.getNextException();
}
}
}
If I execute it...
org.firebirdsql.jdbc.FBDriverNotCapableException: Not yet implemented.
at
org.firebirdsql.jdbc.field.FBBlobField.getCachedObject(FBBlobField.java:178)
at
org.firebirdsql.jdbc.AbstractPreparedStatement.addBatch(AbstractPreparedStatement.java:767)
at Test.main(Test.java:101)
Note: If I just insert the id and name (no Blob) it works...
I read in the Jaybird FAQ that the driver dosn't support Batch Updates.
Can somebody tell me if you plan to implement or allready working on...
java.sql.PreparedStatement:
addBatch(String sql)
clearBatch()
executeBatch()
...and if so when (in which release) it will be available?
Thanx
Michi
[Non-text portions of this message have been removed]