2009-04-08 16 views
4

HibernateのすべてのAPIは1.4以降であり、Javaジェネリックを使用していません。Hibernate Query APIとJava 1.5/Generics

は、だから私は、次がどのように「安全な」疑問:(QueryiのAPIから

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

org.hibernate.Query.list:(前提条件の名前の欄には、データ型の文字列、または文字列に少なくとも互換性のあります) ())javadoc Javaでは

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

答えて

3

クエリに「行ごとに複数の結果が含まれていない」ことが確実である限り、安全です。 (私はクエリに精通していないので、この場合に起こりうるかどうかは分かりません)。行に複数の結果が含まれている場合、アクセスしようとすると実行時にClassCastExceptionがスローされます。 StringオブジェクトではなくObject []オブジェクトです。

+0

たとえば、次のような結合を持つhbmクエリがあるとします。 'アイテムiは、i.preferences pのどこにpがnullであるかを示します。ここでは、項目とその設定の両方の行が選択されるので、複数の結果が得られます。これを避けるには、アイテムだけを返すように指定する必要があります。 'Item iからiを選択してください。i.preferences p join p left is join' – Rihards

2

、ジェネリック医薬品は、実際には何もなく、コンパイラの魔法ではありません消去、です。ジェネリック型引数として使用される型は、実行時には不明です。したがって、返されたリストがListインタフェースを実装している場合、キャストは成功するはずですが、コンパイラが警告をスローする可能性があります。 ListList<String>、とList<Integer>間に違いはありませんので、実行時に

+0

確かに、そのキャストは成功するだろうが、私はそれが欠けていると思う。実際にリストからオブジェクトを取得しようとするとき、それらが実際に 'String'であることを確認したいとします。 – MatrixFrog

+0

@MatrixFrogでは、この仮定は実行時にコンパイラによって生成されるキャストによって強制されます。作者は、配列内のオブジェクトが文字列であると明示的に述べていることに注意してください。 – Lucero

3

のJavaのジェネリックは、型消去を使用します。すべては実際にはListです。コンパイル時に、コンパイラはテンプレートパラメータタイプを強制しますが、実行時にはListです。

実際にリフレクトを使用してテンプレートパラメータタイプを検索しようとすると、それを行うことはできません。

+3

(Class )((ParameterizedType)getClass()\t \t \t .getGenericSuperclass())。getActualTypeArguments()[0]; テンプレートパラメータを取得する方法 – Schildmeijer