2011-02-07 4 views
1

この例外は、Tweetクラスが使用されたときにのみ発生しました。私はSerializableを使うべき理由を見つけることができません。私はGeneticMessage.hbm.xmlで自分自身でマッピングを行いました。 Tweetクラスのすべての型(long & Date)は、Hibernateの基本型です(私はそうだと思います)。私は休止状態を使用しているときにこのクラスがjava.io.Serializableを実装する必要があるのはなぜですか?

実際、この問題は、「例外」で説明したように、TweetのためのSerializableを実装するだけで解決できます。しかし、私はまだその理由を知りたい。

方法

 
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

<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> 

+0

[同様の質問が尋ねたと回答されている..] [1] [1]:http://stackoverflow.com/questions/2020904/when-and-why-jpa- entities-should-implement-serializable-interface/2020973#2020973 –

+0

申し訳ありませんが、私はまだ理解できません。 "FROM PreprocessedMessage WHERE domain =?"混合HQLとネイティブSQLクエリ?私はちょうどそれを明確にするために私の質問を編集しました。 –

+0

q.setEntity(0、domain); この行で問題が発生します。ドメインクラスは直列化可能でなければなりません。 –

答えて

1

HQLまたはSQL関数のすべてのパラメータはシリアライズ可能でなければなりません。もしそうでなければ、確実にHibernateがそれをデータベース層に渡す方法もありません。

+0

私は他のクラスのためにSerializableを実装していませんでした –

+0

どのクラスですか? – Daniel

+0

実際は、すべてのクラス。 GeneticMessage、Tweet、PreprocessedMessage、Token、Dependencyなどを意味します。 –

2

6年間、この質問経ちますが、ここではこの問題つまずく人のための私の5セントですしています

tweetIdではないこと(私はOPで与えられた設定XMLSからそれを伝えることはできませんが)それが可能ですTweetのプライマリキーです。そのため、シリアライズ可能でなければならない唯一のクラスです。これはHibernateのバグとして報告されています。 (https://hibernate.atlassian.net/browse/HHH-7668)。

要約:Hibernateオブジェクト間の関係を作成する場合は、主キーをリンク列として使用してください。それ以外の場合は、リンクされたオブジェクトをSerializableにしてください。 :-)

関連する問題