【问题标题】:MySQL with JPA: Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE)MySQL 与 JPA:排序规则 (utf8mb4_general_ci,IMPLICIT) 和 (utf8_general_ci,COERCIBLE) 的非法混合
【发布时间】:2014-12-04 10:04:16
【问题描述】:

我需要能够在我的数据库中存储像\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")

但还是一无所获。

然后我尝试将排序规则直接放在连接中(在 GlassFish 中,我使用的是 connection_pool),因为我 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 更高级的东西?

【问题讨论】:

  • 连接池字符编码失败,因为在 java 中,utf-8mb4 只是 UTF-8。我认为这是未设置为正确排序规则的连接。为什么不尝试在上下文初始化期间执行SET NAMES 'utf8mb4' 查询(或在您的where .. like 查询之前进行测试)?
  • 难以置信,你的这个小技巧,成功了!数据库正在接受奇怪的字符而不抱怨:) 这可能不是最有效的方法,但现在我可以执行这个:entityManager.createNativeQuery("SET NAMES 'utf8mb4'");,只要我期望文本需要超过 utf8。也许你可以发布这个答案,所以我可以接受——除非你有更多好主意
  • 如果您愿意,也可以在my.cnf 中设置,但将适用于所有连接(不知道是否有任何缺点)
  • 另外,您可以将您的 jdbc 客户端更新到较新的版本吗?
  • 这意味着在我无法更新自己的远程服务器上运行。所以我只有一个 MariaDB 5.5.36 服务器和 GlassFish 3.1.2.2。但是,我不会将数据库用于其他任何事情,所以我可以编辑my.cnf

标签: java mysql jpa glassfish collation


【解决方案1】:

您不需要在 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

【讨论】:

  • 谢谢。有趣的链接 - 我使用 mysql-connector-java-5.1.32 所以我在更改 my.conf 时应该没问题
猜你喜欢
  • 2021-05-06
  • 1970-01-01
  • 2010-09-16
  • 2010-10-30
  • 2010-11-03
  • 2015-06-03
  • 1970-01-01
  • 2016-09-17
  • 2017-10-17
相关资源
最近更新 更多