Hi,
What kind of PostgreSQL binary type Hibernate supports as Blob:
bytea or
oid?
I would like to upload/download files and store the binary content in a database.
My simple POJO class:
Code:
public class Download {
private long id;
private Blob data;
public long getId() {
return id;
}
protected void setId(long id) {
this.id = id;
}
public Blob getData() {
return data;
}
public void setData(Blob data) {
this.data = data;
}
}
If I map the Blob field to
oid the following snipplet works fine:
Code:
...
tx=session.beginTransaction();
Download download=(Download)session.get(Download.class,new Long(9));
InputStream in=download.getData().getBinaryStream();
out=new BufferedOutputStream(new FileOutputStream("/somewhere/blob-test"));
int bytesRead;
byte[] buffer=new byte[512];
while ((bytesRead=in.read(buffer))!=-1) {
out.write(buffer,0,bytesRead);
}
out.flush();
tx.commit();
...
However when I try to upload a file to the database in a similar fashion with
Code:
Blob data=Hibernate.createBlob(...)
and
Code:
download.setData(data)
it fails with the exception below.
Trying to map the Blob field to
bytea will
reverse the results of the tests:
Using exactly the same code as with oid mapping:
Saving the file content works fine.
Retrieving the binary data fails with a JDBC exception saying
Bad Integer.
I wouldn't like to write database specific code neither for saving nor for reading the data (that's why Hibernate is wonderful!).
Is it possible to work around the problem?
(Used drivers: pg74.215.jdbc3.jar and pg80b1.308.jdbc3.jar)
Thank you in advance
Hibernate version: 3.0 beta1
Mapping documents:Code:
<hibernate-mapping>
<class name="Download" table="downloads">
<id name="id" column="id" type="long" unsaved-value="0">
<generator class="native"/>
</id>
<property name="data" type="blob">
<column name="data" sql-type="blob" not-null="true"/>
</property>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
tx=session.beginTransaction();
Download download=new Download();
File file=new File(args[0]);
Blob blob=Hibernate.createBlob(new BufferedInputStream(new FileInputStream(file)));
download.setData(blob);
session.save(upload);
session.flush();
tx.commit();
Full stack trace of any exception that occurs:
Jan 17, 2005 11:25:13 AM org.hibernate.util.JDBCExceptionReporter logExceptions
WARNING: SQL Error: 0, SQLState: null
Jan 17, 2005 11:25:13 AM org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: Batch entry 0 insert into downloads (data, id) values (<stream of 3249 bytes>, 17) was aborted. Call getNextException to see the cause.
Jan 17, 2005 11:25:13 AM org.hibernate.util.JDBCExceptionReporter logExceptions
WARNING: SQL Error: 0, SQLState: 42804
Jan 17, 2005 11:25:13 AM org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: ERROR: column "data" is of type oid but expression is of type bytea
Jan 17, 2005 11:25:13 AM org.hibernate.event.AbstractFlushingEventListener performExecutions
SEVERE: Could not synchronize database state with session
org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:59)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:155)
at org.hibernate.impl.ActionQueue.executeActions(ActionQueue.java:235)
at org.hibernate.impl.ActionQueue.executeActions(ActionQueue.java:137)
at org.hibernate.event.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:255)
at org.hibernate.event.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:814)
at UploadTest.main(UploadTest.java:45)
Caused by: java.sql.BatchUpdateException: Batch entry 0 insert into downloads ( data, id) values (<stream of 3249 bytes>, 17) was aborted. Call getNextException to see the cause.
at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2427)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1152)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:322)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2481)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:53)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:148)
... 6 more
Name and version of the database you are using: PostgreSQL 7.4.6
The generated SQL (show_sql=true):
Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into downloads (data, id) values ( ?, ?)
Debug level Hibernate log excerpt: