为什么hibernate强制在session.get方法中进行序列化

我看到hibernate的session.get()和load()方法只接受Serializable对象。

根据我对hibernate的理解,它将生成一个SQL语句并将其发送给DBMS。 它永远不需要通过网络发送java对象。

为什么hibernate强制对我们进行序列化?

首先,Hibernate在某些签名中使用Serializable这一事实并不意味着Hibernate 序列化任何东西,它只是意味着如果需要,参数是可序列化的。

然后,我找不到绝对的参考,但我认为最强的论点是:

  • 实体ID用作缓存的密钥(第一级,第二级),并且可以通过网络发送

一些较弱的参数(或根本不参数):

  • Session本身可以被潜在地序列化(例如存储在HttpSession
  • Hibernate需要entityId的超类型(包括复合PK)

考虑到所有这些,我认为强制API的用户通过Serializable entityId ,这允许不关闭任何门并避免任何后期限制(oops,你不能激活二级缓存,因为这个pk不是Serializable )。 这是IMO比使用Object更好的设计决策。 说实话,我没有看到任何烦恼。

这不是真的。 来自Javadoc ,相关方法的签名是:

 public Object get(Class clazz, Serializable id) ... public Object load(Class theClass, Serializable id) ... 

(为简洁起见,省略了不相关的部分和其他重载版本)。

因此,要加载的实体可以是任何类,只有它的标识符需要可序列化。

根据来自Java Persistence with Hibernate的引用,实体确实不是可序列化的。 13.3.2:

持久化实例以反汇编forms存储在二级缓存中。 将反汇编视为一个类似于序列化的过程(但算法比Java序列化要快得多)。

所以我猜测标识符(在查询缓存中)也没有序列化。 我找不到任何解释为什么id被声明为Serializable ,并且缺乏这个,我只能猜测。 API需要一个id参数的类型,它应该是至少常用的标识符类型NumberString的常见超类型,除了ObjectSerializable是唯一的选择。

我认为这是因为对缓存的支持。 当使用持久高速缓存或通过网络分发对象的任何高速缓存时,您需要有一种方法来确保对象可以以通用格式传输,在本例中是Java序列化。

坦率地说,我没有看到任何其他方式。 如果您不是定义表结构并生成插入语句以容纳对象,那么生成的SQL语句本身就是一个字符串,它会将另一个文本字符串(您的序列化数据)插入到表的字段中。 无论你在数据库中插入什么都必须是一个字符串,在这种情况下,它不能是一个具有语言相关方法的对象,除非你明确设计一个表来存储这样的数据。