Ein Envers Timestamp sieht in der Datenbank bsplw so aus: 1441090155727 (und ist ein Bigint). Das wäre der 30.04.47636, 06:02:07, und ich bezweifel, dass der Datenbankeintrag aus der Zukunft kommt. Die Lösung ist so naheliegend wie einfach: Die letzten drei Stellen stehen für die Millisekunden, der “korrekte” Timestamp lautet 1441090155, und das ist der 01.09.2015, 08:49:15.
Tag Archives for JPA
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class ModelFlushInterceptor extends EmptyInterceptor { @Override public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) { for (int i = 0; i < currentState.length; i++) { if (currentState[i] == null) { if (previousState[i] != null) { // do stuff } } else if (!currentState[i].equals(previousState[i])) { // do the same stuff } } return super.onFlushDirty( entity, id, currentState, previousState, propertyNames, types ); } } |
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:
1 2 |
# application.conf: hibernate.ejb.interceptor.session_scoped=path.to.my.Interceptor |
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!
Spring Data JPA: Subqueries
JPQL-Subqueries können nicht im FROM stehen – aber Native Queries haben diese Einschränkung nicht (zwingend). Klar, denn native Queries sind eben nativ, sprich in der Sprache der jeweiligen Datenbank. Wer also damit leben kann, die Portabilität zu verlieren, der kann wie folgt “beliebige” Queries verwenden:
1 2 |
@Query(nativeQuery = true, value = "SELECT * FROM (SELECT * FROM `votes` ORDER BY `date` DESC) AS sub GROUP BY `username`") public List<Vote> findLastOfEachUser(); |