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

Mar*_*ius 6 java mysql hibernate utf-8

我试图通过使用Hibernate在MySQL数据库中保存一些值,但大多数立陶宛字符都不会被保存,包括?? ?? ?? ?? ?? ?? ??(它们被保存为?),但是,šŠ žŽ确实得到了保存.

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

到目前为止我尝试了什么:

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, "/*");
}
Run Code Online (Sandbox Code Playgroud)

如上所述这里

我尝试添加?useUnicode=true&characterEncoding=utf-8到db connection url.

如上所述这里

我确保我的数据库设置为UTF-8字符集. phpmyadmin > information_schema > schemata

def db_name utf8 utf8_lithuanian_ci NULL
Run Code Online (Sandbox Code Playgroud)

这是我保存到db的方式:

//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);
    }
}
Run Code Online (Sandbox Code Playgroud)

第一组println包含所有立陶宛字符,而第二组替换最多 ?

编辑:添加详细信息

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 
Run Code Online (Sandbox Code Playgroud)

编辑:我找不到合适的解决方案,所以我想出了一个解决方法.我最终逃脱/取消了角色,将它们存储起来:\uXXXX.

Ric*_*mes 3

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

\n\n

但更重要的是,4 个角色确实出现了。 如果正确存储为 utf8,\xc5\xa0 应该是。C5A0但是,我怀疑您会看到8A,这意味着表中的列确实被声明为CHARACTER SET latin1。(这 4 个字符出现在我的字符集博客的第一列中)。

\n\n

执行SHOW CREATE TABLE查看该列是如何定义的。如果它显示latin1,则问题出在表定义上,您可能应该重新开始。

\n

  • 这样做的十六进制看起来像正确的立陶宛字符。我怀疑 ų 是不久前插入的,当时您对_something_进行了不同的配置。(请注意 Š 已通过。)“插入建筑物值 (11,'ąĄčČęĘ', 'asda');” 是通过 Hibernate 完成的吗?它似乎已正确存储。 (2认同)