web-dev-qa-db-ja.com

MySQLは不正な文字列値エラーをスローします

次のツイートをロングテキスト列/ 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)
36
priya

問題を引き起こしているのは、ツイートの最後のキャラクターです。

「絵文字」の文字、別名日本のスマイリーフェイスのように見えますが、ChromeまたはSafariでは表示されません。

MySQLの一部のバージョンには、4バイトのutf文字を保存する既知の問題があります。明らかに、utf8mb4を使用して4バイトUTF文字を表す必要があります。通常のutf8文字セットは最大3バイトの文字しか表すことができないため、 Basic Multilingual Plane の外側にある文字を格納できません

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

これは基本的に、MySQLのutf8データ型が実際には適切なutf8ではないことを意味するため、これは私にとってニュースです。

ここでこれを処理する方法の提案があります mysqlにutf-8 mb4文字(ios5のemoji)を挿入する方法? を含む:

「また、アプリレイヤーがデータベース接続の文字セットをutf8mb4に設定していることを確認してください。これが実際に行われていることを再確認してください。文字セットが正しく設定されません。そうでない場合は、更新または自分でコンパイルする必要があります。」

Connector/Jを使用している場合、接続構成でcharacter_set_server = utf8mb4を設定する必要があります。

すべての文字セットはutf8mb4である必要があります。これは試したかもしれませんが、現在設定されていません。

57
Danack

私はDanask57の答えが好きです-それは正しいし、それを行う「正しい」方法です。 (私は自分で投票しました)

ただし、もう1つの手っ取り早い解決策は、スキーマを変更することです。 varbinaryまたはbinaryを使用して、ツイート文字列を保存します。

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

利点は、文字セットの問題が発生しないことです。

欠点は、文字列の比較と並べ替えが失われ、列の全文索引付けができなくなることです。

ただの提案ですが、これは「正しい」答えではなく、物事を機能させるための迅速で汚い解決策です。

8
FlipMcF

私はこの正確な問題を抱えていました。解決するには、この優れたガイドに従ってmysqlサーバー側のデフォルトのエンコードをutf8mb4に変更します。 http://mathiasbynens.be/notes/mysql-utf8mb4 .

構成ファイルに変更を加えた後、mysqldサービスを再起動することを忘れないでください。

私にとっては、mysql jdbcドライバーをバージョン5.1.18(バージョン5.1.6から)に更新する必要もありました。 mysql jdbcドライバーがutf8mb4文字エンコードで適切に動作するためには、少なくともバージョン5.1.14を使用する必要があることをどこかで読みました。お役に立てれば!

5
mancini0

あなたの例の引用符の外にテキストがあるのはなぜですか-すなわち、「はい」

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