2015-03-29 6 views
6

Sto tentando di salvare alcuni valori nel database MySQL utilizzando Hibernate, ma la maggior parte dei caratteri lituani non verrà salvata, incluso ąĄ čČ ęĘ ėĖ įĮ ųŲ ūŪ (vengono salvati come ?), tuttavia , šŠ žŽ si salva.UTF-8 non persisterà su Hibernate + MySQL

Se inserisco manualmente, tali valori vengono salvati correttamente, quindi il problema è molto probabile nella configurazione di Ibernazione.

Quello che ho provato finora:

hibernate.charset=UTF-8 
hibernate.character_encoding=UTF-8 
hibernate.use_unicode=true 

--------- 

properties.put(PROPERTY_NAME_HIBERNATE_USE_UNICODE, 
      env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_USE_UNICODE)); 
    properties.put(PROPERTY_NAME_HIBERNATE_CHARSET, 
      env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CHARSET)); 
    properties 
      .put(PROPERTY_NAME_HIBERNATE_CHARACTER_ENCODING, 
        env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CHARACTER_ENCODING)); 

--------- 

private void registerCharachterEncodingFilter(ServletContext aContext) { 
    CharacterEncodingFilter cef = new CharacterEncodingFilter(); 
    cef.setForceEncoding(true); 
    cef.setEncoding("UTF-8"); 
    aContext.addFilter("charachterEncodingFilter", cef) 
      .addMappingForUrlPatterns(null, true, "/*"); 
} 

Come descritto here

Ho provato ad aggiungere ?useUnicode=true&characterEncoding=utf-8 al db collegamento URL.

Come descritto here

ho assicurato che il mio db è impostato su UTF-8 charset. phpmyadmin > information_schema > schemata

def db_name utf8 utf8_lithuanian_ci NULL 

Questo è come mi Salva nei db:

//Controller 
buildingService.addBuildings(schema.getBuildings()); 
     List<Building> buildings = buildingService.getBuildings(); 
     System.out.println("-----------"); 
     for (Building b : schema.getBuildings()) { 
      System.out.println(b.toString()); 
     } 
     System.out.println("-----------"); 
     for (Building b : buildings) { 
      System.out.println(b.toString()); 
     } 
     System.out.println("-----------"); 

//Service: 
@Override 
public void addBuildings(List<Building> buildings) { 
    for (Building b : buildings) { 
     getCurrentSession().saveOrUpdate(b); 
    } 
} 

Prima serie di println contiene tutti i caratteri della Lituania, mentre il secondo sostituisce la maggior parte con ?

EDIT: Aggiunto dettagli

insert into buildings values (11,'ąĄčČęĘ', 'asda');  
select short, hex(short) from buildings; 
//Šalt. was inserted via hibernate 
//letters are properly displayed: 
ąĄčČęĘ  | C485C484C48DC48CC499C498 
MIF Šalt. | 4D494620C5A0616C742E 

select address, hex(address) from buildings; 
Šaltini? <...> | C5A0616C74696E693F20672E2031412C2056696C6E697573 
//should contain "ų" 
-------- 
show create table buildings; 
buildings | CREATE TABLE `buildings` (
    `id` int(11) NOT NULL, 
    `short` varchar(255) COLLATE utf8_lithuanian_ci DEFAULT NULL, 
    `address` varchar(255) COLLATE utf8_lithuanian_ci DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_lithuanian_ci 

MODIFICA: Non l'ho fatto trovare una soluzione adeguata, quindi ho trovato una soluzione alternativa. Ho finito per sfuggire/caratteri di escape, archiviandoli in questo modo: \uXXXX.

+0

Questo non sembra essere il vostro problema specifico, ma abbiamo avuto un problema simile in cui uno script Ant-build stava eseguendo un'attività sql e aveva come impostazione predefinita lo schema di codifica del computer host, che era cp1252 su Windows Server 2008. Anche se il resto della nostra configurazione durante tutto il processo ha specificato UTF-8, questo script di build è stato predefinito a cp1252 quando è stato eseguito sulla macchina di produzione (ma non in ambienti dev). Super misterioso finché non abbiamo capito cosa stava succedendo. –

risposta

3

Verificare che siano stati memorizzati correttamente ... Si prega di fare SELECT col, HEX(col) ... per recuperare alcune celle con caratteri lituani. Un file registrato correttamente ą mostrerà C485. Gli altri dovrebbero mostrare vari valori esadecimali di C4xx o C5xx. 3F è ?.

Ma, cosa più importante, 4 caratteri mostrano. Šdovrebbe essere C5A0 se correttamente memorizzato come utf8. Tuttavia, ho il sospetto, vedrete 8A, implicando che la colonna nella tabella è dichiarata in realtà come CHARACTER SET latin1. (I 4 caratteri vengono visualizzati nella prima colonna di my charset blog).

Do SHOW CREATE TABLE per vedere come è definita la colonna. Se dice latin1, il problema è con la definizione della tabella e probabilmente dovresti ricominciare da capo.

+0

Aggiunte le informazioni richieste. – Marius

+0

Latin Small Letter U con Ogonek (ø) dovrebbe avere l'esadecimale C5B3, quindi avrebbe dovuto essere uguale alle altre lettere con ogoneks. –

+2

L'esagono che ha fatto, sembra corretto caratteri lituani. Sospetto che il ø sia stato inserito qualche tempo fa, quando avevi configurato _qualcosa in modo diverso. (Si noti che Š è venuto attraverso.) È stato 'inserire nei valori di edifici (11, 'ąĄčČęĘ', 'asda');' fatto attraverso Hibernate? Sembra che sia stato memorizzato correttamente. –

0

È necessario assicurarsi che ogni componente che partecipa all'immissione dei dati utilizzi la codifica UTF-8 in modo esplicito.

  • Se si immettono i valori tramite il browser, assicurarsi che la pagina visualizzazione dei risultati con la seguente intestazione Content-Type: text/html; charset=utf-8.

  • Il modulo di ingresso è definito come segue

    <form action="submit" accept-charset="UTF-8">...</form>.

  • Se si sta creando String oggetti da array di byte, assicuratevi di indicare esplicitamente il Charset nel costruttore.

  • Se l'inserimento avviene da un file di testo, il file deve essere UTF-8 codificato.

  • Se è codificato direttamente nel codice, allora la sorgente deve essere UTF-8 codificati.

0

Il fatto che il DB abbia il corretto UTF-8 (due o più byte per una lettera speciale) è rassicurante.

Se si ottiene un singolo ? per una lettera speciale, si è tentato di eseguire una conversione UTF-8 in alcune codifiche che non contengono tali lettere. E sembra essere il caso. Le lettere che sono convertite correttamente sono nella gamma ISO-8859-1 o Windows-1252. Gli altri no. Ora ISO-88591-1 ovvero Latin-1 è la codifica HTTP predefinita, predefinita nel server EE java. Come si potrebbe fare prima di scrivere:

response.setCharacterEncoding("UTF-8"); 

Ora un problema con System.out.println è che utilizza la codifica di default del sistema. La registrazione su un file con un registratore è più interessante. O eseguire il debug e l'ispezione della stringa e del suo array di caratteri.

Che lo schema funzioni apparentemente, può essere che le stringhe dello schema derivano immediatamente da una sorgente Java e la codifica dell'editor e la codifica del compilatore javac differiscono. Questo può essere verificato inviando il valore letterale stringa in java: "\u0105" anziché "ą".

Eseguire un test unità che scrive e legge dal database.