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

我正在使用此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,所以我在做什么错?

最佳答案

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

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

解决方案1,使用@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是最干净的一种

07-24 19:05
查看更多