org.hibernate.MappingException: No Dialect mapping for JDBC type: -9

Folgendes Setup: Play 1.2.5.3, also Hibernate 3.6.10. Damit eine native Query auf einen MS SQL Server.

Folgender Fehler:

WTF? Die Query ist da übrigens nicht erst seit gestern drin, den Fehler gibt es aber erst seit Neuestem.

stackoverflow sagt nun zuerst mal:

The type -9 is java.sql.Types.NVARCHAR

und weiterhin (das liest man auch an anderer Stelle, der Fairness halber), die Lösung wäre:

Kurze Prüfung: Das fragliche Feld ist sowieso ein varchar. Außerdem hat es natürlich normalerweise einen Grund, nvarchar zu benutzen – nvarchar ist ein varchar, das Unicode unterstützt. Das will man nicht zurück casten. Macht also doppelt keinen Sinn. Vielleicht kommt der Fehler initial daher, dass das Feld seit Kurzem mit einem per String.toUpperCase() transformiertem String befüllt wird, vielleicht hilft hier ein String.toUpperCase(Locale), damit nicht implizit ein Unicode-String daraus wird. Klingt irgendwie auch merkwürdig, aber hey: Es ist ein MS SQL-Server! 🙂

Wie auch immer, wir haben durchaus nvarchar-Felder, und wollen die auch nutzen. stackoverflow sagt nun weiterhin, man müsse den nvarchar-Typ explizit bekannt machen, wenn er das im aktuell von Hibernate verwendeten SQL-Dialekt (und das ist hier SQLServer2008Dialect) nicht ist (ist er zwar, aber wenn’s der Sache dient…):

Ausprobiert, geht nicht. Nun gibt es neben registerColumnType auch registerHibernateType (Quelle), und damit geht’s:

Fast vergessen: Das ganze wird dann natürlich auch nicht per XML, sondern per application.conf konfiguriert:

HTH

Hibernate Interceptor mit Play 1.2.x

Update: Man beachte das PS!

Neulich wollte ich (möglichst generisch) wissen, welches Feld von einer Entity modifiziert wurde. Internet sagt, das ginge mit einem Interceptor:

Leider ist für Play nicht offensichtlich, wie man einen solchen einbindet… zumindest nicht für 1.2.x. Es gibt hibernate.ejb.interceptor, das ist es aber nicht. Tatsächlich gibt es “parallel” (“This property can not be combined with hibernate.ejb.interceptor”) noch hibernate.ejb.interceptor.session_scoped – und der geht:

Good to know: Man kann die Entity als solche hier nicht mehr ändern! Man kann aber das zu ändernde Property in currentState suchen und setzen (oder ergänzen) 🙂 Dann sollte man true zurückgeben, statt super.onFlushDirty(...). Quelle.

<Update>Interceptors haben noch einige andere nette Methoden, so kann man beispielsweise zentral checken, welche Entitäten geändert, inserted oder deleted worden sind.</Update>

PS: Internet sagt außerdem, dass Play schon einen eigenen Interceptor nutzen würde… klang für mich ein wenig so, als würde es Probleme geben, wenn man den “überschreibt” – ich konnte aber keine feststellen und das ist leider auch der Fall: im play.db.jpa.JPAPlugin wird ein eigener Interceptor verwendet, der dafür sorgt, dass Entitäten nicht automatisch gespeichert werden (Hibernate Standard?). Das bloße Verwenden eines eigenen Interceptors hebelt dies aus!

PPS: tgorres hat einen Workaround gefunden, siehe Kommentare. Vielen Dank dafür!

Play Dependencies für JBoss ActiveMQ mit Zookeeper

Es gibt bereits ein gutes Tutorial, wie man eine MQ via Zookeeper anspricht, hier aber noch mal explizit für Play (1 und 2).

Schritt 1: Libraries hinzufügen

Play 1

Die Excludes waren für mein Setup nötig, das müssen sie aber nicht generell sein:

Damit das funktioniert, müssen die folgenden Repositories in den Ivy-Setting definiert werden:

Eine Anmerkung dazu: Das “Early Access” Repo ist meiner Einschätzung nach eigentlich nicht nötig; alle letztlich verwendeten Dependencies kommen aus dem “Releases” Repo. Aber: Offenbar gibt es irgendwelche transitiven Dependencies, die dort zu finden sind. Sie werden “später” durch andere transitive Dependecies “überschrieben”, aber sie müssen trotzdem aufgelöst werden können! Andernfalls funktioniert zwar auch alles, aber es gibt unschöne Warnings. Und ich habe einige Zeit darauf verwendet, das “Early Access” Repo durch force und exclude wegzukonfigurieren – ein Fass ohne Boden 🙂

Play 2

Schritt 2: Konfiguration

Schritt 3: Im Code

HTH!

MS SQL: Alle Tabellen leeren

Ich möchte das nicht jedes mal googlen:

In dem Zusammenhang: Flyway initOnMigrate in Play Applikationen:

Play: Lokales .jar als Dependency

bsplw:

via

PS: Die referenzierte .jar ist dieses feine Plugin für Elasticsearch, das es natürlich auch im Maven Repo gibt.

Eclipse: JPDA Port (nachträglich) herausfinden

Ich habe einige Play-Anwendungen im Terminal laufen, plus einer weiteren in Eclipse. Die in Eclipse würde ich gerne debuggen, wozu play eclipsify einen entsprechenden Launcher “Connect JPDA to myapp.launch” anlegt. Der Launcher enthält einen Port “0”:

Nun ist der Port (ich glaube, “0” wählt den default 8000, aber das kann falsch sein) nicht erreichbar, vielleicht ist er durch die Anwendungen im Terminal belegt. Vielleicht wählt “0” auch jedes mal einen zufälligen Port, ich kann das gerade nicht gegenprüfen. Wie auch immer, der Punkt ist:

Beim Start der Anwendung gibt es eine Ausgabe im Log à la

Listening for transport dt_socket at address: <port number>

Läuft die Anwendung lange genug, sehe ich diese Ausgabe aber nicht mehr – wie finde ich nun den Port heraus? Unter OS X wie folgt: Zuerst suche ich in der Aktivitätsanzeige alle “java”-Prozesse:

Uns interessiert derjenige, der zu Eclipse gehört (diese Ansicht wird per Doppelklick auf den Prozessnamen geöffnet):

Die Liste der “geöffneten Dateien und Ports” ist recht lang, aber der Eintrag sticht durch seine Kürze hervor: Voilà, der gesuchte Port.

PS: Man kann den Logger von Play natürlich auch so konfigurieren, dass es die Ausgabe in ein File schreibt, siehe hier (via). Hier brauchte ich aber die Möglichkeit den Port herauszufinden, ohne die Applikation neu zu starten.

Slightly related: Den Prozess, der auf Port (z.B.) 80 hört, findet sich per

” -t” listet die Prozesse auf (Quelle), um sie an kill übergeben zu können:

sudo kann optional sein.