Solved

Hibernate varbinary colum encoding issue

Posted on 2013-05-17
6
575 Views
Last Modified: 2013-05-27
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
0
Comment
Question by:jusnilesh
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
6 Comments
 

Author Comment

by:jusnilesh
ID: 39175758
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
 

Author Comment

by:jusnilesh
ID: 39176271
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
 
LVL 35

Expert Comment

by:girionis
ID: 39180566
What happens if you define the column as CLOB?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:jusnilesh
ID: 39181688
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
 

Accepted Solution

by:
jusnilesh earned 0 total points
ID: 39187960
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
 

Author Closing Comment

by:jusnilesh
ID: 39198757
clean, minimal changes required to existing codebase
0

Featured Post

NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Why is this different from all of the other step by step guides?  Because I make a living as a DBA and not as a writer and I lived through this experience. Defining the name: When I talk to people they say different names on this subject stuff l…
Ever needed a SQL 2008 Database replicated/mirrored/log shipped on another server but you can't take the downtime inflicted by initial snapshot or disconnect while T-logs are restored or mirror applied? You can use SQL Server Initialize from Backup…
Via a live example, show how to set up a backup for SQL Server using a Maintenance Plan and how to schedule the job into SQL Server Agent.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

756 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question