Warum wird ein Objekt von id in JPA, aber nicht durch eine JPQL Frage gefunden?
Frage
Ich habe einen Test JUnit 4 mit der Feder @Transactional
Anmerkung, die ein Objekt speichert, und dann versucht, zu finden. Der Testfall passiert, wenn ich diese Implementierung verwenden:
@Override
public EventSummary findEventSummaryById(Integer id) {
return em.find(EventSummary.class, id);
}
Es schlägt fehl, wenn ich diese Implementierung (und dann ändern, die Methode, die ich Aufruf im Testfall):
@Override
public EventSummary findEventSummary(Integer id) {
Query query = em.createQuery("select es from EventSummary as es where es.id = :id");
query.setParameter("id", id);
EventSummary result = (EventSummary) query.getSingleResult();
return result;
}
Lösung
Wenn Sie die Standard-flush-Modus verwenden (AUTO
) und wenn Sie Ihre Anfrage innerhalb einer Transaktion ausgeführt werden, die JPA-Spezifikation garantiert, dass eine Abfrage nicht abgestanden oder falsche Daten zurück:
3.6.2 Abfragen und Flushmode
Der UP-Modus-Einstellung wirkt sich auf die Ergebnis einer Abfrage wie folgt.
Wenn Abfragen innerhalb einer ausgeführt werden Transaktion, wenn
FlushModeType.AUTO
ist auf demQuery
Objekt gesetzt ist, oder wenn die flush-Modus-Einstellung für die Persistenz Kontext istAUTO
(Standard) und eine flush-Modus-Einstellung ist nicht Für dieQuery
Objekt spezifiziert die Persistenz-Provider ist verantwortlich um sicherzustellen, dass alle Aktualisierungen der Zustand aller Einheiten in der Persistenzkontext die geeignet sind, potenziell beeinflussen das Ergebnis der Abfrage ist für die Verarbeitung von die Abfrage. Die Persistenz-Provider Implementierung kann dies erreichen, indem diese Einheiten zu der Spülung Datenbank oder durch andere Mittel. WennFlushModeType.COMMIT
festgelegt ist, die Wirkung von Aktualisierungen vorgenommen Einheiten in die Persistenzkontext auf Abfragen ist nicht spezifiziert.public enum FlushModeType { COMMIT, AUTO }
Wenn es keine Transaktion aktiv ist, die Persistenz-Provider muss nicht bündig die Datenbank.
Unter der Annahme, dass Sie AUTO
verwenden, überprüfen Sie die Transaktionsseite.
Andere Tipps
Der Erbauer der Einheit ist in der aktuellen Sitzung (Entity-Manager) - es in persistenten Zustand ist, gespült zu warten. Die get-Methode überprüft zuerst den Inhalt der Sitzung, und wenn nicht auf die zugrunde liegende Datenbank gefunden Umdrehungen. In Ihrem Fall hat das Unternehmen gerade in der gleichen Sitzung gespeichert, so dass es gefunden und zurückgegeben.
Update: Es stellte ihm das Problem aus wird einen falschen Transaktionsmanager verwenden, daher hat das Unternehmen nicht in die Datenbank gespült worden. Siehe Pascals Erklärung.
Im ersten Fall ist die ID ein Integer
in der zweiten, ist die ID ein String
ein Integer wird gleich nie einen String