为啥当我使用hibernate时这个类应该实现java.io.Serializable?
Posted
技术标签:
【中文标题】为啥当我使用hibernate时这个类应该实现java.io.Serializable?【英文标题】:Why this class should implement java.io.Serializable when I using hibernate?为什么当我使用hibernate时这个类应该实现java.io.Serializable? 【发布时间】:2011-06-22 12:59:04 【问题描述】:此异常仅在使用 Tweet Class
时发生。我找不到我应该使用Serializable
的原因。我自己在GeneticMessage.hbm.xml
中进行了映射。 Tweet Class 中的所有类型(long 和 Date)都是 Hibernate 中的基本类型(我认为是这样)。
实际上,只要实现异常中提到的Serializable for Tweet就可以解决这个问题。但我还是想知道原因。
方法
域域=(域)对象[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消息; 私有设置依赖项; 私有集令牌; 公共预处理消息() 极好的(); public PreprocessedMessage(GeneticMessage 消息,字符串内容) 这(); this.setMessage(消息); this.setContent(内容); this.setDomain(message.getDomain()); 公共预处理消息(遗传消息消息) 这(消息,message.getContent()); 公共 PreprocessedMessage(GeneticMessage 消息, 设置依赖) 这条信息); this.dependencies = 依赖项; 公共静态集合 convertToCollection( 收集消息) 收集结果 = new HashSet(); 对于(GeneticMessage 消息:消息) result.add(new PreprocessedMessage(message)); 返回结果; 公共无效setMessage(GeneticMessage消息) this.message = 消息; 公共遗传信息 getMessage() 返回消息; 公共设置 getDependencies() 返回依赖项; 公共无效 setDependencies(设置依赖项) 对于(依赖项 d:依赖项) d.setMessage(this); this.dependencies = 依赖项; 公共集合 getTokens() 返回代币; 公共无效 setTokens(设置令牌) 对于(令牌 t:令牌) t.setMessage(this); this.tokens = 代币;
Tweet.java
包 idv.petrie.prtm.model; 导入 java.util.Date; 公共类推文扩展GeneticMessage 私人长推文ID; 私人创建日期在; 私人长 fromUserId; 公共推文() 极好的(); 公共推文(字符串内容) 这(); 设置内容(内容); 公共日期 getCreatedAt() 返回创建时间; 公共无效 setCreatedAt(创建日期) this.createdAt = createdAt; 公共长 getFromUserId() 从用户ID返回; 公共无效 setFromUserId(long fromUserId) this.fromUserId = fromUserId; 公共无效 setTweetId(长推文 ID) this.tweetId = tweetId; 公共长 getTweetId() 返回推文ID;
GeneticMessage.java
包 idv.petrie.prtm.model; 导入 java.util.Date; 公共类 GeneticMessage 实现 Comparable 公共枚举状态 新的(0),预处理的(1); 私人 int id; 私人状态(int id) 这个.id = id; 公共 int getId() 返回标识; 私人长ID; 私人修改日期; 私有字符串内容; 私人状态状态; 私有域域; 公共遗传消息() setModifiedAt(); 设置状态(状态。新); 公共长 getId() 返回标识; 公共无效setId(长ID) 这个.id = id; 公共字符串 getContent() 返回内容; 公共无效 setContent(字符串内容) this.content = 内容; 公共无效 setModifiedAt() this.modifiedAt = new Date(); 公共日期 getModifiedAt() 返回修改后; 公共无效setStatus(状态状态) this.status = 状态; 公共状态 getStatus() 返回状态; 公共无效 setDomain(域域) this.domain = 域; 公共域 getDomain() 返回域; 公共 int compareTo(GeneticMessage o) 字符串内容 = this.getContent(); 字符串 anotherContent = o.getContent(); return content.compareTo(anotherContent); 公共无效 setModifiedAt(修改日期) 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>
【问题讨论】:
[类似问题已被问及回答..][1] [1]:***.com/questions/2020904/… 对不起,我还是听不懂。是“来自 PreprocessedMessage WHERE 域 = 吗?”混合 HQL 和原生 SQL 查询?我刚刚编辑了我的问题以使其清楚。 q.setEntity(0, domain);这条线导致了问题。域类应该是可序列化的。 我明白你的意思。但是 domain 是在另一个 hbm.xml 中定义的(也就是 Domain.hbm.xml,这里没有贴出代码)。并且异常要求我为 Tweet 实现 Serializable? 你知道为什么有些实体需要可序列化而有些不需要吗? 【参考方案1】:这个问题已经过去了 6 年,但是对于那些偶然发现这个问题的人来说,这是我的 5 美分:
tweetId
可能不是Tweet
的主键(尽管我无法从 OP 给出的配置 xml 中看出这一点),这就是为什么它是唯一需要可序列化的类的原因。它被报告为 Hibernate 中的一个错误。 (https://hibernate.atlassian.net/browse/HHH-7668)。
总结:如果要在 Hibernate 对象之间建立关系,只需使用主键作为链接列。否则,使链接对象可序列化,这也可以。 :-)
【讨论】:
我有同样的问题,我添加了可序列化但它不起作用【参考方案2】:HQL 或 SQL 函数中的所有参数都必须是可序列化的。如果不是,Hibernate 肯定也没有办法将其传递给数据库层。
【讨论】:
但我没有为用作参数的其他类实现 Serializable 其实所有类。这意味着GeneticMessage,Tweet,PreprocessedMessage,Token,Dependency等......以上是关于为啥当我使用hibernate时这个类应该实现java.io.Serializable?的主要内容,如果未能解决你的问题,请参考以下文章
为啥当我使用 Spring-Data 时 Maven 会添加 Hibernate Jars
当我应该在 boostrap 轮播中添加活动类时,为啥要在左边添加类
为啥在这个 Hibernate 映射中使用 @ManyToOne 而不是 @OneToOne?
当我所做的只是一个列表时,为啥 Hibernate 会删除我的集合条目?
为啥当我将 hbm2ddl.auto 设置为创建时,Hibernate 会抛出 SQLGrammarException 说表/视图不存在?