【问题标题】:Hibernate/JPA import.sql utf8 characters corruptedHibernate/JPA import.sql utf8 字符损坏
【发布时间】:2012-01-23 00:25:21
【问题描述】:

我正在使用 import.sql 将我的开发数据写入数据库。我正在使用 MySQL Server 5.5,我的 persistence.xml 在这里:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="MobilHM" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>tr.com.stigma.db.entity.Doctor</class>
    <class>tr.com.stigma.db.entity.Patient</class>
    <class>tr.com.stigma.db.entity.Record</class>
    <class>tr.com.stigma.db.entity.User</class>
    <properties>
        <property name="hibernate.hbm2ddl.auto" value="create" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.format_sql" value="true" />
        <!-- Auto detect annotation model classes -->
        <property name="hibernate.archive.autodetection" value="class" />
        <!-- Datasource -->
        <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
        <property name="hibernate.connection.username" value="mobilhm" />
        <property name="hibernate.connection.password" value="mobilhm" />
        <property name="hibernate.connection.url" value="jdbc:mysql://localhost/mobilhm" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
    </properties>
</persistence-unit>

我的 import.sql 中的某些字符在 DB 中未正确显示。例如字符 ü 在 db 中变为 ü。 mysql 中的默认字符集是 utf-8,我正在创建类似

的表
CREATE TABLE doctor (doctorId int unsigned NOT NULL AUTO_INCREMENT, name varchar(45) NOT NULL, surname varchar(45) NOT NULL, PRIMARY KEY (doctorId)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

奇怪的是,如果我使用 Mysql 导入/导出管理器数据是正确的,但使用 hibernate.hbm2ddl.auto=create 会导致字符损坏。

我该如何解决这个问题?

编辑: 我也试过添加

<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding"
            value="UTF-8" />
<property name="hibernate.connection.charSet" value="UTF-8" />

到persistence.xml。但这没有帮助。

修复: 我最终解决了它。我正在使用 Tomcat,这不是休眠或 mysql 的损坏点。我已经使用 set JAVA_OPTS=-Dfile.encoding=UTF-8 命令启动它,我的问题就消失了。

问题的标题现在变得具有误导性。很抱歉。

【问题讨论】:

    标签: hibernate utf-8 character-encoding


    【解决方案1】:

    在为该文件创建阅读器时,Hibernate 直接使用new InputStreamReader(stream);,无需显式编码(假定/使用默认执行平台字符集编码)。

    也就是说,您的import.sql 文件必须采用默认的执行平台字符集编码。

    有一个旧的(2006 年!)未解决的问题,以防有人希望发送补丁:https://hibernate.atlassian.net/browse/HBX-711


    修复选项:

    • JAVA_OPTS环境变量中添加-Dfile.encoding=UTF-8,如:

      # Linux/Unix
      export JAVA_OPTS=-Dfile.encoding=UTF-8
      # Windows
      set JAVA_OPTS=-Dfile.encoding=UTF-8
      
      # Attention, check before if your JAVA_OPTS doesn't already have a value. If so,
      # then it should be
      export JAVA_OPTS=$JAVA_OPTS -Dfile.encoding=UTF-8
      # or
      set JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8
      
    • 在您的 Maven 插件中设置一个属性(可以是surefirefailsafe 或其他,取决于您如何运行导入休眠文件的代码)。 surefire 的示例:

      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
            <argLine>-Dfile.encoding=UTF8</argLine>
         </configuration>
      </plugin>
      
    • 如果 gradle:要在 gradle 中添加此属性,请将 systemProperty 'file.encoding', 'UTF-8' 添加到任务配置块。 (Thanks @meztihn)

    【讨论】:

    • +1 出于正确的原因,但假设不正确,因为那样您的测试将依赖于平台。最简单的解决方案是在您的 IDE 中将文本文件编码设置为 UTF-8&lt;argLine&gt;-Dfile.encoding=UTF8&lt;/argLine&gt; 如果使用 maven,如 @Jaroslav Frolikov 已经说明的那样。
    • 要在 gradle 中添加此属性,请将 systemProperty 'file.encoding', 'UTF-8' 添加到任务配置块中。
    【解决方案2】:

    我在测试阶段使用 import.sql 填充数据库,这个链接帮助我解决了编码问题:http://javacimrman.blogspot.ru/2011/07/hibernate-importsql-encoding-when.html

    【讨论】:

      【解决方案3】:

      从 5.2.3 版开始,Hibernate 中有一个新属性用于此类情况。

      <property name="hibernate.hbm2ddl.charset_name" value="UTF-8" />
      

      【讨论】:

        【解决方案4】:

        这是一个可靠的解决方案,无需设置任何系统属性

        我们假设导入文件使用UTF-8 编码,但Java 默认字符集不同,比如latin1

        1) 为 import_files_sql_extractor hibernate.hbm2ddl.import_files_sql_extractor=com.pragmasphere.hibernate.CustomSqlExtractor

        定义一个自定义类

        2) 修复无效字符串在实现中被hibernate读取。

        package com.pragmasphere.hibernate;
        
        import org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor;
        
        import java.io.IOError;
        import java.io.Reader;
        import java.io.UnsupportedEncodingException;
        import java.nio.charset.Charset;
        
        public class CustomSqlExtractor extends MultipleLinesSqlCommandExtractor {
        
            private final String SOURCE_CHARSET = "UTF-8";
        
            @Override
            public String[] extractCommands(final Reader reader) {
                String[] lines = super.extractCommands(reader);
        
                Charset charset = Charset.defaultCharset();
                if (!charset.equals(Charset.forName(SOURCE_CHARSET))) {
                    for (int i = 0; i < lines.length; i++) {
                        try {
                            lines[i] = new String(lines[i].getBytes(), SOURCE_CHARSET);
                        } catch (UnsupportedEncodingException e) {
                            throw new IOError(e);
                        }
                    }
                }
        
                return lines;
            }
        }
        

        您可以使用导入文件使用的另一种编码更改SOURCE_CHARSET 的值。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-12-01
          • 2014-03-18
          • 2019-07-09
          • 1970-01-01
          • 2022-09-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多