PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Nie można przechowywać znaku Euro we właściwości LOB String za pomocą Hibernate/PostgreSQL

Po długim grzebaniu w kodzie źródłowym Hibernate i sterowniku PostgreSQL JDBC udało mi się znaleźć przyczynę problemu. Na koniec wywoływana jest metoda write() BlobOutputStream (dostarczana przez sterownik JDBC) w celu zapisania zawartości Cloba w bazie danych. Ta metoda wygląda tak:

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());
    }
}

Ta metoda przyjmuje argument „int” (32 bity/4 bajty) i konwertuje go na „bajt” (8 bitów/1 bajt), skutecznie tracąc 3 bajty informacji. Reprezentacje łańcuchowe w Javie są zakodowane w UTF-16, co oznacza, że ​​każdy znak jest reprezentowany przez 16 bitów/2 bajty. Znak Euro ma wartość int 8364. Po konwersji na bajt pozostaje wartość 172 (w reprezentacji oktetu 254).

Nie jestem pewien, jakie jest teraz najlepsze rozwiązanie tego problemu. IMHO sterownik JDBC powinien być odpowiedzialny za kodowanie/dekodowanie znaków Java UTF-16 do dowolnego kodowania wymaganego przez bazę danych. Jednak nie widzę żadnych możliwości ulepszeń w kodzie sterownika JDBC, aby zmienić jego zachowanie (i nie chcę pisać i utrzymywać własnego kodu sterownika JDBC).

Dlatego rozszerzyłem Hibernate o niestandardowy ClobType i udało mi się przekonwertować znaki UTF-16 na UTF-8 przed zapisaniem do bazy danych i odwrotnie podczas pobierania Clob.

Rozwiązania są zbyt duże, aby po prostu wkleić je w tej odpowiedzi. Jeśli jesteś zainteresowany, napisz do mnie, a ja wyślę ci to.

Pozdrawiam, Frank




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Laravel elokwentny - czy istnieje sposób na dodanie podpowiedzi przed SELECT?

  2. Jak mogę sprawdzić ciąg znaków Unicode w Pythonie, aby zobaczyć, że *w rzeczywistości* jest prawidłowym kodem Unicode?

  3. Tabela przestawna dla danych na godzinę

  4. Napisz ramkę danych Spark do bazy danych postgres

  5. Rails 5 form_for z tablicą checkbox