Eu preciso ser capaz de armazenar caracteres como \xF0\x9F\x94\xA5
no meu database, que, de acordo com este post precisa de codificação UTF8mb4
.
Então eu configurei meu database com
CREATE DATABASE `myDB` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
e verificado no shell do MySQL se fosse efetivo:
SHOW FULL COLUMNS FROM myTable; +---------+------------------+--------------------+---- | Field | Type | Collation | ... +---------+------------------+--------------------+----- | id | int(10) unsigned | NULL | ... | myColumn| text | utf8mb4_general_ci | ... +---------+------------------+--------------------+-----
Por enquanto, tudo bem.
Depois de executar o meu programa, recebi esta exceção :
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
Para o registro : Eu estou usando o Java Persistency API (JPA) no meu webapplication com GlassFish 3.1. A Exception
é lançada ao executar uma consulta nomeada:
@NamedQuery(name = "myTable.findByMyColumn", query = "SELECT c FROM myTable c WHERE c.myColumn LIKE :myColumn")
No entanto, parece que o erro ocorre apenas quando a String consultada contém, na verdade, esses caracteres emoji ( \xF0\x9F\x94\xA5
)
Call: SELECT id, myColumn FROM myDB.myTable WHERE myColumn LIKE ? bind => [Something something Lorem Ipsum 🇬🇧]
Então eu pensei, que em algum lugar ainda poderia ser um utf8_general_ci
configurado e eu tentei colocar o COLLATION
diretamente na consulta (como sugerido neste post aqui )
@NamedQuery(name = "myTable.findByMyColumn", query = "SELECT c COLLATE utf8mb4_general_ci FROM myTable c WHERE c.myColumn LIKE :myColumn")
Mas ainda nada.
Então eu tentei colocar o agrupamento diretamente na conexão (no GlassFish eu estou usando um connection_pool ) como eu li aqui
characterEncoding, UTF8mb4
Mas o GlassFish disse que apenas o Connection could not be allocated because: Unsupported character encoding 'UTF8mb4'
A última coisa que fiz foi verificar o sistema de database (estou usando o 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 | +----------------------+------------------+
E agora estou completamente perdido …
O que posso fazer para usar utf8mb4
ou utf-32
ou qualquer outra coisa que seja mais avançada que o simples UTF-8?
Você não precisa de nenhuma mudança no lado do Java, já que o utf8mb4
é apenas UTF-8
em Java.
Em vez disso, como você pode ver aqui:
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 | +----------------------+------------------+
sua configuração de conexão ainda é utf8_general_ci
; para configurá-lo no nível de conexão, uma opção é executar a consulta (específica do mysql):
SET NAMES='utf8mb4'
antes de qualquer tentativa de usar o agrupamento utf8mb4; ou, geralmente, para o servidor mysql, em /etc/my.cnf
:
[mysql] default-character-set = utf8mb4 [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci
Outra opção sem alterar a string de conexão é usar uma versão do driver jdbc> = 5.1.13: http://www.opensubscriber.com/message/java@lists.mysql.com/14151747.html