【发布时间】: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 |
+----------------------+------------------+
现在我完全迷路了……
我该怎么做才能使用 utf8mb4 或 utf-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