【问题标题】:Failed to convert from type [java.lang.Object[]] to type无法从类型 [java.lang.Object[]] 转换为类型
【发布时间】:2017-07-15 17:59:48
【问题描述】:

我有 Spring Web 应用程序(JPA/Hibernate + MySQL)。 我有两个 DAO 类。

客户DAO

@Entity
@Table(name = "customers")
public class Customer {

  @Id
  @Column(name = "customer_id")
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  @Column(name = "name", length = 50)
  private String name;

  @Column(name = "surname", length = 50)
  private String surname;

  @OneToMany(mappedBy = "customer")
  private Set<Order> orders = new HashSet<>();
}

OrderDAO

@Entity
@Table(name = "orders")
public class Order {

  @Id
  @Column(name = "order_id")
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  @Column(name = "date")
  private Date date;

  @Digits(integer = 5, fraction = 2)
  @Column(name = "amount")
  private BigDecimal amount;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "customer_id")
  private Customer customer;

  @OneToMany(mappedBy = "order")
  private Set<OrderDetail> ordersDetails = new HashSet<>();

我有一个从数据库中检索数据的类:

@Repository
public interface OrderDAO extends JpaRepository<Order, Long> {

    @Query("select o.customer.surname, sum(o.amount) as s from Order as o group by o.customer")
    List<Customer> findCustomersBySumOfAmount();

}

它给了我这样的结果:

+---------+---------------+
| surname | sum of amount | 
+---------+---------------+
|Bielecki | 141.49        | 
|Bielen   | 130.34        |
......

现在我想用这种方法List&lt;Customer&gt; findCustomersBySumOfAmount()从数据库中“拆箱”数据

我的 spring 控制器类中有这个方法:

 List<Customer> findCustomersBySumOfAmount = orderService.findCustomersBySumOfAmount();
 model.addAttribute("findCustomersBySumOfAmount", findCustomersBySumOfAmount);

 for(Customer c : findCustomersBySumOfAmount) {
     String s = c.getSurname();
     System.out.println(c);
 }

我有错误:

无法从类型 [java.lang.Object[]] 转换为类型 [com.twistezo.models.Customer] 为价值 '{Bielecki, 141.49}';嵌套的 例外是 org.springframework.core.convert.ConverterNotFoundException:否 发现转换器能够从类型 [java.lang.String] 转换为 输入 [com.twistezo.models.Customer]

我想这是因为我收到了List&lt;Object[]&gt;。我知道我可以在我的数据的 List&lt;Object[]&gt; 之间进行迭代,但也许有一些更简单的方法可以直接将数据检索到 &lt;Customer&gt; ?我是这方面的新手。从现在开始,我使用像 List&lt;Customer&gt; findAll() 这样没有 @Query 注释的方法,我正在寻找类似的“拆箱”。

我试图做这样的事情(在查询中添加 Customer.class)但没有效果:

@Query("select o.customer.surname, sum(o.amount) as s from Order as o group by o.customer", Customer.class) List<Customer> findCustomersBySumOfAmount();

【问题讨论】:

    标签: java mysql spring hibernate jpa


    【解决方案1】:

    我建议创建一个 POJO 类来存储该查询的结果:

    package com.mypackage;
    
    public class CustomerAmountResult{
    
        private String surname;
        private BigDecimal amountSum;
    
        public CustomerAmountResult(String surname, BigDecimal amountSum){
           this.surname = surname;
           this.amountSum = amountSum;
        }
    
        // getters / setters
    }
    

    然后将您的查询更改为以下内容:

    @Query("select NEW com.mypackage.CustomerAmountResult(
                o.customer.surname, sum(o.amount)) 
            from Order as o
            group by o.customer.surname") 
    List<CustomerAmountResult> findCustomersBySumOfAmount();
    

    因此,您无需手动解析结果集。

    【讨论】:

    • 好主意@Maciej Kowalski,但在您的查询中是错误的。控制台说Validation failed for query for method public abstract java.util.List com.twistezo.repositories.OrderDAO.findCustomersBySumOfAmount()! 和Intellij 建议Cannot resolve constructor 'com.twistezo.repositories.CustomerTotalAmountResult(java.lang.String, java.math.BigDecimal) 部分(o.customer.surname,sum(o.amount))`如何解决这个问题?我从未见过这样的查询构造,但看起来它适合构造函数(String,BigDecimal)。
    • 尝试在大写字母中使用 NEW 而不是 new
    • 也可以尝试使用 Double 而不是 BigDecimal
    • 另一方面,您应该按 o.customer.surname 分组,而不是按 o.customer。除此之外,这个例子对我来说很好用。它必须工作,因为它是投影映射的 JPA 标准。你能添加完整的堆栈跟踪吗?
    • 好的,现在可以了。我错过了一些东西。谢谢@Maciej Kowalski
    【解决方案2】:

    您的查询 select o.customer.surname, sum(o.amount) as s from Order as o group by o.customer 未返回 Customer。 Customer 实体期望结果集至少看起来像:

    |   id   | name   | surname |
    -----------------------------
    |   1    | john   | smith   |
    |   2    | james  | white   |
    |   3    | sara   | black   | 
    

    这就是将结果集映射到客户实体的方式。如果您想坚持查询,请将返回类型更改为List&lt;Object[]&gt;,然后遍历列表并提取您想要的数据。

    【讨论】:

    • 好的@raminr,当我使用for(Object[] o : findCustomersBySumOfAmount){ System.out.println(o[0]); System.out.println(o[1]); } 打印来自List&lt;Object[]&gt; findCustomersBySumOfAmount(); 的值时,我有Bielecki 141.49 Bielen 222.39 Nowak 40.80 Nowakowski 171.78,但是我如何将这些参数与@Maciej Kowalski 帖子中的CustomerAmountResult 类连接起来?
    • 面临同样的问题。有人可以帮忙吗?
    • 我的建议是避免创建一个新类,就像 Maciej Kowalski 提供的响应中所建议的那样。如果可以新建一个类,那就按照他的建议,更干净。
    【解决方案3】:

    我已经收到此错误消息。就我而言,我正在做类似下面的代码:

    @Repository
    public interface RepositoryA extends CrudRepository<EntityA, Long> {
    
      @Query(nativeQuery = true, value = " ...SQL_1... ")
      List<EntityA> getListOfEntityA(...PARAMS_1...);
    
      @Query(nativeQuery = true, value = " ...SQL_2... ")
      List<EntityB> getListOfEntityB(...PARAMS_2...);
    
    }
    

    我正在使用“EntityA”参数化存储库接口,并且有另一个方法返回使用“EntityB”参数化的其他类型。

    在您的情况下,您正在使用“订单”参数化 JpaRepository,然后使用返回“客户”列表的方法......也许这会导致此异常。

    【讨论】:

    • 绝对精彩。我有一个混合了实体驱动和本机 sql 驱动的 DAO 的应用程序,这解决了我在同一个 DAO 中的跨实体的所有问题。
    【解决方案4】:

    我也有类似的情况,但在我的情况下,不需要映射(订单到客户)。

    如果你有同一个Domain POJO中的所有字段(这里是CustomerDAO),则不需要创建新的POJO或将返回类型更改为Object。您所需要的只是域 POJO 中的参数化构造函数(与您在 JPQL 查询中获取的字段相同)。

    一个例子

    package com.mypackage.domain
    
    @Entity
    @Table(name = "TABLENAME")
    public class UserDO {
    
    @Column(name = "FIRST_NAME")
    private String firstName;
    
    @Column(name = "LAST_NAME")
    private String lastName;
    
    @Column(name = "DOB")
    private String dob;
    
    public UserDO(){
    }
    
    public UserDO(String firstName, String lastName){
    this.firstName = firstName;
    this.lastName = lastName;
    }
    
    
    }
    

    你的仓库应该包含这样的方法

    @Query("Select NEW com.mypackage.domain.UserDO(user.firstName, user.lastName) from UserDO as user where user.lastName =?1")
    UserDO findByLastName(String lastName);
    
    

    【讨论】:

      猜你喜欢
      • 2020-04-23
      • 2020-03-29
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 2014-05-19
      • 2016-10-17
      • 1970-01-01
      • 2022-10-17
      相关资源
      最近更新 更多