Error Saving and getting blob from database SQL oracle - java

I'm trying to save a CLOB into the database and recovering it, but I'm getting an SQLException:
Caused by: java.sql.SQLException: Lob read/write functions called while another read/write is in progress: getBytes()
at oracle.jdbc.driver.T4CConnection.getBytes(T4CConnection.java:2427)
at oracle.sql.BLOB.getBytes(BLOB.java:348)
at oracle.jdbc.driver.OracleBlobInputStream.needBytes(OracleBlobInputStream.java:181)
I figured that the problem is when I tried to get the CLOB, because it's still saving.
If the CLOB is small it works fine, but when the CLOB is a little bigger it fails.
Sorry about my english and thanks
EDIT:
The annotation is:
#Lob
#Column(nullable = false)
private String body;
The save method
emailRepository.save(email);

Setting the hibernate property
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
sorved the problem for me.
Setting the lobCreator for SessionFactory to NonContextualLobCreator is probably a better solution (not tried yet).
However I'm not sure what causes this error.

I encountered a similar problem in one of the projects, setting
updatable = false
fixed the issue for me.
Example:
#Lob
#Column(name = "CONTENT", updatable = false)
Blob content;
Hibernate somehow tries to re-save the content, even when it was not changed.

Related

How to get length of CLOB in Java/Hibernate

I am working with a table (Oracle), that has a CLOB column. And I am using Hibernate to query the table. Here is a quick look at the class that I am using to map the Oracle table:
#Entity
#Table(name="D2D_OPD_ORDERDELIVERY")
public class D2dOpdOrderDelivery implements Serializable {
// other column mappings omitted for brevity
#Column(name="POD_SIGNATURE_IMG", nullable=true)
#Lob
private Clob podSignatureImage;
I have successfully managed to run the Hibernate query, which returns a single row from the database:
// Create a Hibernate query (HQL)
Query query = session.createQuery("FROM D2dOpdOrderDelivery WHERE orderNumber = :orderNumber");
query.setParameter("orderNumber", orderNumber);
Elsewhere in my code, I perform a null check on my Clob - it is NOT null. Next, I try to get the length of my Clob. And this is where I run into a problem. I get the following error:
java.sql.SQLException: Closed Connection
oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:113)
oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:147)
oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:209)
oracle.sql.CLOB.getDBAccess(CLOB.java:1212)
oracle.sql.CLOB.length(CLOB.java:223)
Sorry, I just don't understand why I am getting this error. I have already run my query (all the other fields in the row are present). Why can't I get the length of my CLOB?
Can someone please point out where I have gone wrong?
Thank you.
OK, after posting this question, I went back and searched the Internet some more. I thought I had done a pretty good job of that before I posted my question - but that is another matter...
Anyway, I found a useful link here:
http://www.javavids.com/video/how-to-read-data-from-blob-using-jpa-hibernate.html
And the change I made to my code:
#Column(name="POD_SIGNATURE_IMG", nullable=true)
#Lob
#Basic(fetch=FetchType.LAZY)
private char[] podSignatureImage;
I was then able to call .length on my char[]
Hope this is helpful to someone else...

H2 Database simulate Oracle XMLtype - Hibernate

I have the following column in one of my hibernate entities:
#Lob
#Basic(fetch=FetchType.LAZY)
#ColumnTransformer(read = "to_clob(xmlContent)", write = "?")
#Column(name="XMLCONTENT", updatable = false, columnDefinition = "XMLType")
private String xmlContent;
However when I have hibernate.hbm2ddl.auto = create on hibernate it fails to create the particular table giving me the following error:
Unknown data type: "XMLTYPE"; SQL statement:
So basically I can't include this table/entity at all in tests with the H2 database. I need to have an XE at least installed.
Is there any workaround/solution to this, possibly another in memory database supports this?

using j2ee to load BLOB always gets null for BLOB attribute of entity bean

I want to load a BLOB from database using EJB.
Problem: The BLOB attribute is alsways null.
The blob attribute looks like this in the bean:
#Column(name = "REPORT_PARAMETER", length = 50000) // tried already: removing "length"
#Lob
#Basic(fetch = FetchType.EAGER) // tried already: uncomment, changing to "LAZY"
private byte[] reportParameters;
I load the bean like this:
TestCacheDataBE data= (TestCacheDataBE) em.find(TestCacheDataBE.class, cacheId);
The loading works, I can read all the other attributes fine. Only the BLOB attribute is always null.
There is data in the database. A SELECT shows me the BLOB column is not null.
select dbms_lob.getlength(report_parameter)
from T_REPORT_CACHE;
The above statement shows me, there is data in the BLOB column.
The data is saved using also the bean and entitymanager like this:
em.persist(data);
But the saving works fine!
So the only problem is loading the BLOB data from the database into the bean. Saving works, and loading all the other data works also.
I use weblogic 10, Java 1.5.
So we solved the problem. I'll document the solution here for others, because apparently, no one knew the answer.
It was a driver problem. We used the Weblogic driver:
<jdbc-driver-params>
<url>jdbc:bea:oracle://domain:1541</url>
<driver-name>weblogic.jdbc.oracle.OracleDriver</driver-name>
It works with Oracle driver:
<jdbc-driver-params>
<url>jdbc:oracle:thin:#domain:1542:abcd</url>
<driver-name>oracle.jdbc.driver.OracleDriver</driver-name>
Fun fact:
It used to work with the Weblogic driver (on Windows 7). But something changed and it did not work anymore (maybe a Windows update or an Oracle-database update changed something). Now it only works with the Oracle-driver. We deploy on a Linux server, there it still works with the Weblogic driver.

Clob to String using hibernate and Oracle

I am having difficulty while reading from oracle database using hibernate. The column is of clob type and mapped class property is of String type. The database is Oracle 11G. I have tried to update my driver as suggested by some posts, But it was of no use. The problem is that All other columns(which are not clob) are read properly and the column which is clob is returned null besides it has data. Thanks in advance.
The query is :
select id,about_us,other_details,periodicity,active,createts,updatets from Details where id = ?
This above the HQL query where about_us and other_details are clob type in database. The java entity contains it as type String.
Rahul
I tried many solutions as suggested in different posts, It includes:
1) Updating odbc jar.
2) Using #lob on the porperty in hibernate mapping/entity.
Both of the above solutions did not work for me, Rather I used the hibernate function str(clob_property) to read it, It worked for me and I could get the property read.
Regards
Rahul
Have you tried something like this?
#Lob #Column(name = "long_text")
private String longText;

JBoss6 JPA: Entity with #Lob results in GenericJDBCException

I have a simple EntityBean with a #Lob annotation. If I delete this annotation I get no errors on JBossAS 6.0.0.Final and MySQL5. But if I annotate it with #Lob (because mt contains about 100 to 5000 characters in my case) I get errors in my testing environment if I persist the entity.
without #Lob: mt is mapped to VARCHAR
with #Lob: mt is mapped to LONGTEXT (this is what I want, but I get errors)
This my entity:
#Entity
#Table(name = "Description")
public class Description implements Serializable
{
public static final long serialVersionUID=1;
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
#Lob
private String mt;
} // ... getter/setter
The error are here:
...
Caused by: org.hibernate.exception.GenericJDBCException: could not insert
[my.Description]
...
Caused by: java.sql.SQLException: Connection is not associated with a managed
connection.org.jboss.resource.adapter.jdbc.jdk6.WrappedConnectionJDK6#3e4dd
...
I really don't know why I get this (reproduceable) error. The environment seems to be ok, many other tests are passed and it even works without the #Lob annotation.
This question is related to JPA: how do I persist a String into a database field, type MYSQL Text, where the usage of #Lob for JPA/MySQL is the accepted answer.
Update 1 The error above is OS specific. On a W7 machine I have no problems with #Lob, with OSX Lion always the error. I will try to update MySQL and the driver.
Update 2 The proposed workaround by Kimi with #Column(columnDefinition = "longtext") works fine, even on OSX. In both cases MySQL creates the same column: LONGTEXT.
Update 3 I updated MySQL to mysql-5.5.17-osx10.6-x86_64 and the connector to mysql-connector-java-5.1.18. Still the same error.
There is no need to annotate a String property with #Lob. Just set the column length with #Column(length = 10000).
EDIT:
Moreover, you can always set the length to your database specific maximum value, as well as define the column type with the columndefinition setting to whichever suits your needs.
For example, if you're using MySQL 5.0.3 or later, the maximum amount of data that can be stored in each data type is as follows:
VARCHAR: 65,535 bytes (~64Kb, 21,844 UTF-8 encoded characters)
TEXT: 65,535 bytes (~64Kb, 21,844 UTF-8 encoded characters)
MEDIUMTEXT: 16,777,215 bytes (~16Mb, ~5.5 million UTF-8 encoded characters)
LONGTEXT: 4,294,967,295 bytes (~4GB, ~1.4 billion UTF-8 encoded characters).
As i understand it, #Lob just sets the column type and length depending on the underlying database.
Another way that worked for me is to update launch configuration of jBoss with
-Dhibernate.jdbc.use_streams_for_binary=true
I'm running jBoss6 with MySQL5

Categories