HibernateのソースコードとPostgreSQLJDBCドライバーを何度も調べた後、問題の根本的な原因を見つけることができました。最後に、BlobOutputStream(JDBCドライバーによって提供される)のwrite()メソッドが呼び出され、Clobの内容がデータベースに書き込まれます。このメソッドは次のようになります:
public void write(int b) throws java.io.IOException
{
checkClosed();
try
{
if (bpos >= bsize)
{
lo.write(buf);
bpos = 0;
}
buf[bpos++] = (byte)b;
}
catch (SQLException se)
{
throw new IOException(se.toString());
}
}
このメソッドは、引数として「int」(32ビット/ 4バイト)を取り、それを「バイト」(8ビット/ 1バイト)に変換して、事実上3バイトの情報を失います。 Java内の文字列表現はUTF-16でエンコードされています。つまり、各文字は16ビット/2バイトで表されます。ユーロ記号のint値は8364です。バイトに変換した後、値172が残ります(オクテット表現254)。
この問題に対する現在の最善の解決策が何であるかはわかりません。 IMHO JDBCドライバーは、データベースが必要とするエンコードにJavaUTF-16文字をエンコード/デコードする責任があります。ただし、JDBCドライバーコードにその動作を変更するための微調整の可能性は見当たりません(そして、独自のJDBCドライバーコードを記述して維持したくありません)。
したがって、カスタムClobTypeを使用してHibernateを拡張し、データベースに書き込む前にUTF-16文字をUTF-8に変換し、Clobを取得するときにその逆を行うことができました。
解決策は大きすぎて、この回答に単純に貼り付けることはできません。興味のある方は、私に連絡してください。お送りします。
乾杯、フランク