TOPIC: SQLServer case-sensitive - JPA Table import Bug
9 months 6 days ago #603
Hallo zusammen,
in der aktuellen Version von RapidClipse hab ich nun das Problem, dass Hibernate Entwickler eine inkonsiquente Programmierung zugelassen haben.
Beim Import von Tabellen aus meiner SQL Server DB, die aus bestimmten Gründen case-sensitive angelegt wurde, kommt eine Exception:

com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'INFORMATION_SCHEMA.Columns'.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:404)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:350)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:180)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:155)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:285)
at org.hibernate.cfg.reveng.dialect.SQLServerMetaDataDialect.getSuggestedPrimaryKeyStrategyName(SQLServerMetaDataDialect.java:36)

ich habe im hibernate SourceCode nachgeschaut und da gibt es einen Statement, der sich auf die System Tabellen zugreift um Tabelleninformationen rauszulesen und in diesem STatement greift es auf 3 Tabellen (genauergenommen sind es System.Views), 2 davon schreiben sie groß aus (INFORMATION_SCHEMA.KEY_COLUMN_USAGE, INFORMATION_SCHEMA.TABLE_CONSTRAINTS) , so wie es auch in SQLSERVER Datenbank immer ist und eine (INFORMATION_SCHEMA.Columns) warum auch immer klein!
Hier der link zum SorceCode hibernate
Dadurch kann man in der aktuellen Version bzw aktuellen Framework Snapshot die Tabellen als Entities aus einer case-sensitiven SQL Server DB nicht importieren! :-((((((((
Das hat mir TAge gekostet und ich weiß grad nicht, was ich machen soll. Wieder zurück zu der RapidClipse 2.3 oder gibt es eine andere Lösung für mich...
Last Edit: 9 months 6 days ago by jonnybl.
The topic has been locked.
9 months 4 days ago #610
Hallo jonnybl,

wir werden das genauer untersuchen und für die Version 3 eine Lösung erarbeiten. Für den Moment würden wir empfehlen tatsächlich auf die Version 2.3.1 umzusteigen. Die Finale Version 3 von RapidClipse nähert sich mit großen Schritten und es wird mit Sicherheit eine Lösung dafür geben.

Euer RapidClipse Team
The topic has been locked.
9 months 3 days ago #622

Hallo jonnybl,

Der Fehler entsteht tatsächlich durch das SQL-Statement in der genannten Klasse.
Beim Ausführen des Statements gibt die Datenbank einen Fehler zurück, wenn die Collation("Sortierung") der SQL Server-Datenbank "case-sensitive" ist.
(wie z.B. "Latin1_General_Bin" -> "case-sensitive", dagegen ist alles mit "_CI_" im Namen "case-insensitive" )

Workaround
Ein Workaround wäre eine eigene Metadata-Dialekt-Klasse zu erstellen, die ebenfalls vom JDBCMetaDataDialect erbt, und diese dann beim Import zu benutzen
Dort kann das fehlerhafte SQL-Statement mit korrektem Statement ersetzt werden.

Dazu müsste folgendes durchgeführt werden:

1. Eine weitere Dependency zur pom.xml hinzufügen, um Zugriff auf die Elternklasse ("JDBCMetaDataDialect") zu bekommen
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-tools</artifactId>
                <version>5.1.0.Final</version>
            </dependency>

2. Eine neue Klasse erzeugen, die von "JDBCMetaDataDialect" erbt, z.B.

public class NameMeinesNeuenDialekts extends JDBCMetaDataDialect { [...]

Der Inhalt dieser Klasse entspricht genau dem der ursprünglichen Klasse "SQLServerMetaDataDialect", (einfach den Inhalt kopieren)
bis auf die Änderung im SQL-Statement:
Original:
sql = "SELECT a.TABLE_CATALOG, a.TABLE_SCHEMA, a.TABLE_NAME as table_name, c.DATA_TYPE as data_type, b.CONSTRAINT_TYPE,  OBJECTPROPERTY(OBJECT_ID(a.TABLE_NAME),'TableHasIdentity') as hasIdentity " + 
      "FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE a " + 
      "INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS b on a.CONSTRAINT_NAME = b.CONSTRAINT_NAME " + 
      "INNER JOIN INFORMATION_SCHEMA.Columns c on a.TABLE_CATALOG = c.TABLE_CATALOG AND a.TABLE_SCHEMA = c.TABLE_SCHEMA AND a.TABLE_NAME = c.TABLE_NAME AND a.COLUMN_NAME = c.COLUMN_NAME " + 
      "WHERE a.TABLE_NAME='"+table+"' AND a.TABLE_SCHEMA='"+schema+"' AND a.TABLE_CATALOG='"+catalog+"' AND b.CONSTRAINT_TYPE = 'Primary key'"; 
Verändert:
sql = "SELECT a.TABLE_CATALOG, a.TABLE_SCHEMA, a.TABLE_NAME as table_name, c.DATA_TYPE as data_type, b.CONSTRAINT_TYPE,  OBJECTPROPERTY(OBJECT_ID(a.TABLE_NAME),'TableHasIdentity') as hasIdentity " + 
      "FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE a " + 
      "INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS b on a.CONSTRAINT_NAME = b.CONSTRAINT_NAME " + 
      "INNER JOIN INFORMATION_SCHEMA.COLUMNS c on a.TABLE_CATALOG = c.TABLE_CATALOG AND a.TABLE_SCHEMA = c.TABLE_SCHEMA AND a.TABLE_NAME = c.TABLE_NAME AND a.COLUMN_NAME = c.COLUMN_NAME " + 
      "WHERE a.TABLE_NAME='"+table+"' AND a.TABLE_SCHEMA='"+schema+"' AND a.TABLE_CATALOG='"+catalog+"' AND b.CONSTRAINT_TYPE = 'Primary key'"; 

Um diese Klasse dann beim Table Import zu benutzen , muss dann noch folgendes durchgeführt werden:

3. Eine "hibernate.properties" - Datei im Ordner "<Projektname>\src\META-INF" erstellen, mit folgendem Inhalt:
[/code]

hibernatetool.metadatadialect=com.company.<Projektname>.business.<NameMeinesNeuenDialekts>

Der Teil "com.company.<Projektname>.business.<NameMeinesNeuenDialekts>" muss gegebenenfalls mit dem Pfad und Namen der unter 2.) erstellten Klasse ersetzt werden.

4. in der Datei "<Projektname>.hibernate.launch" im Ordner "<Projektname>/launcher/" des Projekts folgende Zeile hinzufügen (und an das Projekt angepassen):
[/code]

<stringAttribute key="org.hibernate.eclipse.launch.PROPERTY_FILE" value="\<Projektname>\src\META-INF\hibernate.properties"/>



Die Werte in "<>" müssen je nach Projektname noch angepasst werden.

Euer RapidClipse Team
Last Edit: 9 months 3 days ago by RapidClipse Team.
The topic has been locked.
8 months 4 weeks ago #628
"You're simply the best, and don't know the rest..." !!
Jungs, gute Arbeit, weiter so!
Es hat funktioniert genau wie von euch beschrieben und das macht Bock weiter zu entwickeln!
Ableiten und Bugs lokal überschreiben - hab ich in anderen Kontexten als Workaround schon gemacht - aber die Maven und Hibernate Kenntnisse haben an der Stelle gefehlt, dieses Workaround allein hinzukriegen.

a lot of thx!
The topic has been locked.