Почему этот класс должен реализовывать java.io.Serializable, когда я использую hibernate? - PullRequest
1 голос
/ 07 февраля 2011

Это исключение произошло только при использовании Tweet Class.Я не могу найти причину, почему я должен использовать Serializable.Я сделал отображение самостоятельно в GeneticMessage.hbm.xml.Все типы (long & Date) в Tweet Class являются базовыми типами в Hibernate (я так думаю).

На самом деле, проблему можно решить, просто внедрив Serializable для 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 ]

5 голосов
/ 19 июля 2017

6 лет прошло с тех пор, как этот вопрос, но вот мои 5 центов для тех, кто наткнулся на эту проблему:

Возможно (хотя я не могу сказать это из конфигурации xmls, заданной OP), что tweetId не является первичным ключом Tweet, и именно поэтому это единственный класс, который требует Serializable. Сообщается, что это ошибка в Hibernate. (https://hibernate.atlassian.net/browse/HHH-7668).

В заключение: если вы хотите установить связь между объектами Hibernate, просто используйте первичный ключ в качестве столбца ссылок. В противном случае сделайте связанный объект Serializable, и это также будет работать. : -)

1 голос
/ 07 февраля 2011

Все параметры в функциях HQL или SQL должны быть сериализуемыми. Если это не так, Hibernate, безусловно, также не сможет передать его на уровень базы данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...