2016-05-25 20 views
0

ich die folgende Fehlermeldung von einem Java/Frühjahr/Hibernate-Anwendung empfängt, wenn es eine vorbereitete Anweisung für eine MySQL-Datenbank auszuführen versucht:Woher kommt die Kollatierung "latin1_german1_ci"?

Caused by: java.sql.SQLException: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin1_german1_ci,COERCIBLE) for operation '=' 

Die select-Anweisung, die diese erzeugt (wie in der tomcat gezeigt log) ist:

SELECT s.* FROM score_items s where 
s.s_score_id_l=299 and 
(s.p_is_plu_b = 'F') and 
isTestProduct(s.p_upc_st) = 'N' and 
v_is_complete_b='T' 
order by s.nc_name_st, s.p_upc_st 

die Tabelle Sortierungs pro dem show table status Befehl lautet:

utf8_general_ci 

Die Sortierung für alle Felder char, varchar und text lautet "utf8_general_ci". Es ist null für die Bigint-, Int- und Datetime-Felder.

Die Datenbankkollatierungs sind latin1_swedish_ci wie durch den Befehl angezeigt:

show variables like "collation_database"; 

Edit: mit Eclipse/STS und Tomcat 6 Instanz ich in der Lage war erfolgreich dies von meinem lokalen Rechner laufen zu lassen. Der lokale Prozess liest die Daten aus derselben Datenbank wie der Prozess auf dem Produktionsserver, der den Fehler verursacht hat. Der Server, auf dem der Fehler auftritt, ist eine Tomcat 7.-Instanz ist ein Amazon Linux-Server.

Edit 2: Ich konnte den Bericht auch erfolgreich ausführen, wenn ich ihn aus unserer QA-Umgebung ausführte. Die JDBC-Anweisung in server.xml wurde auf die Produktionsdatenbank zurückgesetzt. QA ist im Wesentlichen ein Spiegel der Produktionsumgebung, mit einigen Entwicklerarbeiten. Ich sollte auch bemerken, dass ich letzten Monat einen ähnlichen Fehler gesehen habe, aber er verschwand, als ich den Bericht erneut verfasste. Schließlich bin ich nicht sicher, warum es einen Unterschied machen würde, aber der abgefragte Tisch ist riesig, mit über 7 Millionen Zeilen und wahrscheinlich 100 Feldern pro Zeile.

Edit 3: Basierend auf Shadows Kommentaren entdeckte ich, dass der Zeichensatz "latin1" in der Testfunktion angegeben wurde. Ich habe das zu utf8 geändert und hoffe, dass dies das Problem löst.

Wie finde ich heraus, welches Feld "latin1_german1_ci" ist?

Warum ist der Vergleich „latin1_swedish_ci“, wenn die Tabelle und Felder sind entweder "utf8_general_ci oder null?

könnte das Problem im Zusammenhang Zeichensatz funktionieren verwenden, und wenn ja, wie kann ich feststellen, welchen Zeichensatz/Sortier ist es mit?

Wie ich welches Feld einzuengen tun/Funktion das Problem verursacht?

Antwort

1

das hat nichts mit Java zu tun hat oder Ruhezustand, diese rein nach unten zu mysql ist und vielleicht zu der Verbindungszeichenfolge.

In mysql Sie Zeichensatz und Sortierung auf mehreren Ebenen definieren, was eine Menge Probleme verursachen können:

  • Server
  • Datenbank
  • Tabelle
  • Spalte
  • Verbindung

Siehe mysql-Dokumentation unter character sets and collations für weitere Details.

Zusammenfassend: die Standardwerte der höheren Ebene treten genau dann in Kraft, wenn Sie auf niedrigerer Ebene keine Zeichensatz oder Sortierung angeben. Daher überschreibt eine Definition auf Spaltenebene eine Definition auf Tabellenebene. Der Befehl show table status zeigt die Standardwerte auf Tabellenebene an, die jedoch möglicherweise auf Spaltenebene überschrieben wurden. show full columns oder show create table Befehle zeigen Ihnen die wahren Zeichensätze und Sortierfolgen, die von einem bestimmten Feld verwendet werden.

Zeichensatz-/Kollatierungsdefinitionen auf Verbindungsebene komplizieren das Bild weiter, da die in den SQL-Anweisungen verwendeten Zeichenfolgenkonstanten den Verbindungszeichensatz/die Kollation verwenden, sofern sie nicht explizit deklariert sind.

Allerdings verwendet mysql Koeffizienten, um die meisten Probleme zu vermeiden, die sich aus der Verwendung verschiedener Zeichensätze und Ausdrücke ergeben, wie in der mysql-Dokumentation unter character sets/collations used in expressions beschrieben.

Von Ihnen erwähnen, dass die Abfrage funktioniert, wenn von einem anderen Computer ausgeführt wird, zeigt an, dass das Problem mit dem Verbindungszeichensatz/Kollation ist. Ich denke, es wird um den Aufruf von isTestProduct() sein.

Die einzige Möglichkeit, wirklich zu bestimmen, welcher Zustand den Fehler verursacht, besteht darin, die Bedingungen einzeln zu beseitigen, und wenn der Fehler verschwunden ist, war der letzte beseitigte Zustand der Täter. Die Definition eines geeigneten Verbindungszeichensatzes und einer Sortierung, die mit den in den Feldern verwendeten übereinstimmen, wird jedoch ebenfalls hilfreich sein.

+0

Danke, das ist eine sehr gute Info. Ich arbeite immer noch daran. Es ist sehr seltsam, dass es sowohl von meiner Maschine als auch von der QA-Umgebung funktioniert, wenn es auf die Prod-db gerichtet ist (siehe meine zweite Bearbeitung oben). –

+0

Deshalb glaube ich, dass das Problem mit der Verbindungskollation ist. Sie können es in der Verbindungszeichenfolge angeben. – Shadow

+0

Ich gab endlich den Geist auf und startete die App neu und es funktionierte. Ich habe keine Idee warum. Vielen Dank! –