【问题标题】:JPA: accented character is saved as ? in databaseJPA:重音字符另存为?在数据库中
【发布时间】:2013-08-16 09:00:54
【问题描述】:

我们的应用程序在 weblogic 10g 上运行,并通过默认 eclipselink 实现支持的 JPA 将数据持久化到 oracle 9 数据库中。

实体很简单:

@Entity
@Table(name="PLUGINDATA")
@SequenceGenerator(name="plugin_seq", sequenceName="PLUGINDATASEQ", initialValue = 1000, allocationSize = 50)
public class PluginData implements Serializable {
    @Column(name = "data", length = 4000, nullable = false)
    private String data;

@PersistenceContext(unitName = "XYZ")
protected javax.persistence.EntityManager entityManager;

entityManager.persist(entity);

当我传递包含重音字符的字符串时,它们在 EJB 中是可以的:

83, 116, -59, -103, 101, 100, 111, -60, -115, 101, 115, 107, -61, -67, 32, 107, 114, 97, 106

但它们在数据库中存储已损坏:

83, 116, 63, 63, 101, 100, 111, -60, 63, 101, 115, 107, 63, 63, 32, 107, 114, 97, 106

例如重音字符替换为问号:St??edo�?esk?? kraj

我不明白,代码没问题,数据源设置与其他正常工作的应用程序一样。有什么想法吗?

编辑 1:

这是 SID NLS 设置(非常像另一个应用程序数据库)

select DECODE(parameter, 'NLS_CHARACTERSET', 'CHARACTER SET', 'NLS_LANGUAGE', 'LANGUAGE', 'NLS_TERRITORY', 'TERRITORY') name, value 
from v$nls_parameters
where parameter in ('NLS_CHARACTERSET', 'NLS_LANGUAGE', 'NLS_TERRITORY');

LANGUAGE    ENGLISH
TERRITORY   CZECH REPUBLIC
CHARACTER SET   EE8ISO8859P2

编辑 2:

WebLogic / 数据源

连接池选项卡具有以下属性:

URL: jdbc:oracle:thin:@hostname:1521:SID 
Driver: oracle.jdbc.xa.client.OracleXADataSource

Oracle 选项卡:一切都未选中

【问题讨论】:

  • 在存储之前如何设置data 的值?您的表/数据库排序规则设置为什么?你有能力在连接属性中设置字符编码吗?如果是这样,它设置为什么?
  • 数据是通过setter设置的,其内容在persist之前有效。我不以任何方式操纵连接。我只是让应用服务器设置EntityManager。
  • 如果将字符集设置为 WE8ISO8859P1(即 ISO-8859-1)是否有效?数据中未正确编码的字符实际上不在 EE8ISO8859P2 (ISO-8859-2) 中。

标签: java jpa jdbc internationalization


【解决方案1】:

如果它可能是数据库中的问题。 oracle 数据库默认不支持重音字符。你必须去你的数据库运行这个“select * from NLS_DATABASE_PARAMETERS;”

如果您将 NLS_LANGUAGE 设置为 AMERICAN,则表格中不能有特殊字符(é、è、ê 等)

解决这个问题

在 Windows 中:HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_O10R2\NLS_LANG=FRENCH_FRANCE.WE8MSWIN1252

在 Linux 中:设置 NLS_LANG=FRENCH_FRANCE.WE8PC850

【讨论】:

  • 他原始数据中的重音字符也会被WE8ISO8859P1覆盖;并且实际上在他当前的设置 EE8ISO8859P2 中丢失了。
【解决方案2】:

查看您的原始字符串与存储的字符串,模式是所有字符 > 0x7f 都存储为 0x3f (63)。这是转换为 US-ASCII(或其他一些没有字节 0x80-0xff 的代码点的字符集)的典型。

这肯定是某个地方的字符编码问题。您指定的未编码字符不在 ISO-8859-2 中,这是您为其配置了 NLS 的字符集。

您可以尝试 ISO-8859-1 (WE8ISO8859P1),例如FRENCH_FRANCE.WE8ISO8859P1(或 CZECH_CZECH REPUBLIC.WE8ISO8859P1,如果您想保持语言为捷克语)。 WE8MSWIN1252比8859-1更完整。

如果您的数据库支持,您也可以使用 CZECH_CZECH REPUBLIC.UTF8。

【讨论】:

  • 我同意你的看法。但我不知道它发生在哪里以及如何避免它。其他应用程序以相同的方式实现和部署,并且它们可以正常工作。这对我来说是个谜。
  • 您的 cmets 排除了应用程序逻辑中的问题以及排序规则问题。它必须是连接设置,或者 EclipseLink(我从未使用过它)正在进行某种转换。您的数据库连接字符串/设置是什么(不要发布您的主机、用户名或密码)?
  • 在哪里?在数据库 SID 中?在数据库/ weblogic的shell环境中?
  • 取决于您的平台。它们都被描述在oracle.com/technetwork/database/globalization/…
  • 我在另一台机器 (linux) 上运行了代码,一切正常。我必须在星期一调查这台本地机器和客户机器之间的区别。一是显而易见的:HP-UX。我祈祷它会是weblogic shell环境,因为我无法触摸数据库。
【解决方案3】:

好的,终于成功了。你们都是对的,这是语言环境的问题。尽管如此,这是weblogic问题,而不是数据库。我尝试在不同的 weblogic 上针对同一个数据库运行示例代码,它运行顺利。然后我比较了 shell 环境,正确的 weblogic 将 LANG 设置为 UTF-8。当我在 setDomainEnv.sh 中添加以下行并重新启动 weblogic 时,它开始正常工作。感谢您的帮助。

export LANG=en_US.utf8

【讨论】:

    猜你喜欢
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-22
    • 2019-07-05
    • 2015-02-20
    相关资源
    最近更新 更多