为什么这个类在使用hibernate时应该实现java.io.Serializable?

时间:2011-02-07 05:17:36

标签: java hibernate

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

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

方法

Domain domain = (Domain) objects[0];
Query q = session.createQuery("FROM PreprocessedMessage WHERE domain = ?");
q.setEntity(0, domain);
return q.list(); // this line

例外:

java.lang.ClassCastException: idv.petrie.prtm.model.Tweet cannot be cast to 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

package idv.petrie.prtm.model;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class PreprocessedMessage extends GeneticMessage {

    private GeneticMessage message;

    private Set dependencies;

    private Set tokens;

    public PreprocessedMessage() {
        super();
    }

    public PreprocessedMessage(GeneticMessage message, String content) {
        this();
        this.setMessage(message);
        this.setContent(content);
        this.setDomain(message.getDomain());
    }

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

    public PreprocessedMessage(GeneticMessage message,
            Set dependencies) {
        this(message);
        this.dependencies = dependencies;
    }

    public static Collection convertToCollection(
            Collection messages) {
        Collection result = new HashSet();
        for (GeneticMessage message : messages) {
            result.add(new PreprocessedMessage(message));
        }
        return result;

    }

    public void setMessage(GeneticMessage message) {
        this.message = message;
    }

    public GeneticMessage getMessage() {
        return message;
    }

    public Set getDependencies() {
        return dependencies;
    }

    public void setDependencies(Set dependencies) {
        for (Dependency d : dependencies) {
            d.setMessage(this);
        }
        this.dependencies = dependencies;
    }

    public Collection getTokens() {
        return tokens;
    }

    public void setTokens(Set tokens) {
        for (Token t : tokens) {
            t.setMessage(this);
        }
        this.tokens = tokens;
    }

}

Tweet.java

package idv.petrie.prtm.model;

import java.util.Date;

public class Tweet extends GeneticMessage {

    private long tweetId;

    private Date createdAt;

    private long fromUserId;

    public Tweet() {
        super();
    }

    public Tweet(String content) {
        this();
        setContent(content);
    }

    public Date getCreatedAt() {
        return createdAt;
    }

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

    public long getFromUserId() {
        return fromUserId;
    }

    public void setFromUserId(long fromUserId) {
        this.fromUserId = fromUserId;
    }

    public void setTweetId(long tweetId) {
        this.tweetId = tweetId;
    }

    public long getTweetId() {
        return tweetId;
    }

}

GeneticMessage.java


package idv.petrie.prtm.model;

import java.util.Date;

public class GeneticMessage implements Comparable {

    public enum Status {
        NEW(0), PREPROCESSED(1);
        private int id;

        private Status(int id) {
            this.id = id;
        }

        public int getId() {
            return id;
        }
    }

    private long id;

    private Date modifiedAt;

    private String content;

    private Status status;

    private Domain domain;

    public GeneticMessage() {
        setModifiedAt();
        setStatus(Status.NEW);
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

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

    public Date getModifiedAt() {
        return modifiedAt;
    }

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

    public Status getStatus() {
        return status;
    }

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

    public Domain getDomain() {
        return domain;
    }

    public int compareTo(GeneticMessage o) {
        String content = this.getContent();
        String anotherContent = o.getContent();
        return content.compareTo(anotherContent);
    }

    public void setModifiedAt(Date modifiedAt) {
        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>

2 个答案:

答案 0 :(得分:5)

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

有可能(虽然我无法从OP给出的配置xmls中告诉它)tweetId不是Tweet的主键,这就是为什么它是唯一需要Serializable的类。它被报告为Hibernate中的一个错误。 (https://hibernate.atlassian.net/browse/HHH-7668)。

总结:如果要在Hibernate对象之间建立关系,只需使用主键作为链接列。否则,使链接对象Serializable并且也可以。 : - )

答案 1 :(得分:1)

HQL或SQL函数中的所有参数都必须是可序列化的。如果不是,那么Hibernate当然也无法将其传递给数据库层。