UTF-8不会在Hibernate + MySQL上持久存在

时间:2015-03-29 16:39:25

标签: java mysql hibernate utf-8

我正在尝试使用Hibernate在MySQL数据库中保存一些值,但大多数立陶宛字符都不会被保存,包括ąĄ čČ ęĘ ėĖ įĮ ųŲ ūŪ(它们保存为?),但是,{{ 1}}得到保存。

如果我手动插入,那么这些值会被正确保存,因此问题很可能出现在Hibernate配置中。

到目前为止我尝试过:

šŠ žŽ

如上所述here

我尝试将hibernate.charset=UTF-8 hibernate.character_encoding=UTF-8 hibernate.use_unicode=true --------- properties.put(PROPERTY_NAME_HIBERNATE_USE_UNICODE, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_USE_UNICODE)); properties.put(PROPERTY_NAME_HIBERNATE_CHARSET, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CHARSET)); properties .put(PROPERTY_NAME_HIBERNATE_CHARACTER_ENCODING, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CHARACTER_ENCODING)); --------- private void registerCharachterEncodingFilter(ServletContext aContext) { CharacterEncodingFilter cef = new CharacterEncodingFilter(); cef.setForceEncoding(true); cef.setEncoding("UTF-8"); aContext.addFilter("charachterEncodingFilter", cef) .addMappingForUrlPatterns(null, true, "/*"); } 添加到数据库连接网址。

如上所述here

我确保我的数据库设置为UTF-8字符集。 ?useUnicode=true&characterEncoding=utf-8

phpmyadmin > information_schema > schemata

这是我保存到db:

的方式
def db_name utf8 utf8_lithuanian_ci NULL

第一组println包含所有立陶宛字符,而第二组用//Controller buildingService.addBuildings(schema.getBuildings()); List<Building> buildings = buildingService.getBuildings(); System.out.println("-----------"); for (Building b : schema.getBuildings()) { System.out.println(b.toString()); } System.out.println("-----------"); for (Building b : buildings) { System.out.println(b.toString()); } System.out.println("-----------"); //Service: @Override public void addBuildings(List<Building> buildings) { for (Building b : buildings) { getCurrentSession().saveOrUpdate(b); } } 取代最多

编辑:添加了详细信息

?

编辑: 我找不到合适的解决方案,所以我想出了一个解决方法。我最终逃脱/取消了角色,将它们存储起来:insert into buildings values (11,'ąĄčČęĘ', 'asda'); select short, hex(short) from buildings; //Šalt. was inserted via hibernate //letters are properly displayed: ąĄčČęĘ | C485C484C48DC48CC499C498 MIF Šalt. | 4D494620C5A0616C742E select address, hex(address) from buildings; Šaltini? <...> | C5A0616C74696E693F20672E2031412C2056696C6E697573 //should contain "ų" -------- show create table buildings; buildings | CREATE TABLE `buildings` ( `id` int(11) NOT NULL, `short` varchar(255) COLLATE utf8_lithuanian_ci DEFAULT NULL, `address` varchar(255) COLLATE utf8_lithuanian_ci DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_lithuanian_ci

3 个答案:

答案 0 :(得分:3)

让我们验证它们是否存储正确...请执行SELECT col, HEX(col) ...以获取具有立陶宛字符的单元格。正确存储的ą将显示C485。其他应显示C4xx或C5xx的各种十六进制值。 3F?

但是,更重要的是,确实显示了4个字符。如果正确存储为utf8,则Š C5A0。但是,我怀疑,您会看到8A,这意味着表中的列实际上已声明为CHARACTER SET latin1。 (4个字符显示在my charset blog的第一列中。)

执行SHOW CREATE TABLE以查看列的定义方式。如果它显示latin1,那么问题在于表定义,你可能应该重新开始。

答案 1 :(得分:0)

您必须确保参与数据录入的每个组件都明确使用 UTF-8 编码。

  • 如果您通过浏览器输入值,请确保 使用以下标题显示结果的页面 Content-Type: text/html; charset=utf-8

  • 输入表格定义如下

    <form action="submit" accept-charset="UTF-8">...</form>

  • 如果要从字节数组创建String个对象,请确保 明确说明构造函数中的Charset

  • 如果您的条目来自文本文件,则该文件必须为 UTF-8 编码。

  • 如果它直接在您的代码中进行硬编码,那么源必须是 UTF-8 编码。

答案 2 :(得分:0)

您的数据库保存正确的UTF-8(特殊字母的两个或更多字节)这一事实令人放心。

如果您为特殊字母获得一个?,则会尝试将UTF-8转换为某些不包含这些字母的编码。 似乎就是这种情况 正确转换的字母位于 ISO-8859-1 Windows-1252 范围内。其他人不是。 现在ISO-88591-1 aka Latin-1是默认的HTTP编码,在java EE服务器中是默认的。你可能喜欢在写作之前做:

response.setCharacterEncoding("UTF-8");

现在System.out.println的一个问题是它使用系统默认编码。使用记录器记录到文件更有趣。或者调试并检查String及其char数组。

架构看起来似乎有效,可能是架构字符串直接来自Java源,编辑器编码和javac编译器编码不同。这可以通过u-evcaping java中的字符串文字来检查:"\u0105"而不是"ą"

进行从数据库写入和读取的单元测试