在使用 UTF-8 字符集資料存盤 CLOB 資料時,我的 Informix 資料庫遇到了問題。帶有 UTF-8 字符的常規 varchar 資料型別存盤沒有任何問題;但是,當我將資料存盤為 CLOB 并且資料(在我的情況下為 XML)包含 utf-8 字符時,只會存盤截斷的 XML。
示例字符:德語變音
Informix db 字符編碼設定為 utf-8。
下面是我的 hbm 檔案
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.test.adapter.persistence.bean">
<class name="MediaLayoutConfigPojo" table="medialayoutconfig">
<id name="dbId" type="int" column="id">
<generator class="native" />
</id>
<property name="layoutxml" type="clob" column="layoutxml" />
<property name="name" type="string" column="name" />
<property name="description" type="string" column="description" />
<property name="layouttype" type="string" column="layouttype" />
</class>
</hibernate-mapping>
SQL驅動程式類是
<property name="connection.driver_class">com.informix.jdbc.IfxDriver</property>
<property name="dialect">org.hibernate.dialect.InformixDialect</property>
我正在使用 ifxjdbc-3.50.JC9.jar JDBC 驅動程式(不幸的是,我堅持使用它;升級它可能會導致額外的損壞,因為它是一個遺留應用程式)。
使用的 Hibernate 版本是:hibernate-core-3.6.3.Final.jar
我瀏覽了這個鏈接https://hibernate.atlassian.net/browse/HHH-6127。不確定我是否在驅動程式類中遇到了同樣的問題。
我正在嘗試存盤的表定義和示例資料以及下面給出的確切存盤內容:
這是我的表定義:
Column name Type Nulls
id serial no
layouttype varchar(32,0) no
name lvarchar(256) no
description lvarchar(512) yes
layoutxml clob no
這是我試圖插入到 CLOB layoutxml 中的資料:
<MediaPropertiesLayout><name>Система</name><description></description><header><entry><showInPopOver/><displayName>Система</displayName><mediaProperty>callVariable1</mediaProperty><uiEditable>false</uiEditable></entry></header><column></column><column></column><uri></uri></MediaPropertiesLayout>
存盤在 layoutxml (CLOB) 中的實際資料
<MediaPropertiesLayout><name>Система</name><description></description><header><entry><showInPopOver/><displayName>Система</displayName><mediaProperty>callVariable1</mediaProperty><uiEditable>false</uiEditable></entry></header><column></column><column></column><uri>
即關閉標簽uri和 MediaPropertiesLayout被截斷。這將根據我使用的 UTF-8 字符而有所不同。如果我使用更大的字串而不是“Система”,那么截斷將在不同的地方。
任何指標都會有很大幫助。
uj5u.com熱心網友回復:
您確定要傳遞正確的 UTF8 值嗎?通常當你被截斷是因為編碼錯誤。
我嘗試使用一個簡單的 Java 控制臺應用程式插入 UTF8 字串 'Fü?e' (46 C3BC C39F 65),它的行為符合預期。
D:\Infx\ids1410>chcp 65001
Active code page: 65001
D:\Infx\ids1410>java com.informix.jdbc.Version
IBM Informix JDBC Driver Version 3.50.JC9X3
D:\Infx\ids1410>javac -encoding utf8 clob.java
D:\Infx\ids1410>od -tcx1 clob.txt
0000000000 F e
46 C3 BC C3 9F 65
0000000006
D:\Infx\ids1410>java -Dfile.encoding=UTF-8 clob
--Fü?e--Fü?e--
D:\Infx\ids1410>oncheck -pp utf8:t1 256
addr stamp chksum nslots flag type frptr frcnt next prev
2:4566 36224780 acf0 1 1 DATA 106 3982 0 0
slot ptr len flg
1 24 82 0
slot 1:
0: 6 46 c3 bc c3 9f 65 0 0 0 1 0 0 0 d9 c8 .FC<C.e.......YH
16: b7 a6 3 0 0 0 3 0 0 0 3 0 0 0 a1 f8 7&............!x
32: 10 61 0 0 0 0 1 0 0 0 0 0 0 0 0 0 .a..............
48: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ................
64: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ................
80: 0 0 ................
D:\Infx\ids1410>dbaccess utf8 -
Database selected.
> unload to t1.unl select * from t1;
1 row(s) unloaded.
> !od -x t1.unl
0000000000 C346 C3BC 659F 307C 362C 632C 6F6C 3162
0000000020 3031 2E66 6138 7C31 000A
0000000031
> !cat t1.unl
Fü?e|0,6,clob110f.8a1|
> !od -x clob110f.8a1
0000000000 C346 C3BC 659F
0000000006
> !cat clob110f.8a1
Fü?e>
>
我手頭沒有 3.50.JC9,但 3.50.JC8 和 3.50.JC9X3 做了同樣的事情,所以我確信“原版”3.50.JC9 也能用。
也許你可以用你的 xml 資料嘗試控制臺應用程式(確保它是 UTF8),看看它是否仍然被損壞。
// ----- clob.java -----
import java.sql.*;
import java.io.*;
import com.informix.jdbc.*;
public class clob {
public static void main(String[] args) {
Connection con = null;
try {
InputStreamReader isr = new InputStreamReader( System.in );
BufferedReader stdin = new BufferedReader( isr );
Class.forName("com.informix.jdbc.IfxDriver");
con = DriverManager.getConnection("jdbc:informix-sqli://420ito:9091/utf8:INFORMIXSERVER=ids1410;user=informix;password=mypassw;DB_LOCALE=en_US.utf8;SQLIDEBUG=pp");
System.out.println ("");
Statement stm1 = con.createStatement();
try {
stm1.executeUpdate ("drop table t1;");
} catch (Exception ex) {}
stm1.executeUpdate ("create table t1 (c1 varchar(20), c2 clob);");
PreparedStatement ps = con.prepareStatement("insert into t1 values ('Fü?e',?);");
FileInputStream fis = new FileInputStream("clob.txt");
BufferedInputStream dataStream = new BufferedInputStream(fis);
ps.setAsciiStream(1, dataStream, dataStream.available());
ps.execute();
ps.close();
PreparedStatement ps2 = con.prepareStatement("select * from t1;");
IfxResultSet resultSet = (IfxResultSet) ps2.executeQuery();
while (resultSet.next()) {
System.out.format("--%s--%s--\n",resultSet.getString(1),resultSet.getString(2));
try {
} catch ( Exception ex ) {};
}
resultSet.releaseBlob();
ps2.close();
((IfxSqliConnect) con).releaseBlob();
} catch (Exception ex) {
ex.printStackTrace();
if (ex instanceof SQLException) {
SQLException sqlex = (SQLException) ex;
System.out.println ("Message: " sqlex.getMessage());
}
}
}
}
// ----- clob.java -----
如果它有效,問題可能在于 Hibernate 如何處理該資料。
uj5u.com熱心網友回復:
在 Hibernate 中創建 Clob 仍然存在問題。不知何故,Hibernate 無法根據 UTF-8 字符計算字串長度。當您有這些特殊字符時,您需要layoutXML.getBytes("utf-8").length改為layoutXML.length(). 這種差異實際上導致了截斷。
但是,我一起跳過了整個轉換開銷,只是通過在 POJO 中將 'layoutxml' 宣告為 String 而不是 java.sql.Clob。為此,我將休眠版本升級到 5.6.1.Final。
使用 3.5.2-Final hibernate verison,即使這種方法也不起作用。
注意:在 POJO 中將 CLOB 條目宣告為字串在性能方面有其自身的缺點。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/377627.html
上一篇:創建entityManagerFactory.Unable構建HibernateSessionF.SchemaManagementException時出錯:多次遇到匯出識別符號[new_user]
