为什么在使用休眠模式时此类应实现java.io.Serializable?

Pet*_*ong 1 java hibernate

此异常仅在Tweet Class使用时发生。我找不到我应该使用的理由Serializable。我自己在中进行了映射GeneticMessage.hbm.xml。Tweet类中的所有类型(long和Date)都是Hibernate中的基本类型(我认为是)。

实际上,仅通过实现Exception中提到的Tweet的Serializable可解决该问题。但是我仍然想知道原因。

方法

域domain =(域)对象[0];
查询q = session.createQuery(“ FROM PreprocessedMessage WHERE domain =?”);
q.setEntity(0,domain);
返回q.list(); //这行

例外:

java.lang.ClassCastException:idv.petrie.prtm.model.Tweet无法转换为java.io.Serializable
    org.hibernate.type.CollectionType.getKeyOfOwner(CollectionType.java:381)
    org.hibernate.type.CollectionType.resolve(CollectionType.java:425)
    org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:139)
    org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:982)
    org.hibernate.loader.Loader.doQuery(Loader.java:857)
    org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
    org.hibernate.loader.Loader.doList(Loader.java:2533)
    org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
    org.hibernate.loader.Loader.list(Loader.java:2271)
    org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:452)
    org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)
    org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
    org.hibernate.impl.SessionImpl.list(SessionImpl.java:1268)
    org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
    idv.petrie.prtm.model.helper.PreprocessedMessageHelper $ 3.execute(PreprocessedMessageHelper.java:66)
    idv.petrie.prtm.util.ModelHelper.execute(ModelHelper.java:36)
    idv.petrie.prtm.model.helper.PreprocessedMessageHelper.findMessageByDomain(PreprocessedMessageHelper.java:69)
    idv.petrie.prtm.servlet.MessageEvaluationServlet.doGet(MessageEvaluationServlet.java:44)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

PreprocessedMessage.java

软件包idv.petrie.prtm.model;

导入java.util.Collection;
导入java.util.HashSet;
导入java.util.Set;

公共类PreprocessedMessage扩展了GeneticMessage {

    私人GeneticMessage消息;

    私有集合依赖项;

    专用Set令牌;

    公共PreprocessedMessage(){
        超();
    }

    public PreprocessedMessage(GeneticMessage消息,字符串内容){
        这个();
        this.setMessage(message);
        this.setContent(content);
        this.setDomain(message.getDomain());
    }

    public PreprocessedMessage(GeneticMessage消息){
        this(message,message.getContent());
    }

    公共PreprocessedMessage(GeneticMessage消息,
            设置依赖项){
        这条信息);
        this.dependencies =依赖关系;
    }

    公共静态集合convertToCollection(
            收藏邮件){
        收集结果= new HashSet();
        对于(GeneticMessage消息:消息){
            result.add(new PreprocessedMessage(message));
        }
        返回结果;

    }

    公共无效setMessage(GeneticMessage消息){
        this.message =消息;
    }

    公共GeneticMessage getMessage(){
        返回消息;
    }

    公共设置getDependencies(){
        返回依赖关系;
    }

    公共无效setDependencies(设置依赖项){
        for(依赖项d:依赖项){
            d.setMessage(this);
        }
        this.dependencies =依赖关系;
    }

    公共集合getTokens(){
        返回令牌;
    }

    公共无效setTokens(设置令牌){
        对于(令牌t:令牌){
            t.setMessage(this);
        }
        this.tokens =令牌;
    }

}

Tweet.java

软件包idv.petrie.prtm.model;

导入java.util.Date;

公共类推文扩展了GeneticMessage {

    私人long tweetId;

    私人Date createdAt;

    私人长fromUserId;

    公共Tweet(){
        超();
    }

    公共推文(字符串内容){
        这个();
        setContent(content);
    }

    公共日期getCreatedAt(){
        返回createdAt;
    }

    public void setCreatedAt(Date createdAt){
        this.createdAt = createdAt;
    }

    公共长getFromUserId(){
        fromUserId返回;
    }

    公共无效setFromUserId(long fromUserId){
        this.fromUserId = fromUserId;
    }

    公共无效setTweetId(long tweetId){
        this.tweetId = tweetId;
    }

    公共长getTweetId(){
        返回tweetId;
    }

}

GeneticMessage.java

软件包idv.petrie.prtm.model;

导入java.util.Date;

公共类GeneticMessage实现Comparable {

    公共枚举状态{
        NEW(0),PREPROCESSED(1);
        私人int ID;

        私人状态(int id){
            this.id = id;
        }

        public int getId(){
            返回ID;
        }
    }

    私人长号;

    私人Date ModifyAt;

    私有字符串内容;

    私人身份状态;

    私有域域;

    公共GeneticMessage(){
        setModifiedAt();
        setStatus(Status.NEW);
    }

    公共长getId(){
        返回ID;
    }

    公共无效setId(长id){
        this.id = id;
    }

    公共字符串getContent(){
        返回内容;
    }

    公共无效setContent(字符串内容){
        this.content =内容;
    }

    公共无效setModifiedAt(){
        this.modifiedAt = new Date();
    }

    公开日期getModifiedAt(){
        返回modifiedAt;
    }

    public void setStatus(状态状态){
        this.status =状态;
    }

    公共状态getStatus(){
        返回状态;
    }

    public void setDomain(域名){
        this.domain =域;
    }

    公共域getDomain(){
        返回域;
    }

    公共诠释compareTo(GeneticMessage o){
        字符串内容= this.getContent();
        字符串anotherContent = o.getContent();
        返回content.compareTo(anotherContent);
    }

    public void setModifiedAt(DatemodifiedAt){
        this.modifiedAt = modifiedAt;
    }
}

GeneticMessage.hbm.xml

<code>
<?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">

<hibernate-mapping>

    <typedef class="idv.petrie.prtm.model.GeneticMessage.Status"
        name="Status">
        <param name="enumClassName">idv.petrie.prtm.model.GeneticMessage.Status</param>
        <param name="identifierMethod">getId</param>
    </typedef>

    <class name="idv.petrie.prtm.model.GeneticMessage">
        <id name="id">
            <generator class="native" />
        </id>
        <property name="modifiedAt" />
        <property name="content" />
        <property name="status" />
        <many-to-one name="domain" class="idv.petrie.prtm.model.Domain"
            cascade="all" outer-join="true" />

        <joined-subclass name="idv.petrie.prtm.model.PreprocessedMessage">
            <key />
            <many-to-one name="message" class="idv.petrie.prtm.model.GeneticMessage"
                outer-join="true" />
            <set name="dependencies" cascade="save-update" inverse="true">
                <key property-ref="message" />
                <one-to-many class="idv.petrie.prtm.model.Dependency" />
            </set>
            <set name="tokens" cascade="save-update" inverse="true">
                <key property-ref="message" />
                <one-to-many class="idv.petrie.prtm.model.Token" />
            </set>
        </joined-subclass>

        <joined-subclass name="idv.petrie.prtm.model.Tweet">
            <key />
            <property name="tweetId" unique="true" />
            <property name="createdAt" />
            <property name="fromUserId" />
        </joined-subclass>
    </class>
</hibernate-mapping>
</code>
Run Code Online (Sandbox Code Playgroud)

小智 5

这个问题已经过去6年了,但是对于那些偶然遇到这个问题的人来说,这是我的5美分:

可能(尽管我不能从OP给出的配置xml告诉它)tweetId不是它的主键,Tweet这就是为什么它是唯一需要可序列化的类的原因。它被报告为Hibernate中的错误。(https://hibernate.atlassian.net/browse/HHH-7668)。

简介:如果要在Hibernate对象之间建立关系,只需将主键用作链接列。否则,将链接对象设置为Serializable即可。:-)