Hibernate/JPA import.sql utf8 повреждены
Я использую 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. Шрифт по умолчанию в 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" />
to persistence.xml. Но это не помогло.
Fix:
Я решил это в конце концов. Я использую Tomcat, и это является причиной коррупции, а не hibernate или mysql. Я начал его с команды JAVA_OPTS = -Dfile.encoding = UTF-8, и моя проблема исчезла.
Название вопроса теперь вводит в заблуждение. Извините за это.
Ответы
Ответ 1
При создании считывателя для этого файла Hibernate использует new InputStreamReader(stream);
напрямую, без явного кодирования (предполагается/используется кодировка кодировки платформы исполнения по умолчанию).
Итак, другими словами, ваш файл import.sql
должен быть в кодировке кодировки платформы исполнения по умолчанию.
Для этого существует старая (2006!) Открытая проблема, на случай, если кто-то захочет отправить патч: https://hibernate.atlassian.net/browse/HBX-711
Варианты исправления:
-
Добавьте -Dfile.encoding=UTF-8
в переменную среды JAVA_OPTS
, например:
# 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 (может быть surefire
, failsafe
или другим, в зависимости от того, как вы запускаете код, импортирующий файл гибернации). Пример для surefire
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Dfile.encoding=UTF8</argLine>
</configuration>
</plugin>
-
Если gradle: чтобы добавить это свойство в gradle, добавьте systemProperty systemProperty 'file.encoding', 'UTF-8'
в блок конфигурации задачи. (Спасибо @meztihn)
Ответ 2
Я использую import.sql для заполнения базы данных на этапе тестирования, и эта ссылка помогла мне решить проблему кодирования: http://javacimrman.blogspot.ru/2011/07/hibernate-importsql-encoding-when.html.
Ответ 3
Здесь надежное решение без установки какого-либо системного свойства.
Мы предполагаем, что файлы импорта закодированы с помощью 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
на другую кодировку, используемую файлами импорта.
Ответ 4
Начиная с версии 5.2.3, в Hibernate появилось новое свойство для подобных случаев.
<property name="hibernate.hbm2ddl.charset_name" value="UTF-8" />