Oracle数据库采用UTF-16,Java hibernate webapp采用UTF-8,★字符不存在

时间:2016-02-10 11:04:12

标签: java oracle hibernate encoding utf-8

我有一个用Java6 + Hibernate编写的webapp(jdbc oracle瘦客户端)+在tomcat7 + ORACLE 10g上运行的Guice。该应用程序完全以UTF-8编码,db以UTF-16编码。

Oracle Docs我看到客户端使用jvm编码将数据发送到数据库。数据在db上转换,应该正确保留。不幸的是,当我尝试保留包含的字符串时,这会被保留为反转的问号。

我尝试设置jvm参数-Dfile.encoding=UTF8,但这不起作用。还有其他可能的解决方案吗?

更新

给定一个实体

@Entity
@Table(name="bean")
public class Bean{
    private String name;
    private String surname;
    //getters and setters
}

扩展BasePersistentService的服务,允许数据访问, 一个包含两列的“bean”表:

name nvarchar2(200),
surname varchar2(200)

确切的用例如下:

// context initialized, BeanService injected in the variable beanService
Bean p = new Bean();
p.setName("myLittleStar★");
p.setSurname("nope");
beanService.save(p);

然后在db:

select * from bean;

结果:

name: 'myLittleStar¿'
surname: 'nope'

这是单个jdbc资源

<Resource name="jdbc/dbConnPool" auth="Container"
    factory="oracle.ucp.jdbc.PoolDataSourceImpl" type="oracle.ucp.jdbc.PoolDataSource"
    description="Connection Pool DB" connectionFactoryClassName="oracle.jdbc.pool.OracleDataSource"
    initialPoolSize="10" minPoolSize="10" maxPoolSize="90" maxStatements="100"
    connectionWaitTimeout="30" inactiveConnectionTimeout="20"
    abandonedConnectionTimeout="600" user="*******" password="*******"
    url="*******" fastConnectionFailoverEnabled="true"
    onsConfiguration="*******" connectionPoolName="UCPPool"
    validateConnectionOnBorrow="true" />

这是hibernate cfg

的相关部分

<session-factory>
    <property name="hibernate.search.default.directory_provider">
        org.hibernate.search.store.FSDirectoryProvider
    </property>

    <property name="connection.datasource">java:comp/env/jdbc/dbConnPool</property>
    <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
    <property name="archive.autodetection">class, hbm</property>

</session-factory>

我没有找到在文件中设置编码的可能配置。

此外,我发现无法在oracle连接字符串中配置编码。

告诉我是否可以提供更多有用的数据。

编辑2 : 将'bean'表中'name'列的类型从varchar2替换为nvarchar2,这不能解决问题,但是必要。

1 个答案:

答案 0 :(得分:0)

可怕但有效的解决方案:

使用urlencode,Base64或更适合您需要的编码算法对需要持久化的字符串进行编码。当然,编码必须产生一个输出,该输出不包含不能保留在数据库中的字符。

您可以包装实体或更改设置器。从db获取实体时,必须反过来解码字符串。

这是一个丑陋的解决方法,但它解决了本地的问题。