Подтвердить что ты не робот

MySQL выбрасывает неверную ошибку строкового значения

Я пытаюсь сохранить следующий твит в столбце longtext/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)
4b9b3361

Ответ 1

Это символ в конце твита, который вызывает проблему.

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

Известны проблемы хранения четырехбайтовых символов utf в некоторых версиях MySQL. По-видимому, вы должны использовать 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, вам нужно установить character_set_server = utf8mb4 в конфигурацию подключения.

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

Ответ 2

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

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

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

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

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

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

Ответ 3

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

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

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

Ответ 4

Почему у вас есть текст за пределами цитат в вашем примере - то есть "lol yes"

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

Ответ 5

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

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

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