MySQL выдает ошибку неверного строкового значения - PullRequest
36 голосов
/ 03 января 2012

Я пытаюсь сохранить следующий твит в столбце длинного текста / utf8 charset / MySQL 5.5. база данных с хранилищем MyISAM.

Мы также попробовали кодировки utf8mb4, utf16, utf32, но не смогли обойти эту проблему.

tweet="@Dorable_Dimples: Okay enough of those #IfYouWereMines I'm getting dep
ressed. #foreveralone ?" lol yes

mysql> ALTER DATABASE foo CHARACTER SET utf8 COLLATE utf8_bin;

mysql> show variables like 'char%';
+--------------------------+-------------------------------------------+
| Variable_name | Value |
+--------------------------+-------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /rdsdbbin/mysql-5.5.12.R1/share/charsets/ |

Incorrect string value: '\xF0\x9F\x98\x94\xE2\x80...' for column 'tweet' at row 1

Unable to store tweet "@Dorable_Dimples: Okay enough of those #IfYouWereM
ines I'm getting depressed. #foreveralone ?" lol yes
javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCExcept
ion: could not insert
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityMana
gerImpl.java:1387)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityMana
gerImpl.java:1315)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityMana
gerImpl.java:1321)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityMana
gerImpl.java:843)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)

at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(
SQLStateConverter.java:140)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.ja
va:128)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelpe
r.java:66)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(Abstra
ctReturningDelegate.java:64)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(Abstract
EntityPersister.java:2345)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(Abstract
EntityPersister.java:2852)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentity
InsertAction.java:71)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplica
te(AbstractSaveEventListener.java:320)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(Abstract
SaveEventListener.java:203)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(
AbstractSaveEventListener.java:129)
at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(E
JB3PersistEventListener.java:69)
at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(
DefaultPersistEventListener.java:179)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultP
ersistEventListener.java:135)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultP
ersistEventListener.java:61)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:808)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:782)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:786)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityMana
gerImpl.java:837)
... 5 more
Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x94\xE2\x
80...' for column 'tweet' at row 1
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3609)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3541)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2624)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.jav
a:2127)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:
2427)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:
2345)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:
2330)
at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAnd
Extract(IdentityGenerator.java:94)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(Abstra
ctReturningDelegate.java:57)

Ответы [ 5 ]

57 голосов
/ 07 января 2012

Проблема в персонаже в конце твита.

Это похоже на персонажа 'эмодзи', похожего на японское смайлик, но оно не отображается для меня ни в Chrome, ни в Safari.

В некоторых версиях MySQL существуют известные проблемы с сохранением 4-байтовых символов utf. По-видимому, вы должны использовать utf8mb4 для представления 4-байтовых символов UTF, поскольку обычный набор символов utf8 может представлять только символы длиной до 3 байтов и поэтому не может хранить символы, находящиеся за пределами Базовая многоязычная плоскость

http://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html

Что для меня новость, поскольку в основном это означает, что тип данных utf8 в MySQL не совсем правильный utf8.

Есть предложения о том, как справиться с этим здесь Как вставить UTF-8 символ MB4 (Emoji в ios5) в MySQL? в том числе:

"Также убедитесь, что уровень вашего приложения устанавливает для набора символов своих соединений с базой данных utf8mb4. Дважды проверьте, что это на самом деле происходит - если вы используете старую версию выбранной вами клиентской библиотеки mysql фреймворка, возможно, она не скомпилирована с поддержкой utf8mb4, и он не установит кодировку должным образом. Если нет, возможно, вам придется обновить или скомпилировать ее самостоятельно "

Если вы используете Connector / J, вам нужно установить символ_с_сервера = utf8mb4 в конфигурации соединения.

Все ваши наборы символов должны быть utf8mb4, которые вы, возможно, пробовали, но в данный момент не установлены.

8 голосов
/ 11 января 2012

Мне нравится ответ Danask57 - это правильный и «правильный» способ сделать это. (Я сам проголосовал за это)

Однако, другое быстрое и грязное решение - изменить схему. используйте varbinary или binary для хранения строки твита:

http://dev.mysql.com/doc/refman/5.0/en/binary-varbinary.html

Плюс в том, что у вас не возникнет проблем с набором символов.

Недостатком является то, что сравнение и сортировка строк будут потеряны, и вы не сможете выполнить полнотекстовую индексацию столбца.

Просто предложение, но это не «правильный» ответ, просто быстрое и грязное решение, которое заставляет все работать.

5 голосов
/ 07 июня 2014

У меня была именно эта проблема.Чтобы решить эту проблему, измените кодировку по умолчанию на стороне сервера mysql на utf8mb4, следуя этому прекрасному руководству: http://mathiasbynens.be/notes/mysql-utf8mb4.

Не забудьте перезапустить службу mysqld после внесения изменений в файл конфигурации.

Мне также нужно было обновить драйвер mysql jdbc до версии 5.1.18 (с версии 5.1.6).Я где-то читал, что вы должны использовать по крайней мере версию 5.1.14, чтобы драйвер mysql jdbc хорошо работал с кодировкой символов utf8mb4.Надеюсь, это поможет!

1 голос
/ 06 января 2012

Почему у вас есть текст вне кавычек в вашем примере - например, 'lol yes'

tweet="@Dorable_Dimples: Okay enough of those #IfYouWereMines I'm getting depressed. #foreveralone ?" lol yes
0 голосов
/ 11 января 2012

проблема в строке "@". база данных движка интерпретируется как специальный символ. я делаю:

   tweet="Dorable_Dimples: Okay enough of those #IfYouWereMines I'm getting dep

волосы погладила. #foreveralone? "lol yes

...