Hibernate varbinary colum encoding issue

We are using hibernate3.0  as the persistence layer and need to store a really long string in the back end. Since there is a limit if i user Varchar (no utf-8 encoding issues there), i tried using varbinary and set the length to 700. The problem with that is, in my entity, the column is represented by String. Inserting does not seem to be a problem, but while retrieving the string, hibernate screw up the encoding for e.g changes Moiré to Moir¿ .
Table has: ENGINE=InnoDB DEFAULT CHARSET=utf8;
Hibernate properties has:

  <prop key="hibernate.connection.useUnicode">true</prop>
  <prop key="hibernate.connection.characterEncoding">UTF-8</prop>
  <prop key="hibernate.connection.charSet">UTF-8</prop>

Open in new window


Entity :

@Column(name="content")
private String getContent(){....}

Open in new window

encoding.png
jusnileshAsked:
Who is Participating?
 
jusnileshConnect With a Mentor Author Commented:
Finally figure it out.
For those who are stuck with the same problem, here a clean solution.

step-1: Override org.hibernate.type.StringType
 
 public class ContentStringType extends org.hibernate.type.StringType {
 	
 	private static final long serialVersionUID = 1L;
 
 	public Object get(ResultSet rs, String name) throws SQLException {
 		String content=null;
 		try {
 			content= new String(rs.getBytes(name),"UTF-8");
 		} catch (UnsupportedEncodingException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
 			return content;
 	}
 	
}

Open in new window

step-2: Apply newly created type
 
   @Type(type="com.company.hibernate.entity.ContentStringType")
    @Column(name="content")
    public String getContent() {
        return this.content;
  }

Open in new window


3:
Make sure your db url has useUnicode=true &amp;characterEncoding=utf-8
0
 
jusnileshAuthor Commented:
So i tried updating the database settings

	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost/t1?useUnicode=true&characterEncoding=UTF-8" />
		<property name="username" value="root" />
		<property name="password" value="root" />
		<property name="initialSize" value="5" />
		<property name="maxActive" value="10" />
		<property name="maxIdle" value="2" />
		<property name="validationQuery" value="SELECT 1" />
		<property name="testOnBorrow" value="true" />
	</bean>	

Open in new window


Result:
The utf-8 representation of value that gets persisted is correct, however, hibernate still returns a corrupted value.
0
 
jusnileshAuthor Commented:
So it seems like Hibernate is the culprit. When i use native sql query, i get the correctly encoded value. However, when i tell the query to use my entity which has a String variable that gets populated with Varbinary on the column, hell breaks loose.

So i need a way to define an entity so that i can populate 2 variables with the same column, define one as byte[] and use that for reading and other as String for updating.

Any better ideas.

Please help !!
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
girionisCommented:
What happens if you define the column as CLOB?
0
 
jusnileshAuthor Commented:
Not sure if i want to use CLOB.
Here's one possible solution that works, not sure if it is the best though, but would definitely love to hear your opinion on it.

Added an extra attribute in my Hibernate entity

@Type(type="org.hibernate.type.BinaryType")
@Column(name="content",insertable=false,updatable=false )
private byte[] contentBin;
@Column(name="content")
private String content;

private String getContent(){
    	String content= null;
        try {
  			content= new String(this.contentBin,"UTF-8");  			
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return content;

}

Open in new window


DAO:

	public MyEntity getContent (String content){
		
		MyEntity f=  null;
			f = (MyEntity) getCloudSessionFactory()
				.getCurrentSession()
				.createQuery("from MyEntity m where m.content= ?" )
				.setBinary(0, content.getBytes())
				.uniqueResult();
		return f;
		
	}

Open in new window

0
 
jusnileshAuthor Commented:
clean, minimal changes required to existing codebase
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.