为什么这个类在我使用 hibernate 时应该实现 java.io.Serializable?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4918262/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why this class should implement java.io.Serializable when I using hibernate?
提问by Petrie Wong
This exception only happened when Tweet Class
was used. I cannot find the reason why I should use Serializable
. I did the mapping myself in GeneticMessage.hbm.xml
. All the types (long & Date) in Tweet Class are basic type in Hibernate (I think so).
此异常仅在Tweet Class
使用时发生。我找不到我应该使用Serializable
. 我自己在GeneticMessage.hbm.xml
. Tweet Class 中的所有类型(long & Date)都是 Hibernate 中的基本类型(我认为是)。
Actually, the problem can be solved by just implementing Serializable for Tweet as mentioned in the Exception. But I still want to know the reason.
实际上,只要按照异常中提到的为 Tweet 实现 Serializable 就可以解决这个问题。但我还是想知道原因。
Method
方法
Domain domain = (Domain) objects[0]; Query q = session.createQuery("FROM PreprocessedMessage WHERE domain = ?"); q.setEntity(0, domain); return q.list(); // this line
Exception:
例外:
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.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
预处理消息.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
推文.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
遗传信息.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
遗传信息.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>
回答by Javi Armendáriz
6 years has passed since this question, but here's my 5 cents for those who stumble upon this problem:
这个问题已经过去了 6 年,但对于那些偶然发现这个问题的人,这是我的 5 美分:
It's possible (although I cannot tell it from the config xmls given by the OP) that tweetId
is not the primary key of Tweet
and that's why it's the only class that requires to be Serializable. It is reported as a bug in Hibernate. (https://hibernate.atlassian.net/browse/HHH-7668).
有可能(尽管我无法从 OP 提供的配置 xmls 中分辨出来)它tweetId
不是 的主键,Tweet
这就是为什么它是唯一需要可序列化的类的原因。它被报告为 Hibernate 中的一个错误。(https://hibernate.atlassian.net/browse/HHH-7668)。
In Summary: if you want to make a relation between Hibernate objects, just use the primary key as the link column. Otherwise, make the linked object Serializable and that'll work as well. :-)
总结:如果你想在 Hibernate 对象之间建立关系,只需使用主键作为链接列。否则,使链接对象可序列化,这样也能正常工作。:-)
回答by Daniel
All parameters in HQL or SQL functions must be Serializable. If it is not, there is certainly also no way for Hibernate to pass it to the database layer.
HQL 或 SQL 函数中的所有参数都必须是可序列化的。如果不是,Hibernate当然也没有办法把它传递给数据库层。