【问题标题】:class cast exception using SqlResultSetMapping and ConstructorResult使用 SqlResultSetMapping 和 ConstructorResult 的类转换异常
【发布时间】:2017-03-05 16:35:06
【问题描述】:

我正在尝试将 NativeQuery 的结果映射到非实体 pojo,使用 SqlResultSetMappingConstructorResult

我正在使用这个 StreetCity 类,带有结果映射:

@Data
@SqlResultSetMapping(name = "StreetCityResult", classes = {
        @ConstructorResult(targetClass = StreetCity.class, columns = {
                @ColumnResult(name = "street", type = String.class),
                @ColumnResult(name = "city", type = String.class) }) })
public class StreetCity {
    public String street;
    public String city;

    public StreetCity(String street, String city) {
        this.street = street;
        this.city = city;
    }
}

这是执行 NativeQuery 的函数

public List<StreetCity> retrieveStreetCity(String zipCode, int houseNumber) {
        Query query = em.createNativeQuery(getLocationQuery(zipCode, houseNumber), "StreetCityResult");
        List<StreetCity> streetCityList = query.getResultList();
        return streetCityList;
    }

这是应该执行的查询

public String getLocationQuery(String zipCode, int houseNumber) {
        String query = 
            "select straat.straatnaam as street, plaats.plaatsnaam as city " 
            + " from pcreeks "
            + " left join plaats on plaats.plaatsid = pcreeks.plaatsid "
            + " left join straat on straat.straatid = pcreeks.straatid "
            + " where (...) ";
        return query;
    }

但我仍然遇到异常

2017-03-05T16:35:57.736+0100|Warning: javax.ejb.EJBException
Caused by: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to nl.xxx.service.business.locations.entity.StreetCity

编辑: 错误来自此代码的第二行:

List<StreetCity> streetCityList = storage.retrieveStreetCity(zipCode, houseNumber);
streetCityList.get(0).getStreet();

Oracle 有exact same example in the javadoc,那我做错了什么?

【问题讨论】:

  • 限制 1 不是有效的 oracle 语法
  • 是的,我一开始忘了去掉,但是没有限制1,结果是一样的
  • 我读了那篇文章,但没有说明“您必须确保 YourDTO 已由您的持久性提供商注册”,但没有说明如何

标签: java oracle classcastexception sqlresultsetmapping


【解决方案1】:

找到了两个解决方案,在这两种情况下,StreetCity 都必须是 @Entity

使用@ConstructorResult,还需要构造函数。

解决方案一,使用@EntityResult 代替@ConstructorResult

@Data
@Entity
@SqlResultSetMapping(name = "StreetCityMapping", entities = @EntityResult(entityClass = StreetCity.class, fields = {
        @FieldResult(name = "street", column = "street"), @FieldResult(name = "city", column = "city") }))
public class StreetCity {
    @Id
    public String street;
    public String city;
}

解决方案2,使用@ConstructorResult,带有构造函数:

@Data
@Entity
@SqlResultSetMapping(name = "StreetCityMapping", classes = {
@ConstructorResult(targetClass =
 StreetCity.class, columns = {
 @ColumnResult(name = "street", type = String.class),
 @ColumnResult(name = "city", type = String.class) }) })
public class StreetCity {
    @Id
    public String street;
    public String city;

    public StreetCity() {
    }

    public StreetCity(String street, String city) {
      this.street = street;
      this.city = city;
    }
}

无需其他代码更改, 我想解决方案 1 是最干净的

【讨论】:

    猜你喜欢
    • 2017-03-04
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多