左连接查询,在hbm.xml中有两个joined-subclass,哪个joined-subclass的类在后面,就报这个类的ClassCastException,例如本来在hbm.xml中1.java在前,2.java在后,就报1.java的ClassCastException;修改hbml.xml把2.java放在前面,1.java在后,这样报2.java的ClassCastException。下面是代码Newtracking.hbm.xml<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
    <class name="Bei.Google.PM.XML.vo.Newtracking" table="newtracking" schema="SCOTT">
        <id name="jobid" type="java.lang.String">
            <column name="JOBID" length="16" />
            <generator class="assigned">
            </generator>
        </id>
        
        <property name="csvendor" type="java.lang.String" >
<column name="CSVENDOR" length="32" not-null="false" />
</property>
        <property name="ctvendor" type="java.lang.String">
            <column name="CTVENDOR" length="32" not-null="false" />
        </property>
        <property name="newhodate" type="java.lang.String">
            <column name="NEWHODATE" length="32" not-null="true" />
        </property>
        <property name="newhbdate" type="java.lang.String">
            <column name="NEWHBDATE" length="32" not-null="true" />
        </property>
        <property name="wordcount" type="java.lang.String">
            <column name="WORDCOUNT" length="32" not-null="true" />
        </property>        <joined-subclass name="Bei.Google.PM.XML.vo.NewStatus" table="newstatus">
         <key column ="JOBID"/>
         <property name="jobstatus" type="java.lang.String" column="jobstatus"></property>
         <property name="csstatus" type="java.lang.String" column="csstatus"></property>
<property name="ctstatus" type="java.lang.String" column="ctstatus"></property>

        </joined-subclass>
        <joined-subclass name="Bei.Google.PM.XML.vo.NewVendorDeliverTime" table="newvendordelivertime">
         <key column ="JOBID"/>
         <property name="cntime" type="java.lang.String" column="cntime"></property>
<property name="cttime" type="java.lang.String" column="cttime"></property>
        </joined-subclass>
    </class>
</hibernate-mapping>
Newtracking.javapackage Bei.Google.PM.XML.vo;public class Newtracking 
private String jobid;
private String csvendor;
private String ctvendor;
private String newhodate;
private String newhbdate;
private String wordcount; public String getCsvendor() {
return csvendor;
}
public void setCsvendor(String csvendor) {
this.csvendor = csvendor;
}
public String getCtvendor() {
return ctvendor;
}
public void setCtvendor(String ctvendor) {
this.ctvendor = ctvendor;
}
public String getJobid() {
return jobid;
}
public void setJobid(String jobid) {
this.jobid = jobid;
}
public String getNewhbdate() {
return newhbdate;
}
public void setNewhbdate(String newhbdate) {
this.newhbdate = newhbdate;
}
public String getNewhodate() {
return newhodate;
}
public void setNewhodate(String newhodate) {
this.newhodate = newhodate;
}
public String getWordcount() {
return wordcount;
}
public void setWordcount(String wordcount) {
this.wordcount = wordcount;
}
}
NewStatus.javapackage Bei.Google.PM.XML.vo;public class NewStatus extends Newtracking {
private String jobstatus ;
private String csstatus ;
private String ctstatus ; public String getJobstatus() {
return jobstatus;
}
public void setJobstatus(String jobstatus) {
this.jobstatus = jobstatus;
}
public String getCsstatus() {
return csstatus;
}
public void setCsstatus(String csstatus) {
this.csstatus = csstatus;
}
public String getCtstatus() {
return ctstatus;
}
public void setCtstatus(String ctstatus) {
this.ctstatus = ctstatus;
}
}NewVendorDeliverTimepackage Bei.Google.PM.XML.vo;public class NewVendorDeliverTime extends Newtracking {
private String cntime ;
private String cttime ; public String getCntime() {
return cntime;
}
public void setCntime(String cntime) {
this.cntime = cntime;
}
public String getCttime() {
return cttime;
}
public void setCttime(String cttime) {
this.cttime = cttime;
}
}
Impl文件package Bei.Google.PM.NewSearch.impl;import java.util.*;import org.hibernate.Query;
import org.hibernate.Session;import Bei.Google.PM.NewSearch.vo.NewinfoSearchDTO;
import Bei.Google.PM.XML.vo.NewStatus;
import Bei.Google.PM.XML.vo.NewVendorDeliverTime;
import Bei.Google.PM.XML.vo.Newtracking;public class NewInfoSearchimpl implements NewSearchDAO {
private Session session; public NewInfoSearchimpl() {
this.session = SessionFactory.getSession();
}
public boolean isSearch(NewinfoSearchDTO newinfosearchdto) throws Exception {
boolean flag = false;
Newtracking nt = null;
String hql = "FROM Newtracking as t where t.jobid=?";
Query q = session.createQuery(hql);
q.setString(0, newinfosearchdto.getJobid());
Iterator iter = q.list().iterator();
if (iter.hasNext()) {
nt = (Newtracking) iter.next();
flag = true;
NewStatus ns = (NewStatus) nt;
NewVendorDeliverTime nvdt = (NewVendorDeliverTime) nt;
String lc = newinfosearchdto.getLanguagecode();
if ("zh-CN".equals(lc)) {
newinfosearchdto.setStatus(ns.getCsstatus());
newinfosearchdto.setVendor(nt.getCsvendor());
newinfosearchdto.setVendorhbd(nvdt.getCntime());
newinfosearchdto.setWordcount(nt.getWordcount());
} else if ("zh-TW".equals(lc)) {
newinfosearchdto.setStatus(ns.getCtstatus());
newinfosearchdto.setVendor(nt.getCtvendor());
newinfosearchdto.setVendorhbd(nvdt.getCttime());
newinfosearchdto.setWordcount(nt.getWordcount());
}
}
return flag;
}
}

解决方案 »

  1.   

    多谢,这个异常确实是转型错误,不过请看看我的描述,如果将joined-subclass得顺序颠倒一下,异常类会变化,也就是本来NewStatus.java配置在上NewVendorDeliverTime类在下,这时会报NewStatus.java类的CastException,如果NewStatus.java配置在下NewVendorDeliverTime类在上,这时就变成NewVendorDeliverTime.java的CastException,可以看出这两个类都可以顺利转型,而且映射应该是和实体匹配的吧,帮忙看看问题是不是出在Impl上了呢?
      

  2.   

    这个问题跟joined-subclass得顺序颠不颠倒没有关系。问题出在那个NewInfoSearchimpl类里。具体分析请看下面代码的注解:public class NewInfoSearchimpl implements NewSearchDAO {
        private Session session;    public NewInfoSearchimpl() {
            this.session = SessionFactory.getSession();
        }
        public boolean isSearch(NewinfoSearchDTO newinfosearchdto) throws Exception {
            boolean flag = false;
            Newtracking nt = null;
            String hql = "FROM Newtracking as t where t.jobid=?";
            Query q = session.createQuery(hql);
            q.setString(0, newinfosearchdto.getJobid());
            Iterator iter = q.list().iterator();
            if (iter.hasNext()) {
                nt = (Newtracking) iter.next();//这里会得到Newtracking类的一个实例nt
                                                     //这个实例nt可能是NewStatus
                                               //也可能是NewVendorDeliverTime
                flag = true;            NewStatus ns = (NewStatus) nt; //那么这行就有问题了
                                                     //如果nt是NewVendorDeliverTime的话
                                                     //这里就会甩出ClassCastException            NewVendorDeliverTime nvdt = (NewVendorDeliverTime) nt; //同理这行也有问题了
                                                      //如果nt是NewStatus的话
                                                     //这里就会甩出ClassCastException
                //根据以上分析,上面那两行代码可改为:
                //NewStatus ns = null;
                //NewVendorDeliverTime nvdt = null;
                //if(nt instanceof NewStatus){
                //    ns = (NewStatus) nt
                //}else if(nt instanceof NewVendorDeliverTime) {
                //    nvdt = (NewVendorDeliverTime) nt;
                //}
                //这样下面的代码也要做相应修改                      String lc = newinfosearchdto.getLanguagecode();
                if ("zh-CN".equals(lc)) {
                    newinfosearchdto.setStatus(ns.getCsstatus());
                    newinfosearchdto.setVendor(nt.getCsvendor());
                    newinfosearchdto.setVendorhbd(nvdt.getCntime());
                    newinfosearchdto.setWordcount(nt.getWordcount());
                } else if ("zh-TW".equals(lc)) {
                    newinfosearchdto.setStatus(ns.getCtstatus());
                    newinfosearchdto.setVendor(nt.getCtvendor());
                    newinfosearchdto.setVendorhbd(nvdt.getCttime());
                    newinfosearchdto.setWordcount(nt.getWordcount());
                }
            }
            return flag;
        }
    }
      

  3.   

    这点确实有问题,我感到Impl有问题,不过我把Impl分成两个Impl了NewStatus ns = (NewStatus) nt转型放在一个Impl里面,NewVendorDeliverTime nvdt = (NewVendorDeliverTime) nt放在另一个Impl里面;这样在action里面执行这两个Impl,可是CastException还是如上述顺序出现;最奇怪的是我将执行NewStatus ns = (NewStatus) nt转型的那个Impl注释掉,只执行NewVendorDeliverTime nvdt = (NewVendorDeliverTime) nt那个Impl,结果问题还是一样的,在执行
    Iterator iter1 = q.list().iterator();
    if (iter.hasNext()) {nt1 = (Newtracking) iter1.next();
    NewVendorDeliverTime nvdt = (NewVendorDeliverTime) nt1;
    这段时,执行Iterator iter1 = q.list().iterator();时栈中的elementData就已经是NewStatus,也就是时,nt1 = (Newtracking) iter1.next();这行nt1将被转型成NewStatus,这下再执行NewVendorDeliverTime nvdt = (NewVendorDeliverTime) nt1;时必然出现ClassCastExceptoin。可是问题是为什么Iterator iter1 = q.list().iterator();这行会将Newtracking转型成NewStatus呢?
      

  4.   

    那是因为这行代码: String hql = "FROM Newtracking as t where t.jobid=?";
    如果这个jobid对应的是一个NewStatus,hibernate就会给你一个NewStatus。同理如果这个jobid对应的是一个NewVendorDeliverTime,hibernate就会给你一个NewVendorDeliverTime
      

  5.   

    jobid是主键,它在Newtracking,NewStatus和NewVendorDeliverTime中都是主键,难道不是如此关联吗?怎么会给我NewStatus,应该给我Newtracking(Newtracking父类,NewStatus和NewVendorDeliverTime都继承Newtracking),然后依我的类型转换转型啊~~!请follow up~~
      

  6.   


    不错,jobid在三个表中都是主键。在读取数据时hibernate会使用outer join然后返回相应的类。楼主可看看这方面的文档。
      

  7.   


    可能由于我没有表述清楚,其实Newtracking中每个jobid在NewStatus和NewVendorDeliverTime都有对应的行,所以依靠jobid无法让hibernate去判断是NewStatus型和NewVendorDeliverTime型,我已将NewVendorDeliverTime作为NewStatus的子类,这样就解决问题了;
    虽然islandrabbit兄弟没有给我精确答案,但“如果这个jobid对应的是一个NewStatus,hibernate就会给你一个NewStatus。同理如果这个jobid对应的是一个NewVendorDeliverTime,hibernate就会给你一个NewVendorDeliverTime”这句话我细细思考后,得出了答案。结贴~~!