【问题标题】:Why doesn't createNativeQuery return a TypedQuery<T>?为什么 createNativeQuery 不返回 TypedQuery<T>?
【发布时间】:2019-06-22 00:40:47
【问题描述】:

当我尝试执行泛型类型的 TypedQuery 时,我收到来自 Eclipse 的未经检查的类型转换警告。

我在这里使用泛型,因为在数据集中,由于查询和编辑的时间限制,每年都必须分成不同的表。表中有 118 年的数据(自 1900 年以来),我想构建一个可以使用 Java Reflections API 每年扩展自身的系统。但是,这意味着在编译之前,我的父类不知道它们将在哪个子类或表上进行操作。

下面是一些代码示例,即使我通过 TypedQuery 指定所有内容的类型,也会导致未经检查的警告。我的代码可以在我的数据库上编译和运行。

public class MyParentRepository<T extends MyParentPojo>
{
   @PersistenceContext
   private EntityManager em;

   private Class<T> tea;

   public MyParentRepository(Class<T> tea)
   {
      this.tea = tea;
   }

   public void giveWarning(int year)
   {
      String sql = String.format("SELECT * FROM mytable%d t", year);

      TypedQuery<T> resultSet = (TypedQuery<T>) em.createNativeQuery(sql, tea);
   }
}

预期的结果是,由于tea 保证使用泛型类型进行实例化,因为它在任何地方都是相同的类型,并且一旦实例化就无法更改,因此编译器应该了解实体管理器将返回一个TypedQuery 的类型也是如此。但是,即使保证可以正常工作,它也会导致未经检查的类型警告。

我看到有人建议通过从 Query 转到 TypedQuery 来修复未经检查的类型警告,但这在这种情况下没有帮助。有没有办法在做我想做的事情的同时避免这个警告?

针对已删除的答案,我想澄清一点。

em.createQuery(String)
em.createQuery(String, Class<T>)
em.createNativeQuery(String)
em.createNativeQuery(String, Class)
  1. 在这些选项中,第一个接受 JPQL 字符串并返回一个 通用查询。
  2. 选项 2 采用 JPQL 字符串和表示表的特定类 行,并返回一个 TypedQuery。
  3. 选项 3 接受一个 SQL 字符串并返回一个通用查询。
  4. 选项 4 接受一个 SQL 字符串和一个表示表行的特定类, 为什么它返回一个通用查询而不是一个 TypedQuery?

在我看来,如果我给它一个适当类型的 POJO,选项 4 应该弄清楚如何序列化它,就像选项 2 对我所做的那样。事实上确实如此,但它没有像选项 2 那样正确设置类型。从我的角度来看,这是不可接受的,因为不是每个 SQL 查询都可以用 JPQL 查询表示,所以有时我需要使用 SQL ,并且我希望返回一个 TypedQuery。

我已经通过切换到选项 2 解决了我的警告,但我仍然想知道答案,以防万一我说将来出现我无法使用选项 2 的情况。

【问题讨论】:

  • 你在哪里得到警告?
  • 好的,有人删除了一个原来非常有用的答案,即使它没有直接回答这里的问题。我现在有一个新问题。当 createQuery(String, Class) 返回 TypedQuery 时,为什么 EnityManager 的 createNativeQuery(String, Class) 返回 Query 而不是 TypedQuery。这意味着要么我必须通过不必要的步骤将结果显式转换为 T,要么我必须处理代码中的警告。另外,我应该用这个更新这个问题,还是按照这些思路创建一个新问题?

标签: java jpa generics suppress-warnings


【解决方案1】:

这是因为 createNamedQuery 返回 Query 而不是 TypedQuery&lt;T&gt; 即使在“类型化结果”变体中也是如此。 https://docs.oracle.com/javaee/7/api/javax/persistence/Query.html

【讨论】:

  • 感谢您至少尝试,但我什至在我的问题中说了这么多。也许你知道他们为什么决定返回一个普通的 Query 而不是 TypedQuery.
  • 这个答案只是改写了问题标题,将“为什么”改为“因为”。
  • @PetrAleksandrov 没错,但要考虑到在 iv 发布该答案后标题已更改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-07
  • 2016-11-10
  • 2015-09-22
  • 2017-04-01
  • 1970-01-01
  • 2014-09-09
相关资源
最近更新 更多