2009-04-08 4 views
4

Alle APIs in Hibernate stammen von 1.4 und verwenden daher keine Java-Generics.Hibernate Query API und Java 1.5/Generics

So frage ich mich, wie "sicher" ist das Folgende: (Voraussetzungen: Name Spalte ist vom Datentyp String, oder zumindest kompatibel zu String)

@SuppressWarnings("unchecked") 
public List<String> getAll() { 
    Query q = session.createQuery(
     "select name from Customers"); 
    return q.list();  
} 

Von der Queryi API (org.hibernate.Query.list()) Javadoc.

"Return the query results as a List. If the query contains multiple results pre row, the results are returned in an instance of Object[]. "

Antwort

3

Es ist sicher, solange Sie sicher sind, dass die Abfrage nicht "mehrere Ergebnisse pro Zeile enthält". (Ich bin nicht mit Abfragen vertraut, daher bin ich mir nicht sicher, ob dies in diesem Fall passieren kann.) Wenn eine Zeile mehrere Ergebnisse enthält, wird ClassCastException zur Laufzeit ausgelöst, wenn Sie versuchen, darauf zuzugreifen Object [] -Objekt anstelle eines String-Objekts.

+0

Das kann passieren, wenn Sie zum Beispiel eine HBM-Abfrage mit Joins wie folgt haben: 'von Item links links i.preferences p verbinden, wobei p null ist. Hier werden sowohl die Zeilen für das Element als auch für die Einstellungen ausgewählt, sodass Sie mehrere Ergebnisse erhalten. Um zu vermeiden, dass Sie angeben müssen, dass nur Elemente zurückgegeben werden sollen: 'Wählen Sie i aus Element i links verbinden Sie i.preferences p wobei p null ist – Rihards

2

In Java Generika sind eigentlich Löschungen, die nichts anderes als Compiler Magie. Die als generische Typargumente verwendeten Typen sind zur Laufzeit unbekannt. Daher sollte die Umwandlung erfolgreich sein, wenn die zurückgegebene Liste die List-Schnittstelle implementiert, der Compiler jedoch Warnungen an Sie ausgibt.

+0

Sicher, diese Besetzung wird erfolgreich sein, aber ich denke, dass der Punkt fehlt. Wenn Sie versuchen, tatsächlich Objekte aus der Liste zu entfernen, möchten Sie sicher sein, dass sie tatsächlich 'String's sind. – MatrixFrog

+0

@ MatrixFrog wird diese Annahme zur Laufzeit durch die Umwandlungen erzwungen, die vom Compiler generiert werden. Beachten Sie, dass der Autor explizit angegeben hat, dass die Objekte im Array Strings wären. – Lucero

3

Java Generics verwenden Typ löschen, so zur Laufzeit gibt es keinen Unterschied zwischen einem List, einem List<String>, und einem List<Integer>. Alle sind wirklich nur List s. Bei der Kompilierung erzwingt der Compiler den Template-Parametertyp, aber unter den Covers zur Laufzeit haben Sie eine List.

In der Tat, wenn Sie versuchen, Reflektion verwenden, um die Vorlage Parametertyp zu finden, können Sie nicht.

+3

(Klasse ) ((ParametrierterTyp) getClass() \t \t \t .getGenericSuperclass()). GetActualTypeArguments() [0]; Wie Sie Ihren Template-Parameter erhalten – Schildmeijer