MySQL与JPA:非法混合排序(utf8mb4_general_ci,IMPLICIT)和(utf8_general_ci,COERCIBLE)

时间:2014-10-09 12:57:49

标签: java mysql jpa glassfish collation

我需要能够在我的数据库中存储\xF0\x9F\x94\xA5等字符,根据this post需要UTF8mb4编码。

所以我用

设置我的数据库
CREATE DATABASE `myDB` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci

并在MySQL shell中验证它是否有效:

SHOW FULL COLUMNS FROM myTable;

+---------+------------------+--------------------+----
| Field   | Type             | Collation          | ...
+---------+------------------+--------------------+-----
| id      | int(10) unsigned | NULL               | ...   
| myColumn| text             | utf8mb4_general_ci | ...
+---------+------------------+--------------------+-----

到目前为止一切顺利。

运行我的程序后,我得到了异常

Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation 'like'
Error Code: 1267

对于记录:我在使用GlassFish 3.1的web应用程序中使用Java Persistency API(JPA)。执行命名查询时会抛出Exception

@NamedQuery(name = "myTable.findByMyColumn", query = "SELECT c FROM myTable c WHERE c.myColumn LIKE :myColumn")

但是,只有当查询的字符串实际包含那些已经使用的表情符号字符(\xF0\x9F\x94\xA5)时才会出现错误

Call: SELECT id, myColumn FROM myDB.myTable WHERE myColumn LIKE ?
bind => [Something something Lorem Ipsum ]  

所以我想,某个地方可能仍然是utf8_general_ci设置,我尝试将COLLATION直接放入查询中(如建议in this post here

@NamedQuery(name = "myTable.findByMyColumn", query = "SELECT c COLLATE utf8mb4_general_ci FROM myTable c WHERE c.myColumn LIKE :myColumn")

但仍然没有。

然后我尝试将排序规则直接放在连接中(在我使用 connection_pool 的GlassFish中),因为read here

characterEncoding, UTF8mb4

但是GlassFish只说了Connection could not be allocated because: Unsupported character encoding 'UTF8mb4'

我做的最后一件事是检查数据库系统(我正在使用MariaDB)

show variables WHERE variable_name like "col%";
+----------------------+------------------+
| Variable_name        | Value            |
+----------------------+------------------+
| collation_connection | utf8_general_ci  |
| collation_database   | utf32_general_ci |
| collation_server     | utf8_general_ci  |
+----------------------+------------------+

现在我完全迷失了......

如果使用utf8mb4utf-32或其他任何比较简单的UTF-8更高级的内容,我该怎么办?

1 个答案:

答案 0 :(得分:11)

Java端不需要任何更改,因为utf8mb4只是Java中的UTF-8

相反,正如你在这里看到的那样:

show variables WHERE variable_name like "col%";
+----------------------+------------------+
| Variable_name        | Value            |
+----------------------+------------------+
| collation_connection | utf8_general_ci  |
| collation_database   | utf32_general_ci |
| collation_server     | utf8_general_ci  |
+----------------------+------------------+

您的连接设置仍为utf8_general_ci;要在连接级别设置它,一个选项是执行(特定于mysql)查询:

SET NAMES='utf8mb4'

在尝试使用utf8mb4整理之前;或者,通常用于mysql服务器,在/etc/my.cnf

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

另一个不更改连接字符串的选项是使用jdbc驱动程序版本> = 5.1.13: http://www.opensubscriber.com/message/java@lists.mysql.com/14151747.html