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

时间:2010-06-10 08:07:30

标签: java hibernate

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

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

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

4 个答案:

答案 0 :(得分:5)

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

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

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

一些较弱的论点(或根本不论证):

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

鉴于这一切,我认为强制API的用户传递Serializable entityId是有意义的,这样就不会关闭任何门并避免任何后期限制(哎呀,你不能激活第二级缓存,因为此pk不是Serializable)。这是IMO比使用Object更好的设计决策。说实话,我没有看到任何烦恼。

答案 1 :(得分:1)

这不是真的。 From the Javadoc,相关方法的签名是:

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

(为简洁省略了无关的部分和其他重载版本。)

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

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

  

持久化实例存储在反汇编的二级缓存中   形成。将反汇编视为一个有点像序列化的过程(算法是   然而,比Java序列化要快得多。

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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