Java JPA 实体何时以及为什么应该实现 Serializable 接口?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2020904/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 02:40:13  来源:igfitidea点击:

When and why JPA entities should implement Serializable interface?

javahibernateserializationormjpa

提问by Roman

The question is in the title. Below I just described some of my thoughts and findings.

问题在标题中。下面我只是描述了我的一些想法和发现。

When I had very simple domain model (3 tables without any relations) all my entities did NOT implement Serializable.

当我有非常简单的域模型(没有任何关系的 3 个表)时,我的所有实体都没有实现 Serializable。

But when domain model became more complex I got RuntimeException which said that one of my entities didn't implement Serializable.

但是当域模型变得更加复杂时,我得到了 RuntimeException,它说我的一个实体没有实现 Serializable。

I use Hibernate as a JPA implementation.

我使用 Hibernate 作为 JPA 实现。

I wonder:

我想知道:

  1. Is it vendor-specific requirement/behavior?
  2. What happens with my serializable entities? Should they be serializable for storing or for transferring?
  3. At which moment it becomes necessary to make my entity serializable?
  1. 它是供应商特定的要求/行为吗?
  2. 我的可序列化实体会发生什么?它们应该可序列化以进行存储还是传输?
  3. 什么时候有必要使我的实体可序列化?

采纳答案by Aaron Digulla

This usually happens if you mix HQL and native SQL queries. In HQL, Hibernate maps the types you pass in to whatever the DB understands. When you run native SQL, then you must do the mapping yourself. If you don't, then the default mapping is to serialize the parameter and send it to the database (in the hope that it does understand it).

如果您混合使用 HQL 和本机 SQL 查询,通常会发生这种情况。在 HQL 中,Hibernate 将您传入的类型映射到 DB 理解的任何类型。当您运行本机 SQL 时,您必须自己进行映射。如果不这样做,则默认映射是序列化参数并将其发送到数据库(希望它确实理解它)。

回答by Bozho

You need your entities to be Serializableif you need to transfer them over-the-wire (serialize them to some other representation), store them in http session (which is in turn serialized to hard disk by the servlet container), etc.

Serializable如果您需要通过网络传输它们(将它们序列化为其他表示形式),将它们存储在 http 会话中(依次由 servlet 容器序列化到硬盘)等,则需要您的实体。

Just for the sake of persistence, Serializableis not needed, at least with Hibernate. But it is a best practice to make them Serializable.

只是为了持久化,Serializable是不需要的,至少用Hibernate。但最好的做法是制作它们Serializable

回答by jarnbjo

Classes must implement Serializable if you want to serialize them. This is not directly related to JPA and the JPA specification does not require that entities are serializable. If Hibernate really complains about this, I suppose it is a Hibernate bug, but I suppose that you directly or indirectly are doing something else with the entities, which require them to be serializable.

如果要序列化类,则必须实现 Serializable。这与 JPA 没有直接关系,并且 JPA 规范不要求实体是可序列化的。如果 Hibernate 真的抱怨这个,我想这是一个 Hibernate 错误,但我想你直接或间接地对实体做了一些其他的事情,这需要它们是可序列化的。

回答by Conor

According to JPA Spec:

根据 JPA 规范:

If an entity instance is to be passed by value as a detached object (e.g., through a remote interface), the entity class must implement the Serializable interface.

如果实体实例要作为分离对象按值传递(例如,通过远程接口),则实体类必须实现 Serializable 接口。

"JSR 220: Enterprise JavaBeansTM,Version 3.0 Java Persistence API Version 3.0, Final Release May 2, 2006"

“JSR 220:Enterprise JavaBeansTM,3.0 版 Java Persistence API 3.0 版,2006 年 5 月 2 日最终发布”

回答by Avner Levy

I believe your problem is related to having a field of a complex type (class) which isn't annotated. In such cases the default handling will be storing the object in its serialized form in the database (which probably isn't what you meant to do) Example:

我相信您的问题与具有未注释的复杂类型(类)的字段有关。在这种情况下,默认处理将以序列化形式将对象存储在数据库中(这可能不是您想要做的)示例:

Class CustomerData {
    int getAge();
    void setAge(int age);
}

@Entity
Class Customer {
  CustomerData getCustomerData();
  void setCustomerData(CustomerData data)
}

In the above case the CustomerData will be saved in a byte array field in the database in its serialized form.

在上述情况下,CustomerData 将以其序列化形式保存在数据库中的字节数组字段中。

回答by Sym-Sym

To complement the nice answer of Conor who referred to the JSR-317 specifications. Typically, EAR projects consist of an EJB module with the EJBs exposed via a remote interface. In this one case you need to make your entity beans serializable as they are aggregated in the remote EJB and are built to be wired through the network.

为了补充提到 JSR-317 规范的 Conor 的好回答。通常,EAR 项目由一个 EJB 模块和通过远程接口公开的 EJB 组成。在这种情况下,您需要使实体 bean 可序列化,因为它们在远程 EJB 中聚合并构建为通过网络连接。

A JEE6 war project without CDI: can contain EJB lite backed by non-serializable JPA entities.

没有 CDI 的 JEE6 战争项目:可以包含由不可序列化的 JPA 实体支持的 EJB lite。

A JEE6 war project with CDI: Beans that use session, application, or conversation scope must be serializable, but beans that use request scope do not have to be serializable.Thus the underlying JPA entity beans -if any- would follow the same semantics.

带有 CDI 的 JEE6 战争项目:使用会话、应用程序或对话范围的 Bean 必须可序列化,但使用请求范围的 Bean 不必可序列化。因此,底层 JPA 实体 bean - 如果有的话 - 将遵循相同的语义。

回答by aman maharjan

According to the hibernate docs, while using @JoinColumn annotation:

根据hibernate docs,在使用 @JoinColumn 注释时:

It has one more parameters named referencedColumnName. This parameter declares the column in the targeted entity that will be used to the join. Note that when using referencedColumnNameto a non primary key column, the associated class has to be Serializable.

它还有一个名为 的参数referencedColumnName。此参数声明目标实体中将用于连接的列。请注意,当referencedColumnName用于非主键列时,关联的类必须是Serializable.

回答by Amalgovinus

This is also the error that's thrown when you pass an incorrectly-typed ID as the second param to something like em.find() (i.e. passing the entity itself rather than its ID). I haven't found it yet necessary to actually declare JPA entities serializable--it's not really necessary unless you're using referencedColumnName as described by aman.

这也是当您将错误类型的 ID 作为第二个参数传递给 em.find() 之类的东西(即传递实体本身而不是其 ID)时引发的错误。我还没有发现实际上有必要声明 JPA 实体可序列化——除非您使用 aman 描述的 referencedColumnName,否则这不是真的必要。

回答by tamil

remote hit using postman or ajax or angular js etc....., may cause the repeat cycle with StackOverflow exception with Hymanson fasterxml.So, it is better to use serializer.

使用 postman 或 ajax 或 angular js 等远程命中.....,可能会导致与 Hymanson fastxml 的 StackOverflow 异常的重复循环。所以,最好使用序列化程序。

回答by Michal

  1. At which moment it becomes necessary to make my entity serializable?
  1. 什么时候有必要使我的实体可序列化?

Implementing ehcache with diskstore as second level cache (i.e. using @Cacheableannotation on entity or repository/service method) requires Serializable, otherwise the cache will fail (NotSerializableException) to write the entity to the disk cache.

使用 diskstore 作为二级缓存实现 ehcache(即@Cacheable在实体或存储库/服务方法上使用注解)需要 Serializable,否则缓存将失败 ( NotSerializableException) 将实体写入磁盘缓存。