类型转换异常的意思我还是知道些的,但是这里我实在是不明白为什么。
POJO里只是多了个workHour属性,其他跟数据库表没区别。
在代码1中通过查询得到了一个List,强转为List<EventTag>,这个时候没报异常,但是在代码2中,使用这个list的时候就会报强制类型转换错误。不明白原因,请高手给解答一下。谢谢代码如下:
POJO
@Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;                 
    private Integer eventId;                // 日程Id
    private String realName;                // 用户姓名
    private Integer tagId;                  // 标签Id
    private String tagName;                 // 标签名称
    private String userName;                // 用户名
    @Transient
    private Integer workHour;               // 工时 数据库表:
id     int         11
eventId     int         11
realName    varchar 255
tagId     int         11
tagName     varchar 255
userName    varchar 255sql:
SELECT et1.* from tr_work_event_tag et1 inner join tb_work_event ev on et1.eventId = ev.id  where ev.creator = ? and ev.startDate >= ? and ev.endDate <= ? and ev.status = ? order by (select count(et2.id) from tr_work_event_tag et2 where et2.tagId = et1.tagId) desc java代码
代码1
public List<EventTag> personTags(String userName, ViewMode viewMode, Date firstDate) {
        Date endDate = DateUtils.getLastDate(viewMode, firstDate);
        String sql = "SELECT et1.* from tr_work_event_tag et1 inner join tb_work_event ev on et1.eventId = ev.id " +
                     "where ev.creator = ? and ev.startDate >= ? and ev.endDate <= ? and ev.status = ?" +
                     "order by (select count(et2.id) from tr_work_event_tag et2 where et2.tagId = et1.tagId) desc ";
          //String sql = "SELECT et1 from EventTag as et1 inner join Event as ev on et1.eventId = ev.id " +
           //          "where ev.creator = ? and ev.startDate >= ? and ev.endDate <= ? and ev.status = ?" +
           //        "order by (select count(et2.id) from Event as et2 where et2.tagId = et1.tagId) desc ";
        
        SQLQuery query = this.eventTagDao.getSQLQuery(sql);
        //Query query = this.eventTagDao.getQuery(sql);
        query.setString(0, userName);
        query.setTimestamp(1, firstDate);
        query.setTimestamp(2, endDate);
        query.setString(3, EventStatus.Normal.toString());
        query.setMaxResults(8);
        
        List<EventTag> eventTags = (List<EventTag>)query.list();
        this.statisticsTags(eventTags, userName, firstDate, endDate);
        return eventTags;
    }代码2:
 public void statisticsTags(List<EventTag> eventTags, String userName, Date firstDate, Date endDate) {
        try{
            for(int i=0; i<eventTags.size(); i++) {
//这里报强制类型转换错误
                EventTag eventTag = eventTags.get(i);
                String sql = "select sum(ev.workHour) from tr_work_event_tag et inner join tb_work_event ev on et.eventId = ev.id " +
                        "where et.tagId = ? and ev.startDate >= ? and ev.endDate <= ? and ev.status = ?";
                Query query = this.eventTagDao.getSQLQuery(sql);
                query.setInteger(0, eventTag.getTagId());
                query.setTimestamp(1, firstDate);
                query.setTimestamp(2, endDate);
                query.setString(3, EventStatus.Normal.toString());
                eventTag.setWorkHour((Integer)query.uniqueResult());
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

解决方案 »

  1.   

    POJO没用过,query.list()返回的类型是List的吧?强转的话,应该类似这个例子:
    List list1 =new ArrayList();
    list1.add(new Object());
    List<B> list2 = (List<B>)list1;
    B b = list2.get(0);//这里会报运行时异常应该属于无泛型转为有泛型时,经常碰到的问题:无泛型时增加不确定的对象,强转为有泛型list使用,运行时转换为泛型类报错ClassCastException。LZ试试不要用*方式查询,把类中有的字段在sql中明确查出来,这样转对应class就应该没问题了。否则要改类结构。
      

  2.   

    这是因为java泛型不完善导致的问题,事实上,泛型强制类型转换java什么都不做,类型检查也不做,所以你的这个:List<EventTag> eventTags = (List<EventTag>)query.list();运行绝对不会出错,但会有编译警告,即使你写成List<String> eventTags = (List<String>)query.list();也不会错,因为这句话java什么都没做,java把所有泛型类型都视为Object,所以强制类型转换多少次都是一样的,编译后java会把List<EventTag> eventTags 当做List eventTags看待,但EventTag eventTag = eventTags.get(i);这个时候java反而会进行强制类型转换,因为不管是List<String>还是List<EventTag>,编译后java都把他们当做List,所以eventTags.get(i)返回值类型是Object,这里隐含了一个强制类型转换,把Object转为EventTag,这时候当然错了,因为eventTags.get(i)的类型是Object[]无法转换为EventTag,
      

  3.   

    所以你这句就错了:List<EventTag> eventTags = (List<EventTag>)query.list();应该改为List<Object[]> eventTags = (List<Object[]>)query.list();
      

  4.   

    query.uniqueResult()返回是Object吧,有没有试过这么写?
    Integer.parseInt(query.uniqueResult().toString());