Spring roo - adding CLOB field - java

In my web application, I am saving some Text message in a COLUMN of a DB table(Oracle). Earlier the VARCHAR2 length(maximum length) is (500 BYTE). Now the maximum length is increased to 4000 characters. So I need to add a 'CLOB' field in my domain class.
Can anyone please clarify what are the steps need to be followed in order to create a CLOB field in my domain class. I also have CLOB cloumn in my DB.
(What is the command/syntax to start with?)

Adding CLOB at database
and adding the below code in the domain class is the solution.
#Lob
private String message;

If you need to create a CLOB field named message then you would run the following command on the Roo Shell:
field string --fieldName message --lob true

Related

How to get an entity-related object correctly

I have approximately the following entity:
public class Article {
private String name;
private Long fileId;
}
As you can see, it has a field fileld that contains the id of the associated file, which is also an entity. However, the file does not know anything about the Article, so the only thing that connects them is the fileId field in the Article. Therefore, they must be explicitly linked so as not to get lost. Now to get a linked file, I have to make a separate query to the database for each Article. That is, if I want to get a list of 10 Articles, I need to make a request to the database 10 times and get the file by its id. This looks very inefficient. How can this be done better? I use jooq, so I can't use JPA, so I can't substitute a file object instead of the fileId field. Any ideas?
I'm going to make an assumption that your underlying tables are something like this:
create table file (
id bigint primary key
content blob
);
create table article (
name text,
file_id bigint references file
);
In case of which you can fetch all 10 files into memory using a single query like this:
Result<?> result =
ctx.select()
.from(ARTICLE)
.join(FILE).on(ARTICLE.FILE_ID.eq(FILE.ID))
.fetch();

convert byte array to java.sql.Clob

Is there any way to convert a byte array into java.sql.Clob ?
I am having this type of issue...
getHibernateTemplate().save(object)
Where object is having a field private Clob docData; and the similar is mapped into oracle table as CLOB
This docData clob is getting formed from somewhere in my java code like Hibernate.createClob(someString)
I tried to save it with type="clob" but getting cann't cast com.sun.proxy$Proxy124 to oracle.sql.CLOB. I have tried many ways to remove this Proxy but finally failed.
So I have decided to go like byte[] data = IOUtils.toByteArray(docData.getCharacterStream()); / byte[] data = IOUtils.toByteArray(docData.getAsciiStream()) and saving it as type="binary" but I am getting Caused by: java.sql.BatchUpdateException: ORA-01461: can bind a LONG value only for insert into a LONG column.
So now I want to create as a Clob from byte[].
Any help welcome.
Note earlier I was using Hibernate 3.3 and it was working fine without any such byte array conversion and etc...now I have upgraded to Hibernate 3.6.10 and getting this issue.
I'm using this method to create Blobs:
org.hibernate.engine.jdbc.NonContextualLobCreator.NonContextualLobCreator.INSTANCE.createBlob( buffer )
where buffer is an array of bytes.
There are 2 similar methods for creating CLOBs:
NonContextualLobCreator.INSTANCE.createClob( reader, length )
NonContextualLobCreator.INSTANCE.createClob( string )
Pick the one that fits better with your data.
Your error message says
cann't cast com.sun.proxy$Proxy124 to oracle.sql.CLOB
In the rest of your text you are referring to java.sql.Clob Check your imports, you might be using the clob from the oracle.sql package instead of the java.sql package somewhere.
Well, issue is resolved. I kept the java data type as 'Clob' only and made the hibernate mapping like type="string". Issue got resolved since my digital sign data does not contain more than 2 MB (that java string max supports).

Derby "A truncation error was encountered trying to shrink CLOB '<stream-value>' to length 255"

I have a column definition in my JPA entity.
#Lob
String message;
I have following error when I try to persist my entity with some message.
Caused by: java.sql.SQLException: Java exception: 'A truncation error was encountered trying to shrink CLOB '' to length 255.: org.apache.derby.iapi.services.io.DerbyIOException'.
Caused by: org.apache.derby.iapi.services.io.DerbyIOException: A truncation error was encountered trying to shrink CLOB '' to length 255.
I'm using Hibernate 4.2.15.Final with Apache Derby 10.10.2 and schema generation during testing. It looks like the length of the column is limited to 255. How to overcome this error?
The Derby dialect in Hibernate generates column definition with limited legth:
message clob(255)
You may want to override this behaviour and set your own length or leave default length. You may use
#Column(columnDefinition="clob")
#Lob
String message;
Remember that in derby
A CLOB without a specified length is defaulted to two gigabytes (2,147,483,647)
This is regarded as a bug in Hibernate https://hibernate.atlassian.net/browse/HHH-7264 and https://hibernate.atlassian.net/browse/HHH-1501 but it's not going to be fixed as it seems.
Hibernate does not take into account the length/scale/precision nor
the dialect when determining the Hibernate Type to use for a property
which omitted specifying one. What it does is to basically choose a
default based solely on the Java type
The base class of all Derby Dialects (DB2Dialect) does this:
registerColumnType( Types.CLOB, "clob($l)" );
You can hook declare a Hibernate DialectResolver which does something like:
private class DerbyTenSevenDialectWithClob extends DerbyTenSevenDialect {
public DerbyTenSevenDialectWithClob() {
super();
registerColumnType( Types.CLOB, "clob" );
}
}
I just verified that using Hibernate 5.3.7 and Derby 10.12.1.1
I had the same problem and here is my solution for hibernate-core-4.2.7 and Derby:
If you create a string columns they will become VARCHAR(255)
#Column()
private String userName;
BUT you can increase the length, for example to 1000 characters by doing :
#Column(length = 1000)
private String description;
PS: I had to drop/delete my old table to force create a new with the correct size, also have a look inside the #Column interface there is some useful stuff there like unique, ullable, updatable

com.ibm.db2.jcc.am.SqlException: [jcc][10120][11936][4.14.88] Invalid operation: Lob is closed. ERRORCODE=-4470, SQLSTATE=null

In our application we are having a simple POJO class that has a Clob attribute within it.
I am having issue in getting the String representation of that Clob entity.
Say I have already queried and cached the result in the POJO object, now I am trying to get the String value of the Clob as below.
int aLength = (int)myPojo.getClobField().length();
String aStringValue = myPojo.getClobField().getSubString(1L, aLength);
But the above execution gives me the error,
com.ibm.db2.jcc.am.SqlException: [jcc][10120][11936][4.14.88] Invalid operation: Lob is closed. ERRORCODE=-4470, SQLSTATE=null
Am I missing something?
This issue can be solved by adding progressiveStreaming=2; argument to the connection url
The fully specified Connection URL is to be given as below:
jdbc:db2://localhost:50000/SAMPLE:progressiveStreaming=2;
In case you have exception on that parameter add the following to it or add any one or combinations of these parameters to fix it:
jdbc:db2://localhost:50000/SAMPLE:driverType=4;fullyMaterializeLobData=true;fullyMaterializeInputStreams=true;progressiveStreaming=2;progresssiveLocators=2;
It is preferred to use db2jcc4.jar
The Clob Java object is not a copy of the CLOB value stored in the database. It is a locator (pointer), which becomes invalid after the result set is closed. You'll need to copy CLOB contents while processing the result set.
For hibernate users , when mapping to a database Lob type (BLOB or CLOB) the field should be annotated #Lob and no need to keep the copy , you can directely convert it in to character array like
(java.sql.Clob)payload.field1 bodyText = clobTest.getCharacterStream()
targetString = org.apache.commons.io.IOUtils.toString(bodyText)
int length=targetString.length();
payload.PAYLOADHEADERS=targetString
return payload
Make sure you have added progressiveStreaming=2; in your data-source configuration properties.

Spring 3 MVC + MySQL: cannot store € character

I have Spring 3 MVC set up with Hibernate and MySQL 5. In a web form, I enter a single character into a field, € (i.e. just the one character). When I then attempt to save the data, I get the following exception:
java.sql.BatchUpdateException: Data truncation: Data truncated for column 'name' at row 1
'name' is a String on my model object. The 'name' column is of datatype VARCHAR(80) in MySQL. I have also tried entering a € into a TEXT column, with the same result.
I have configured a CharacterEncodingFilter for my webapp and my DB connection string looks like this:
jdbc:mysql://localhost/baseApp?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8
Any ideas what the problem might be?
Update:
I don't think MySQL has anything to do with this issue. I have intercepted the HTTP POST before the properties of my model object are set and the € is properly encoded as %80. When I interrogate the properties of my model object, however, €'s are simply ?'s.
Any thoughts?
Are you sure the MySQL database suports UTF-8? I think the default install settings uses latin1. You also need to make sure that the 'default-character-set' for [mysql] and [mysqld] in the my.ini configuration file is set to 'utf8'. Furthermore make sure the table was built with UTF-8 settings.

Categories

Resources