【问题标题】:JPQL: How to "SELECT new Foo(null, null... someValue, ..)?JPQL:如何“选择新的 Foo(null, null... someValue, ..)?
【发布时间】:2013-08-29 16:34:12
【问题描述】:

例如我有一个实体

public class Foo {
   private String col1;
   private String col2;
   private String col3;
   private String col4;

   //getters and setters   
}

我想做的只是select col3col4。但我已经有一个Foo 构造函数,如下所示:

public Foo (String col1, String col2) {
   this.col1 = col1;
   this.col2 = col2;
}

因此,我不能为col3col4 提供另一个构造函数,因为它具有相同的签名。

到目前为止,我想要完成的是制作一个 complete 构造函数,例如:

public Foo (String col1, String col2, String col3, String col4) {
   this.col1 = col1;
   this.col2 = col2;
   this.col3 = col3;
   this.col4 = col4;
}

但是当我尝试在查询中执行以下操作时

SELECT new Foo(null, null, f.col3, f.col4)
FROM Foo f

我明白了

org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected end of subtree

虽然当我尝试

SELECT new Foo(f.col1, f.col2, f.col3, f.col4)
FROM Foo f

它按预期工作。

编辑:

我试过了

Select f.col3, col4..

下面的错误被抛出

org.springframework.dao.InvalidDataAccessApiUsageException: Cannot create TypedQuery for query with more than one return using requested result type [com.lala.entity.Foo]; nested exception is java.lang.IllegalArgumentException: Cannot create TypedQuery for query with more than one return using requested result type [com.lala.entity.Foo]

【问题讨论】:

标签: hibernate jpa jpql


【解决方案1】:

您可以尝试(但只是尝试)

SELECT new Foo(cast(null as string), cast(null as string), f.col3, f.col4)
FROM Foo f

或寻找 JPQL 的 cast() 运算符(我不确定)
否则

Session session = entityManager.unwrap(Session.class);
List<Foo> list = session.createQuery("select f.col3, f.col4 from Foo f").list()

这是特定于 Hibernate 的,您不需要为每个投影使用特定的构造函数;只需创建一个空的构造函数Foo()(至少受保护,我不记得是否允许私有)并让Hibernate从您的查询中将值注入col3, col4(如果您的基础数据库支持该功能,则支持cast()运算符)。

【讨论】:

    【解决方案2】:

    我知道这个问题很老,但你也可以这样做(如果演员对你不起作用):

    String query = "select new Pojo( " +
            " trim(:null), " +
            " trim(:null), " +
            " f.col3, " +
            " f.col4 " +
            " ) " +
            " from Foo as f ";
    
    return em.createQuery(query, Pojo.class)
            .setParameter("null", null)
            .getResultList();
    

    编辑: JPA 在将文字列映射到构造函数参数时会忽略它们,因此用 trim 包装以让 JPA 知道文字值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-02
      • 1970-01-01
      • 1970-01-01
      • 2017-01-07
      • 2020-02-10
      • 1970-01-01
      • 2010-12-11
      相关资源
      最近更新 更多