如何避免使用Hibernate HQL结果的类型安全警告?

ser*_*erg 101 java generics

例如,我有这样的查询:

Query q = sess.createQuery("from Cat cat");
List cats = q.list();
Run Code Online (Sandbox Code Playgroud)

如果我尝试做这样的事情,它将显示警告"类型安全:类型列表的表达式需要未经检查的转换以符合列表":

Type safety: The expression of type List needs unchecked conversion to conform to List<Cat>


List<Cat> cats = q.list();
Run Code Online (Sandbox Code Playgroud)

有没有办法避免它?

Mat*_*ail 97

@SuppressWarnings如所建议的那样,在任何地方使用都是一种很好的方法,尽管每次调用时它都会涉及一些手指输入q.list().

还有其他两种技巧我建议:

写一个演员帮手

只需将您的所有内容重构@SuppressWarnings为一个地方:

List<Cat> cats = MyHibernateUtils.listAndCast(q);

...

public static <T> List<T> listAndCast(Query q) {
    @SuppressWarnings("unchecked")
    List list = q.list();
    return list;
}
Run Code Online (Sandbox Code Playgroud)

防止Eclipse针对不可避免的问题生成警告

在Eclipse中,转到Window> Preferences> Java> Compiler> Errors/Warnings,在Generic type下,选中复选框 Ignore unavoidable generic type problems due to raw APIs

这将关闭类似问题的不必要警告,例如上述不可避免的问题.

一些评论:

  • 我选择传入Query而不是结果,q.list()因为这种"欺骗"方法只能用于欺骗Hibernate,而不是用于欺骗任何List一般.
  • 您可以添加类似的方法.iterate()等.

  • 乍一看,Collections.checkedList(Collection <E>,Class <E>)方法看起来就像是完美的解决方案.但是,javadoc说它只能防止通过方法生成的类型安全视图添加错误输入的元素.没有在给定列表上进行检查. (20认同)
  • "List <Cat> list = Collections.checkedList(q.list(),Cat.class);" 在Eclipse中仍然需要"@SuppressWarnings".关于另一个提示:键入"listAndCast"并不比通过Eclipse自动添加的"@SuppressWarnings"短. (11认同)
  • 顺便说一句,`Collections.checkedList()`方法不会压制未经检查的赋值警告. (2认同)

ant*_*npp 34

问题问题已经有很长一段时间了,但我希望我的回答可能会对像我这样的人有所帮助.

如果你看看javax.persistence api docs,你会发现之后添加了一些新的方法Java Persistence 2.0.其中一个是createQuery(String, Class<T>)返回TypedQuery<T>.您可以像使用TypedQueryQuery一样使用所有操作现在都是类型安全的小差异.

所以,只需将代码更改为smth,如下所示:

Query q = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q.list();
Run Code Online (Sandbox Code Playgroud)

你们都准备好了.

  • 最近版本的 Hibernate 实现了 JPA 2.x,所以这个答案是相关的。 (3认同)

cre*_*zel 21

我们也使用@SuppressWarnings("unchecked"),但我们经常尝试仅在变量的声明上使用它,而不是在整个方法上使用它:

public List<Cat> findAll() {
    Query q = sess.createQuery("from Cat cat");
    @SuppressWarnings("unchecked")
    List<Cat> cats = q.list();
    return cats;
}
Run Code Online (Sandbox Code Playgroud)


小智 14

尝试使用TypedQuery而不是Query.例如,而不是: -

Query q = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q.list();
Run Code Online (Sandbox Code Playgroud)

用这个:-

TypedQuery<Cat> q1 = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q1.list();
Run Code Online (Sandbox Code Playgroud)


tys*_*ock 5

在我们的代码中,我们使用以下方法注释调用方法:

@SuppressWarnings( "未登记")

我知道这似乎是一个黑客攻击,但最近联合开发人员检查了一下,发现这就是我们所能做的.


Pau*_*son 5

显然,Hibernate API中的Query.list()方法"设计"并不是类型安全的,并且没有计划对其进行更改.

我认为避免编译器警告的最简单的解决方案确实是添加@SuppressWarnings("unchecked").此注释可以放在方法级别,或者,如果在方法内部,则放在变量声明之前.

如果您有一个封装Query.list()并返回List(或Collection)的方法,您也会收到警告.但是这个使用@SuppressWarnings("rawtypes")来抑制.

Matt Quail提出的listAndCast(Query)方法不如Query.list()灵活.虽然我能做到:

Query q = sess.createQuery("from Cat cat");
ArrayList cats = q.list();
Run Code Online (Sandbox Code Playgroud)

如果我尝试以下代码:

Query q = sess.createQuery("from Cat cat");
ArrayList<Cat> cats = MyHibernateUtils.listAndCast(q);
Run Code Online (Sandbox Code Playgroud)

我将得到一个编译错误:类型不匹配:无法从List转换为ArrayList