我看到hibernate的session.get()和load()方法只接受Serializable对象。
根据我对hibernate的理解,它将生成一个SQL语句并将其发送给DBMS。它永远不需要通过网络发送java对象。
为什么hibernate强制对我们进行序列化?
答案 0 :(得分:5)
首先,Hibernate在某些签名中使用Serializable
的事实并不意味着Hibernate 将序列化任何东西,它只是意味着如果需要,参数可以序列化。 / p>
然后,我找不到绝对的参考,但我认为最强的论据是:
一些较弱的论点(或根本不论证):
Session
本身可能会被序列化(例如存储在HttpSession
中)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
参数的类型,该参数应至少是常用标识符类型Number
和String
的常见超类型,除了Object
之外,{ {1}}是唯一的选择。
答案 2 :(得分:0)
我认为这是因为对缓存的支持。当使用持久性缓存或通过网络分发对象的任何缓存时,您需要有一种方法来确保对象可以以通用格式传输,在本例中是Java序列化。
答案 3 :(得分:0)
坦白说,我没有其他任何方式。如果您不是定义表结构并生成插入语句以容纳对象,那么生成的SQL语句本身就是一个字符串,它会将另一个文本字符串(您的序列化数据)插入到表的字段中。无论你在数据库中插入的是什么,在这种情况下都必须是一个字符串,它不能是一个具有语言相关方法的对象,除非你明确地设计一个表来存储这样的数据。