问题出在 Headers 中 . 下面我刚才描述了我的一些想法和发现 .
当我有非常简单的域模型(3个没有任何关系的表)时,我的所有实体都没有实现Serializable .
但是当域模型变得更复杂时,我得到了RuntimeException,它说我的一个实体没有实现Serializable .
我使用Hibernate作为JPA实现 .
我想知道:
-
是特定于供应商的要求/行为吗?
-
我的可序列化实体会发生什么?它们是否可以序列化以便存储或传输?
-
此时有必要让我的实体可序列化吗?
11 回答
如果需要通过线程传输它们(将它们序列化为其他表示形式),则需要将实体存储为
Serializable
,将它们存储在http会话中(由servlet容器依次序列化为硬盘)等 .只是为了持久化,不需要
Serializable
,至少在Hibernate中是这样 . 但是最好的做法是让它们成为Serializable
.根据hibernate docs,在使用@JoinColumn注释时:
如果要序列化类,则必须实现Serializable . 这与JPA没有直接关系,JPA规范不要求实体可序列化 . 如果Hibernate真的抱怨这个,我认为它是一个Hibernate错误,但我想你直接或间接地对实体做了其他事情,这要求它们是可序列化的 .
根据JPA规范:
“JSR 220:Enterprise JavaBeansTM,Version 3.0 Java Persistence API Version 3.0,Final Release May 2,2006”
请参考http://www.adam-bien.com/roller/abien/entry/do_jpa_entities_have_to它说,只需要通过IIOP或JRMP(RMI)在JVM实例之间传输数据来实现java.io.Serializable . 在纯Web应用程序的情况下,域对象有时存储在HTTPSession中以用于缓存/优化目的 . http会话可以序列化(钝化)或群集 . 在这两种情况下,所有内容都必须是可序列化的 .
为了补充Conor提到JSR-317规范的好答案 . 通常,EAR项目由EJB模块组成,EJB模块通过远程接口公开EJB . 在这种情况下,您需要使实体bean可序列化,因为它们在远程EJB中聚合并构建为通过网络连接 .
没有CDI的JEE6 war项目:可以包含由不可序列化的JPA实体支持的EJB lite .
与CDI的JEE6战争项目:Beans that use session, application, or conversation scope must be serializable, but beans that use request scope do not have to be serializable.因此,基础JPA实体bean -if any将遵循相同的语义 .
使用postman或ajax或angular js等进行远程命中,可能会导致重复循环与StackOverflow异常与Jackson fastxml.So,最好使用序列化程序 .
使用diskstore作为二级缓存实现ehcache(即在实体或存储库/服务方法上使用
@Cacheable
注释)需要Serializable,否则缓存将失败(NotSerializableException
)将实体写入磁盘缓存 .如果混合使用HQL和本机SQL查询,通常会发生这种情况 . 在HQL中,Hibernate将传入的类型映射到DB理解的任何内容 . 运行本机SQL时,必须自己进行映射 . 如果不这样做,则默认映射是序列化参数并将其发送到数据库(希望它能理解它) .
我相信你的问题与一个没有注释的复杂类型(类)的字段有关 . 在这种情况下,默认处理将在数据库中以序列化形式存储对象(这可能不是你想要做的)示例:
在上面的例子中,CustomerData将以序列化形式保存在数据库的字节数组字段中 .
这也是当您将错误键入的ID作为第二个参数传递给em.find()之类时抛出的错误(即传递实体本身而不是其ID) . 我还没有发现实际声明JPA实体可序列化的必要性 - 除非你使用aman所描述的referencedColumnName,否则它并不是必需的 .