【问题标题】:why hibernate forcing serialization in session.get method为什么休眠在 session.get 方法中强制序列化
【发布时间】:2011-03-02 01:22:54
【问题描述】:

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

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

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

【问题讨论】:

    标签: java hibernate


    【解决方案1】:

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

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

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

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

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

    鉴于这一切,我认为强制 API 的用户传递Serializable entityId 是有意义的,这允许不关闭任何门并避免任何以后的限制(哎呀,您不能激活二级缓存,因为这个pk不是Serializable)。这是 IMO 比使用 Object 更好的设计决策。老实说,我对此没有任何不满。

    【讨论】:

    • 我对使用 Serializable 真的没问题。但我的观点是,为什么别人必须强迫我做点什么,即使这是很好的做法?
    【解决方案2】:

    这并不完全正确。 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之外,Serializable是唯一的选择。

    【讨论】:

    • 是的,但为什么连标识符都必须是可序列化的?
    【解决方案3】:

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

    【讨论】:

    • 但是这个缓存是在多个 JVM 上的默认选项吗?我认为不是,如果我正在配置缓存或集群,我会让我的对象可序列化。但是为什么当我不使用任何分布式缓存时,hibernate 必须强制我使用序列化?
    • 不,默认情况下未启用。我猜想强制执行 Serializable 实现应该让开发人员认识到值对象可能会受到序列化,因此应该以这种方式设计。只是一个猜测,我从来没有真正想过它,直到我读到你的问题才意识到它。
    【解决方案4】:

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

    【讨论】:

    • 1. get() 和 load() 不会向表中插入任何内容,只是检索现有实体,2. Hibernate 的重点是对象关系映射(ORM),即对象的属性映射到表列之一以明确设计的方式增加一个(或多或少)。默认情况下不会发生序列化,除非您明确定义它(并且您可能需要为此自定义映射类型)。
    • 好点。我误解了你的问题。但是,我以前使用这些来存储引用,即对象的 id,因此序列化作为一种​​存储方法是有意义的。在这种情况下,我的经验可能有点有限。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多