UTF-8 from Hibernate

2019-07-08 14:55发布

问题:

I have a problem when I retrieve information from a query from my MySql database it comes like this:

Je bâtirai 

There is a mistake with UTF-8 charset and Hibernate or with MySql.

How can I solve this please?

This my Hibernate setup:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/church</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>

        <property name="hibernate.connection.CharSet">utf8</property>
        <property name="hibernate.connection.characterEncoding">utf8</property>
        <property name="hibernate.connection.useUnicode">true</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>
        <!-- SQL dialect -->
        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>
        <!-- Disable the second-level cache -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->
        <!-- créer la BD -->
        <!-- property name="hbm2ddl.auto">create</property -->
        <!-- Met la BD existante à jour -->
        <!-- property name="hbm2ddl.auto">update</property -->
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!-- Mapping des classes persistantes -->

        <mapping class="com.church.metier.User" />
        <mapping class="com.church.metier.Comment" />
        <mapping class="com.church.metier.Text" />
        <mapping class="com.church.metier.MessageText" />
        <mapping class="com.church.metier.MessageVideo" />
        <mapping class="com.church.metier.News" />
        <mapping class="com.church.metier.VerseMonth" />
        <mapping package="com.church.metier" />


    </session-factory>
</hibernate-configuration>

When I retrieve:

System.out.println(VerseMonthDAO.retrieveVersetMonth());

My DAO:

package com.church.DAO;

import com.church.metier.VerseMonth;

import java.util.Locale;

import org.hibernate.Session;
import org.springframework.cglib.core.Local;
import org.springframework.context.i18n.LocaleContextHolder;

import com.church.util.HibernateUtil;

public class VerseMonthDAO {

    public static void savaOrUpdate(VerseMonth verse) {
        Session hibernateSession = HibernateUtil.getSession();
        org.hibernate.Transaction transc = null;

        try {
            transc = hibernateSession.beginTransaction();
            hibernateSession.saveOrUpdate(verse);
            transc.commit();
        } catch(Exception e) {
            if (transc != null) {
                transc.rollback();
            }
            e.printStackTrace();
        } finally {
            hibernateSession.close();
        }
    }

    public static String retrieveVersetMonth() {
        Locale locale = LocaleContextHolder.getLocale();
        String language = locale.getLanguage();

        if (language.equals("en")) {
            language = "textEn";
        } else if (language.equals("in")) {
            language = "textIn";
        } else {
            language = "textFr";
        }

        Session hibernateSession = HibernateUtil.getSession();
        org.hibernate.Transaction transc = null;
        String verse = null;
        Long count;

        try {
            transc = hibernateSession.beginTransaction();
            count = ((Long) hibernateSession.createQuery("select count(*) from VerseMonth").uniqueResult());

            verse = (String) hibernateSession.createQuery
                    ("SELECT "+ language +" FROM VerseMonth verse WHERE verse.verseId = '" + count.intValue() + "'")
                    .uniqueResult();

            transc.commit();
        } catch(Exception e) {
            if (transc!=null) {
                transc.rollback();
            }
            e.printStackTrace();
        } finally {
            hibernateSession.close();
        }

        return verse;
    }

    public static String retrieveSourceMonth() {
        Locale locale = LocaleContextHolder.getLocale();
        String language = locale.getLanguage();

        if (language.equals("en")) {
            language = "sourceEn";
        } else if (language.equals("in")) {
            language = "sourceIn";
        } else {
            language = "sourceFr";
        }

        Session hibernateSession = HibernateUtil.getSession();
        org.hibernate.Transaction transc = null;
        String source = null;
        Long count;

        try {
            transc = hibernateSession.beginTransaction();
            count = ((Long) hibernateSession.createQuery("select count(*) from VerseMonth").uniqueResult());

            source = (String) hibernateSession.createQuery
                    ("SELECT "+ language +" FROM VerseMonth verse WHERE verse.verseId = '" + count.intValue() + "'")
                    .uniqueResult();

            transc.commit();
        } catch(Exception e) {
            if (transc!=null) {
                transc.rollback();
            }
            e.printStackTrace();
        } finally {
            hibernateSession.close();
        }

        return source;
    }
}

my databases:

+---------+----------------+----------------+----------------+-------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| verseId | SOURCEEN       | SOURCEFR       | SOURCEIN       | TEXTEN                                                                                                | TEXTFR                                                                                              | TEXTIN                                                                                              |
+---------+----------------+----------------+----------------+-------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
|       1 | Je bâtirai    | Je bâtirai    | Je bâtirai    | Je bâtirai                                                                                           | Je bâtirai                                                                                         | Je bâtirai                                                                                         |
+---------+----------------+----------------+----------------+-------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+

thanks for your answers

回答1:

I find the answer After configure Hibernate with these parameter:

<property name="hibernate.connection.CharSet">utf8</property>
<property name="hibernate.connection.characterEncoding">utf8</property>
<property name="hibernate.connection.useUnicode">true</property>

We must also configure Spring to UTF-8 with these parameter in the web.xml:

<filter>
    <filter-name>SetCharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>SetCharacterEncodingFilter</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>

and it works ! Thanks everybody



回答2:

Make sure your Mysql is UTF-8 encode :

show variables like 'collation_%';

The result should be:

+----------------------+-----------------+
| Variable_name        | Value           |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
| collation_database   | utf8_general_ci |
| collation_server     | utf8_general_ci |
+----------------------+-----------------+

Then you need make sure your database is UTF-8 encode:

SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA S WHERE schema_name = 'your_database_name';

The result should be:

+-------------------------------+-------------------------+
|   DEFAULT_CHARACTER_SET_NAME  | DEFAULT_COLLATION_NAME  |  
+-------------------------------+-------------------------+
|   utf8                        |  utf8_general_ci        |
+-------------------------------+-------------------------+


回答3:

Mojibake really sounds like the character set during insertion was latin1, not utf8.

Your output implies that the character set when fetching was correctly utf8.