java
  • postgresql
  • jdbc
  • unicode
  • 2014-12-04 1 views 1 likes 
    1

    응용 프로그램을 통해 삽입이 발생하면 모든 유니 코드 문자 (일본어, 그리스어 등)가 물음표로 바뀝니다.PostgreSQL이 유니 코드 문자 대신 물음표를 삽입합니다.

    SAVEPOINT "DAO" 
    LOG: execute <unnamed>: insert into foo values ($1,$2,$3) 
    DETAIL: parameters: $1 = '23', $2 = '34bcb5f2-e7ee-40cf-9103-f2d1bf2ac7acd853d7c6-1703-44d2-aa99-6fd1df84da37', $3 = 'Anyone-日本語_l' 
    

    위의 로그 항목에서 알 수 있듯이 데이터베이스는 올바른 유니 코드 매개 변수를 허용합니다.

    그러나, 삽입 후, 테이블 항목은 다음과 같습니다

    23 | 34bcb5f2-e7ee-40cf-9103-f2d1bf2ac7acd853d7c6-1703-44d2-aa99-6fd1df84da37 | Anyone-???_l 
    

    내 첫번째 추측이 데이터베이스 구성 문제라고했다, 그러나 나는 확인했다 그 (본인이 아는에) 포스트 그레스 실제로 행하여 UTF-8을 받아들이고 다음

    : I는 상기 수동으로 데이터베이스에 엔트리를 삽입하여이를 cornfirmed 한

    SHOW server_encoding; 
    server_encoding 
    ----------------- 
    UTF8 
    (1 row) 
    
    SHOW client_encoding; 
    client_encoding 
    ----------------- 
    UTF8 
    (1 row) 
    

    위에서 알 수 있듯이 데이터베이스가 내 값을 받아들이고 데이터베이스에 유니 코드 문자를 성공적으로 추가했습니다.

    이 시점에서이 값은 응용 프로그램에서 JDBC 커넥터와 데이터베이스로 푸시 될 때 발생한다고 생각합니다. 아마 JDBC 커넥터가 유니 코드 데이터를 전송할 것이라고 말해야한다고 생각했습니다. 이 작업을 수행 할 수있는 방법은은 JDBC 커넥터의 URL에 다음을 추가하여, 실제로있다 :

    jdbc:postgresql://localhost/bar?useUnicode=yes&characterEncoding=UTF-8 
    

    불행하게도, 위에서 어떤 차이를하지 않았다.

    매우 큰 프로젝트의 일부이며 관련된 조각들이 여기 저기에 파편화되어있어 응용 프로그램의 코드를 제외 시켰습니다. 그러나 Postgres 로그가받은 매개 변수를 명확하게 표시하기 때문에 문제와 관련이 없다고 생각합니다.

    데이터베이스에서 수신 한 쿼리와 유니 코드 데이터가 정확하므로이 문제의 원인은 무엇입니까? 데이터베이스는 참으로 기대하고있다

    OS: RHEL 6.6 
    Postgres version: 9.3.5 
    JDBC Connector: Tried a couple (8.1, 9.3) 
    JRE: 1.7 
    

    는 UTF-8 :

    SELECT foo_name::bytea FROM foo; 
    
    foo_name 
    -------------------------- 
    \x416e796f6e652d3f3f3f5f6c 
    

    질문 :

    psql -U postgres -h localhost --list 
    
    Name  | Owner | Encoding | Collate | Ctype | Access privileges 
    ----------------+----------+----------+-------------+-------------+-------------- 
    bar  | postgres | UTF8  | en_US.UTF-8 | en_US.UTF-8 | 
    

    관련 항목의 bytea와 결과는 다음과 같다 엄마 RKS는 실제로 데이터베이스에 삽입되었습니다

    SELECT * FROM foo WHERE foo_name LIKE 'Anyone-?%' 
    23 | 34bcb5f2-e7ee-40cf-9103-f2d1bf2ac7acd853d7c6-1703-44d2-aa99-6fd1df84da37 | Anyone-???_l 
    

    나는 또한이 PGStream에 공급되기 전에 JDBC 컨트롤러에 의해 생성 된 내 테스트 중 하나의 바이트 시퀀스를 잡고있다.

    {65, 110, 121, 111, 110, 101, 45, -26, -105, -91, -26, -100, -84, -24, -86, -98, 95, 105} 
    

    내가 수행하여 UTF-8 문자열이 변환 한 (독립 실행 형 응용 프로그램에서) 다음

    String result = new String(bytes, StandardCharsets.UTF_8); 
    

    결과는 정확 하나 : Anyone- 日本語 _ i

    +2

    그냥 기록과'characterEncoding = UTF-8' 연결 매개 변수가 yes'을 useUnicode을 할 ='에 대한 모든 JDBC 드라이버에는 적용되지 않습니다. 이것들은 MySQL Connector/J에만 해당하며 [PostgreSQL JDBC 드라이버의 연결 매개 변수] (http://jdbc.postgresql.org/documentation/93/connect.html#connection-parameters) 목록에 나타나지 않습니다. . –

    +1

    OS 명령 행에서'psql -U postgres -h localhost --list'를 실행하여 데이터베이스를 나열하고 문제의 실제 데이터베이스의'인코딩 '을 확인하십시오. * 서버 *의 (기본) 인코딩이 'UTF8'이지만 * 데이터베이스 *가 다른 인코딩을 가지고있을 가능성이 있음을 확인했습니다. –

    +2

    'table에서 column_with_dubious_text :: bytea를 선택하십시오 '를 실행하여 실제 바이트가 예상 utf-8 표현인지 여부를 확인하십시오. 문제에 따라 사전 삽입 또는 삽입 후인지 알 수 있습니다. –

    답변

    3

    레거시 코드를 자세히 조사한 결과 문제가 발견되어 해결되었습니다.

    데이터베이스 계층은 정상적으로 작동했습니다. 시스템이 ByteArrayInputStream을 사용하여 데이터베이스에 동일한 값을 다시 삽입하려고 시도 할 때 문제가 발생했습니다.

    foo_name이 포함 된 문자열에서 getBytes()을 수행하면 ByteArrayInputStream이 채워집니다. 그러나이 메소드를 호출 할 때 UTF-8 인코딩을 정의해야합니다. 변경함으로써

    :

    String name = "日本語"; 
    InputStream is = new ByteArrayInputStream(name.getBytes()); 
    

    행 :

    String name = "日本語"; 
    InputStream is = new ByteArrayInputStream(name.getBytes(StandardCharsets.UTF_8)); 
    

    문제가 해결되었다.

    1

    나는 postgres와 glassfish와 함께 unicode-8에 문제가있었습니다. persistence.xml에서 이것을 시도해 보았습니다. 나는 당신에게 도움이 될 수 있기를 바랍니다

    <properties> 
        <property name="javax.persistence.jdbc.url" 
          value="jdbc:postgresql://(url_Project)?useUnicode=yes"/> 
    </properties> 
    

    (url_Proyecto)는 데이터베이스의 전체 URL입니다

    관련 문제