MSSQL - JPA - Кодировка символов для специальных символов - добавление NativeQuery

Я использую Spring 4.3.1 с JPA 2.0 и подключен к MSSQL. Я использую метод сохранения JpaRepository для вставки и обновления данных. В одном из полей есть nvarchar, который может содержать специальные символы, такие как латиница, китайский.

Кроме того, я установил ниже свойства JPA в applicationContext-hibernate.xml.

            <prop key="hibernate.connection.CharSet">UTF-8</prop>
            <prop key="hibernate.connection.useUnicode">true</prop>
            <prop key="hibernate.connection.characterEncoding">UTF-8</prop>

Когда я сохраняю данные, все специальные символы сохраняются как вопросительные знаки (??). Предлагаемое решение состояло в том, чтобы добавить «N» перед запросом на обновление, чтобы сохранить вставленные специальные символы. Однако я нигде не вижу, как добавить «N» в метод сохранения JpaRepository. Какие-либо предложения?


person Kanag raj    schedule 03.01.2018    source источник
comment
Может помочь использовать UTF16? Тип данных SQL-Server VARCHAR не UTF-8, а своего рода расширенный ASCII (в зависимости от COLLATION). И обязательно используйте столбец NVARCHAR в качестве цели. Если вы сохраните это в столбце VARCHAR, вы также получите вопросительные знаки.   -  person Shnugo    schedule 04.01.2018
comment
если я перейду на UTF16, это повлияет и на другие поля? Я попробую это. Есть ли способ в JPA указать в запросе, что во время сохранения добавляется N перед данными?   -  person Kanag raj    schedule 04.01.2018
comment
SQL Server вообще не поддерживает UTF-8 (ну, последняя версия поддерживает UTF-8, но только для BULK нагрузок...). Любая строка, которую вы отправляете на SQL-Server, будет воспринята либо как 1-byte-encoded-extended-ASCII (VARCHAR), либо как 2-byte-enocded unicode / UTF-16 / UCS-2 (NVARCHAR). Какой бы язык или инструмент вы ни использовали для связи с SQL-Server, лучше всего использовать 2-byte-unicode   -  person Shnugo    schedule 04.01.2018
comment
хм. спасибо .. значит ли это, что объявление переменной в pojo, как показано ниже, не имеет никакого эффекта? Column(name=[CD Hours of Operation], columnDefinition = nvarchar) Должен ли я явно преобразовывать строку в 2-байтовый юникод?   -  person Kanag raj    schedule 04.01.2018
comment
Извините, этого я не знаю... Но в любом случае вы должны передавать это как 2-byte-unicode, а не как UTF-8   -  person Shnugo    schedule 04.01.2018


Ответы (2)


Объявите поле как массив byte[], как показано ниже.

@Column(name="[colName]", columnDefinition = "nvarchar", length=4000)
    private byte[] colName;

и при отображении вам нужно преобразовать byte[] в String с использованием UTF-16, как показано ниже. Из БД (сопоставление):

byte[] eCodeData = dbData.getColName();
            if(eCodeData != null){
                uiData.setColName(new String(eCodeData, StandardCharsets.UTF_16));
            }

to DB:

String eCodeData = uiData.getColName();
        if(eCodeData != null){
            dbData.setColName(eCodeData.getBytes(StandardCharsets.UTF_16)); 
        }

Это оно. Это совершит волшебство.

person Kanag raj    schedule 09.01.2018

На самом деле не нужно определять массив byte[] для поля, но

@Column(columnDefinition = "nvarchar(255)")
private String colName;

Достаточно.

person WeiJie He    schedule 28.03.2018