Search the FirstSpirit Knowledge Base
Hallo Leute!
TL;DR Hat jemand Erfahrung mit der Anbindung von nicht-unterstützten exotischen Datebanken? Ist es möglich, einen proprietären JDBC-Treiber zu nutzen oder muss man auf das App-Center und eine selbstgebaute Anwendung umsteigen?
Wir wollen eine existierende Datenbank (AS400 von IBM) an unser FirstSpirit anbinden. Den Treiber com.ibm.as400.access.AS400JDBCDriver haben wir in den /lib-Ordner gelegt und die JDBC-Konfiguration haben wir mit einer URL (jdbc:as400://DATENBANK;database name=HAV3;libraries=SCHEMA) angelegt.
Wenn wir das existierende Schema mit "Schema aus Datenbank erzeugen" importieren, erscheinen auch alle Tabellen inklusive Primary Keys in der grafischen Übersicht. Sobald wir aber den Bearbeitungsmodus beenden, scheint FirstSpirit die Primary Keys zu vergessen. Bei der Erstellung von Abfragen kommt dann immer die Fehlermeldung: "XXX has no key". Meine Vermutung ist, dass das an dem SQL-Dialekt der AS400 liegt bzw an deren Verwendung von Primary Keys.
Nach dem Lesen der Javadocs habe ich ein paar Packages gefunden, die interessant klingen:
In diesen Packages gibt es z.B. das Interface SQLBuilder
und ein paar Implementierungen für Mysql/DB2/usw.
Jetzt stellt sich für mich die Frage, ob wir die Anbindung an unsere nicht offiziell unterstützte Datenbank anhand dieser Packages selbst implementieren können oder ob es überhaupt nicht möglich ist, eine andere Datenbank anzusprechen? Oder sollten wir das App-Center nutzen und unsere Datenbank-Schnittstelle selbst implementieren?
FirstSpirit benutzt zwar intern ein Abstraktions-Layer für den Zugriff auf verschiedene Datenbanksysteme (das sind die Packages, die du gefunden hast), das ist aber keine offizielle API für eigene Erweiterungen.
Kannst du deine genutzten Layerinformationen vollständig posten und die komplette Fehlermeldung?
Meinst Du mit Layerinformation die Einstellungen für die JDBC?
jdbc.DRIVER=com.ibm.as400.access.AS400JDBCDriver
jdbc.PASSWORD=passwordhere
jdbc.SCHEMA=PNC2C
jdbc.URL=jdbc:as400://host;database name=HAV3;libraries=foo,*LIBL;errors=full;date format=iso;time format=iso
jdbc.USER=usernamehere
jdbc.layerclass=de.espirit.or.impl.db2.DB2Layer
Ich hab einfach die jdbc.layerclass der DB2 verwendet, da mir keine bessere Auswahl aufgefallen ist.
Hier ist die Fehlermeldung beim Erstellen einer Abfrage:
USERNAME, session: 7988740394534721374, project: 314367, ip: 127.0.0.1
Error (de.espirit.firstspirit.client.AWTDispatchingEventQueue): Error during dispatching of java.awt.event.MouseEvent[MOUSE_RELEASED,(590,150),absolute(2262,142),button=1,modifiers=Button1,clickCount=1] on frame0
FSVersion=4.2.432.43881#2516;JDK=1.7.0_02 64bit Oracle Corporation;OS=Windows 7 6.1 amd64;Date=22.05.2012 11:18:05
java.lang.IllegalStateException: Designation has no key
at de.espirit.or.impl.generic.SelectBuilder.getColumnClause(SelectBuilder.java:200)
at de.espirit.or.impl.AbstractSessionHandler.createStatement(AbstractSessionHandler.java:867)
at de.espirit.or.impl.AbstractSessionHandler.executeQuery(AbstractSessionHandler.java:689)
at de.espirit.or.impl.AbstractSessionHandler.executeQuery(AbstractSessionHandler.java:229)
at de.espirit.firstspirit.content.ContentManagerImpl.executeQuery(ContentManagerImpl.java:501)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at de.espirit.firstspirit.io.DefaultServerHandler.callManager(DefaultServerHandler.java:62)
at de.espirit.firstspirit.server.io.handler.ManagerCall.doCall(ManagerCall.java:91)
at de.espirit.firstspirit.server.io.handler.CompactCall.handle(CompactCall.java:67)
at de.espirit.firstspirit.server.io.ManagerCallWorker.run(ManagerCallWorker.java:108)
at de.espirit.firstspirit.server.ExecutionManagerImpl$RunnableWrapper.call(ExecutionManagerImpl.java:553)
at de.espirit.firstspirit.server.ExecutionManagerImpl$ExtendedCallable.call(ExecutionManagerImpl.java:520)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at de.espirit.common.util.BoundedExecutorService$RunnableWrapper.run(BoundedExecutorService.java:419)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at de.espirit.firstspirit.client.io.ServerCaller.callManager(ServerCaller.java:372)
at de.espirit.firstspirit.io.DefaultClientHandler.callManager(DefaultClientHandler.java:49)
at de.espirit.firstspirit.client.io.RemoteManagerCaller.invoke(RemoteManagerCaller.java:52)
at de.espirit.firstspirit.server.$Proxy37.executeQuery(Unknown Source)
at de.espirit.firstspirit.store.access.templatestore.SessionHandlerImpl.executeQuery(SessionHandlerImpl.java:73)
at de.espirit.or.impl.AbstractSession.executeQuery(AbstractSession.java:252)
at de.espirit.firstspirit.client.gui.tree.store.contentstore.ContentTable.execute(ContentTable.java:709)
at de.espirit.firstspirit.client.gui.tree.store.contentstore.ContentTable.execute(ContentTable.java:701)
at de.espirit.firstspirit.client.gui.tree.store.templatestore.TSQueryView$ResultViewComponent.update(TSQueryView.java:714)
at de.espirit.firstspirit.client.gui.tree.store.templatestore.TSQueryView.tabBecomesVisible(TSQueryView.java:116)
at de.espirit.firstspirit.client.gui.tree.store.AbstractAccessTabbedView.getComponent(AbstractAccessTabbedView.java:198)
at de.espirit.firstspirit.client.gui.tree.store.AbstractAccessTabbedView.access$100(AbstractAccessTabbedView.java:50)
at de.espirit.firstspirit.client.gui.tree.store.AbstractAccessTabbedView$1.tabSelected(AbstractAccessTabbedView.java:148)
at de.espirit.firstspirit.client.gui.tree.store.AbstractAccessTabbedView$SubTabModel$2.invoke(AbstractAccessTabbedView.java:613)
at de.espirit.firstspirit.client.gui.tree.store.AbstractAccessTabbedView$SubTabModel$2.invoke(AbstractAccessTabbedView.java:612)
at de.espirit.firstspirit.client.gui.tree.store.AbstractAccessTabbedView$SubTabModel.notifyListeners(AbstractAccessTabbedView.java:665)
at de.espirit.firstspirit.client.gui.tree.store.AbstractAccessTabbedView$SubTabModel.notifyTabSelected(AbstractAccessTabbedView.java:611)
at de.espirit.firstspirit.client.gui.tree.store.AbstractAccessTabbedView$SubTabModel.selectTab(AbstractAccessTabbedView.java:601)
at de.espirit.firstspirit.client.gui.tabbing.TabContext.select(TabContext.java:191)
at de.espirit.firstspirit.client.gui.tabbing.TabButton.doSelect(TabButton.java:339)
at de.espirit.firstspirit.client.gui.tabbing.TabButton.onClick(TabButton.java:560)
at de.espirit.firstspirit.client.gui.tabbing.TabButton$3.mouseReleased(TabButton.java:152)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at de.espirit.firstspirit.client.AWTDispatchingEventQueue.defaultDispatchEvent(AWTDispatchingEventQueue.java:130)
at de.espirit.firstspirit.client.AWTDispatchingEventQueue._dispatchEvent(AWTDispatchingEventQueue.java:115)
at de.espirit.firstspirit.client.AWTDispatchingEventQueue.dispatchEvent(AWTDispatchingEventQueue.java:108)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
Der Layer ist in dem Projekt mit den Optionen "Schreibgeschützt" und "kein Schema Sync" eingebunden?
Ja, alles durchgespielt,mit ausgewähltem Schreibschutz und ohne.
Es kommt immer die gleiche Fehlermeldung: "XXX has no key".
Hallo Katja,
kannst du einmal die schema.xml anhängen, die bei der Erzeugung des Schemas aus der Datenbank erzeugt wird?
Du erhälst sie, wenn du das Datenbankschema in der Vorlagenverwaltung in den Bearbeitungsmodus versetzt und dann "rechte Maustaste > extern bearbeiten > XML schema" wählst.
Vielen Dank,
Raphael.
Hallo Raphael,
ich habe im Anhang einmal einen Teilausschnitt unseres XML Schemas beigefügt.
Der erste Anhang (xml-schema-1.xml) ist gleich nach dem Import mit den Primary Keys.
Der zweite Anhang (xml-schema-2.xml) ist nach dem Verlassen des Bearbeitungsmodus. Die Primary Keys gehen verloren.
Grüße
Katja
Also, Primary Keys kann ich hier nicht erkennen, nur Foreign Keys, die wahrscheinlich beim Speichern verschwinden, weil keinerlei Primary Keys gefunden wurden.
Primary Keys müssten z.B. in deinem Fall so aussehen:
<xs:key dbName="PK_CHANNEL" name="pk_Channel">
<xs:selector xpath="A_Channel"/>
<xs:attribute xpath="A_ChannelNo"/>
</xs:key>
bzw.
<xs:key dbName="PK_DETAIL" name="pk_Detail">
<xs:selector xpath="A_Detail"/>
<xs:attribute xpath="A_DetailNo"/>
</xs:key>
Versuch doch einmal, die xml-Datei mit diesen Ergänzungen an der richtigen Stelle manuell zu editieren.
Viele Grüße,
Raphael.
Hallo!
Das manuelle Editieren hat tatsächlich geholfen. Jetzt kann ich Querys erstellen und bekomme auch die Werte aus der Datenbank. Vielen Dank!
Allerdings muss ich auf fast allen unserer Tabellen einen Filter auf 2 Datumspalten setzen, um gültige Einträge zu finden und die AS400 versteht das FirstSpirit-Parameter "today" leider nicht - sobald ich so einen Filter für mein Query definiere, bleibt das Ergebnis leer.
Könnte ich die Datumspalte evtl als String im XML definieren? Aber dann werden die Parameter im SQL-Statement sicher schon eingesetzt und ich kann keinen Datumvergleich mehr anwenden, richtig?
Vielleicht kann ich das noch umgehen, in dem ich eine Funktion in der Datenbank definiere, aber dazu müsste ich mir jetzt erstmal das SQL-Query ansehen, das dorthin abgesetzt wird.
Katja Garzareck schrieb:
Könnte ich die Datumspalte evtl als String im XML definieren? Aber dann werden die Parameter im SQL-Statement sicher schon eingesetzt und ich kann keinen Datumvergleich mehr anwenden, richtig?
Ich würde ihrer Vermutung zustimmen, dass Datumsvergleiche dann nicht mehr richtig funktionieren.